## `Re, Im` -- real and imaginary part of an arithmetical expression

#### Introduction

`Re(z)` returns the real part of z.

`Im(z)` returns the imaginary part of z.

#### Call(s)

`Re(z)`
`Im(z)`

#### Parameters

`z` | - | an arithmetical expression

#### Returns

an arithmetical expression.

### Overloadable:

`z`

#### Side Effects

These functions are sensitive to properties of identifiers set via `assume`. See example 2.

#### Related Functions

`abs`, `assume`, `conjugate`, `rectform`, `sign`

#### Details

- The intended use of `Re` and `Im` is for constant arithmetical expressions. Especially for numbers, of type `DOM_INT`, `DOM_RAT`, `DOM_FLOAT`, or `DOM_COMPLEX`, the real and the imaginary part is computed directly and very efficiently.

- `Re` and `Im` can handle symbolic expressions. Properties of identifiers are taken into account (see `assume`). An identifier without any property is assumed to be complex. See example 2.

  However, for arbitrary symbolic expressions, `Re` or `Im` may be unable to extract the real or the imaginary part of `z`, respectively. You may then use the function `rectform` (see example 3). Note, however, that using `rectform` is computationally expensive.

- If `Re` cannot extract the whole real part of `z`, then the returned expression contains symbolic `Re` and `Im` calls. The same is true for `Im`. See example 2.

#### Example 1

The real and the imaginary part of 2 e1+i are:

    >> Re(2*exp(1 + I)), Im(2*exp(1 + I))

                         2 cos(1) exp(1), 2 sin(1) exp(1)

#### Example 2

`Re` and `Im` are not able to extract the whole real and imaginary part, respectively, of symbolic expressions containing identifiers without a value. However, in some cases they can still simplify the input expression, as in the following two examples:

    >> delete u, v: Re(u + v*I), Im(u + v*I)

                           Re(u) - Im(v), Im(u) + Re(v)

    >> delete z: Re(z + 2), Im(z + 2)

                                 Re(z) + 2, Im(z)

By default, identifiers without a value are assumed to represent arbitrary complex numbers. You can use `assume` to change this. The following command tells the system that `z` represents only real numbers:

    >> assume(z, Type::Real): Re(z + 2), Im(z + 2)

                                     z + 2, 0

#### Example 3

Here is another example of a symbolic expression for which `Re` and `Im` fail to extract its real and imaginary part, respectively:

    >> delete z: Re(exp(I*sin(z))), Im(exp(I*sin(z)))

                       Re(exp(I sin(z))), Im(exp(I sin(z)))

You may use the function `rectform`, which splits a complex expression z into its real and imaginary part and is more powerful than `Re` and `Im`:

    >> r := rectform(exp(I*sin(z)))

          cos(sin(Re(z)) cosh(Im(z))) exp(-cos(Re(z)) sinh(Im(z))) +

             (sin(sin(Re(z)) cosh(Im(z))) exp(-cos(Re(z)) sinh(Im(z)))) I

Then `Re(r)` and `Im(r)` give the real and the imaginary part of `r`, respectively:

    >> Re(r)

             cos(sin(Re(z)) cosh(Im(z))) exp(-cos(Re(z)) sinh(Im(z)))

    >> Im(r)

             sin(sin(Re(z)) cosh(Im(z))) exp(-cos(Re(z)) sinh(Im(z)))

#### Example 4

Symbolic expressions of type `"Re"` and `"Im"` always have the property `Type::Real`, even if no identifier of the symbolic expression has a property:

    >> is(Re(sin(2*x)), Type::Real)

                                       TRUE

#### Example 5

Advanced users can extend the functions `Re` and `Im` to their own special mathematical functions (see section ``Backgrounds'' below). To this end, embed your mathematical function into a function environment `f` and implement the behavior of the functions `Re` and `Im` for this function as the slots `"Re"` and `"Im"` of the function environment.

If a subexpression of the form `f(u,..)` occurs in `z`, then `Re` and `Im` issue the call `f::Re(u,..)` and `f::Im(u,..)`, respectively, to the slot routine to determine the real and the imaginary part of `f(u,..)`, respectively.

For illustration, we show how this works for the sine function and the slot `"Re"`. Of course, the function environment `sin` already has a `"Re"` slot. We call our function environment `Sin` in order not to overwrite the existing system function `sin`:

    >> Sin := funcenv(Sin):
       Sin::Re := proc(u) // compute Re(Sin(u))
         local r, s;
       begin
         r := Re(u);
         if r = u then
           return(Sin(u))
         elif not has(r, {hold(Im), hold(Re)}) then
           s := Im(u);
           if not has(s, {hold(Im), hold(Re)}) then
             return(Sin(r)*cosh(s))
           end_if
         end_if;
         return(FAIL)
       end:

    >> Re(Sin(2)), Re(Sin(2 + 3*I))

                              Sin(2), Sin(2) cosh(3)

The return value `FAIL` tells the function `Re` that `Sin::Re` was unable to determine the real part of the input expression. The result is then a symbolic `Re` call:

    >> delete f, z: Re(2 + Sin(f(z)))

                                 Re(Sin(f(z))) + 2

#### Background

- If a subexpression of the form `f(u,..)` occurs in `z` and `f` is a function environment, then `Re` attempts to call the slot `"Re"` of `f` to determine the real part of `f(u,..)`. In this way, you can extend the functionality of `Re` to your own special mathematical functions.

  The slot `"Re"` is called with the arguments `u,..` of `f`. If the slot routine `f::Re` is not able to determine the real part of `f(u,..)`, then it must return `FAIL`.

  If `f` does not have a slot `"Re"`, or if the slot routine `f::Re` returns `FAIL`, then `f(u,..)` is replaced by the symbolic call `Re(f(u...))` in the returned expression.

  The same holds for the function `Im`, which attempts to call the corresponding slot `"Im"` of `f`.

  See example 5.

- Similarly, if an element `d` of a library domain `T` occurs as a subexpression of `z`, then `Re` attempts to call the slot `"Re"` of that domain with `d` as argument to compute the real part of `d`.

  If the slot routine `T::Re` is not able to determine the real part of `d`, then it must return `FAIL`.

  If `T` does not have a slot `"Re"`, or if the slot routine `T::Re` returns `FAIL`, then `d` is replaced by the symbolic call `Re(d)` in the returned expression.

  The same holds for the function `Im`, which attempts to call the corresponding slot `"Im"` of the `T`.

#### Changes

- `Re` and `Im` react to properties of identifiers set by `assume`.

Do you have questions or comments?
Copyright © SciFace Software GmbH & Co. KG 2000