rectform -- rectangular form of
a complex expression
Introductionrectform(z) computes the rectangular form
of the complex expression z, i.e., it splits z
into z = Re(z) + I*Im(z).
Call(s)rectform(z)
Parametersz |
- | an arithmetical expression, a polynomial, a series expansion, an array, a list, or a set |
Returnsan element of the domain rectform if z is an
arithmetical expression, and an object of
the same type as z otherwise.
Side
EffectsThe function is sensitive to properties of identifiers set via
assume; see
example 3.
z
Further
DocumentationChapter ``Manipulating Expressions'' of the Tutorial.
Related
Functionsabs, assume, collect, combine, conjugate, expand, Im, normal, radsimp, Re, rewrite, sign, simplify
Detailsrectform(z) tries to split z
into its real and imaginary part and to return z in the
form Re(z) + I*Im(z).
rectform works recursively, i.e., it first tries to
split each subexpression of z into its real and imaginary
part and then tackles z as a whole.
Re and Im to extract the real and imaginary
parts, respectively, from the result of rectform. See
example 1.rectform is more powerful than a direct application of
Re and Im to z. However, usually it
is much slower. For constant arithmetical
expressions, it is therefore recommended to use the functions
Re and Im directly. See example 2.rectform is for symbolic expressions,
and properties of identifiers are
taken into account (see assume). An identifier without any
property is assumed to be complex valued. See example 3.z is a array, a list, or a set, then
rectform is applied to each entry of z.
If z is a polynomial or a
series expansion, of type Series::Puiseux or Series::gseries, then
rectform is applied to each coefficient of
z.
See example 5.
r := rectform(z) is an element of the domain rectform. Such a domain element consists of three operands,
satisfying the following equality:z = op(r, 1) + I*op(r, 2) + op(r, 3).Sometimes rectform is unable to compute the required
decomposition. Then it still tries to return some partial information
by extracting as much as possible from the real and imaginary part of
z. The extracted parts are stored in the first two
operands, and the third operand contains the remainder, where no
further extraction is possible. In extreme cases, the first two
operands may even be zero. Example 6
illustrates some possible cases.
rectform are possible. The
result of an arithmetical operation is again an element of this domain
(see example 4).expand, normal, simplify etc.) can be applied to
elements of type rectform. They act on each of
the three operands individually.expr to convert
the result of rectform into an element of a basic domain; see example 4.
Example
1The rectangular form of sin (z) for complex values z is:
>> delete z: r := rectform(sin(z))
sin(Re(z)) cosh(Im(z)) + (cos(Re(z)) sinh(Im(z))) I
The real and the imaginary part can be extracted as follows:
>> Re(r), Im(r)
sin(Re(z)) cosh(Im(z)), cos(Re(z)) sinh(Im(z))
The complex conjugate of r can be obtained
directly:
>> conjugate(r)
sin(Re(z)) cosh(Im(z)) + (-cos(Re(z)) sinh(Im(z))) I
Example
2The real and the imaginary part of a constant
arithmetical expression can be determined by the functions Re and Im, as in the following example:
>> Re(ln(-4)) + I*Im(ln(-4))
I PI + ln(4)
In fact, they work much faster than
rectform. However, they fail to compute the real and the
imaginary part of arbitrary symbolic expressions, such as for the term
exp(I*sin(z)):
>> delete z: f := exp(I*sin(z)): Re(f), Im(f)
Re(exp(I sin(z))), Im(exp(I sin(z)))
The function rectform is more powerful. It
is able to split the expression above into its real and imaginary
part:
>> r := rectform(f)
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
Now we can extract the real and the imaginary part of
f:
>> 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
3Identifiers without properties are considered to be complex variables:
>> delete z: rectform(ln(z))
2 2
ln(Im(z) + Re(z) )
------------------- + I arg(Re(z), Im(z))
2
However, you can affect the behavior of
rectform by attaching properties to the identifiers. For
example, if z assumes only real negative values, the real
and the imaginary part simplify considerably:
>> assume(z < 0): rectform(ln(z))
ln(-z) + I PI
Example
4We compute the rectangular form of the complex variable x:
>> delete x: a := rectform(x)
Re(x) + I Im(x)
Then we do the same for the real variable y:
>> delete y: assume(y, Type::Real): b := rectform(y)
y
>> domtype(a), domtype(b)
rectform, rectform
We have stored the results, i.e., the elements of domain
type rectform, in
the two identifiers a and b. We compute the
sum of a and b, which is again of domain type
rectform, i.e., it is already splitted into its real and
imaginary part:
>> c := a + b
(y + Re(x)) + I Im(x)
>> domtype(c)
rectform
The result of an arithmetical operation between an
element of domain type rectform and an arbitrary
arithmetical expression is of domain type rectform as
well:
>> delete z: d := a + 2*b + exp(z)
(2 y + Re(x) + cos(Im(z)) exp(Re(z))) +
I (Im(x) + sin(Im(z)) exp(Re(z)))
>> domtype(d)
rectform
Use the function expr to convert an element of domain
type rectform into an element of a basic domain:
>> expr(d)
2 y + I Im(x) + Re(x) + cos(Im(z)) exp(Re(z)) +
I sin(Im(z)) exp(Re(z))
>> domtype(%)
DOM_EXPR
Example
5rectform also works for polynomials and series
expansions, namely individually on each coefficient:
>> delete x, y: p := poly(ln(-4) + y*x, [x]): rectform(p)
poly((Re(y) + I Im(y)) x + (ln(4) + I PI), [x])
Similarly, rectform works for lists, sets, or arrays, where it is applied to each individual
entry:
>> a := array(1..2, [x, y]): rectform(a)
+- -+
| Re(x) + I Im(x), Re(y) + I Im(y) |
+- -+
Note that rectform does not work directly
for other basic data types. For example, if the input expression is a
table of arithmetical expressions, then
rectform responds with an error message:
>> a := table("1st" = x, "2nd" = y):
rectform(a)
Error: invalid argument, expecting an arithmetical expression \
[rectform::new]
Use map to
apply rectform to the operands of such an object:
>> map(a, rectform)
table(
"2nd" = Re(y) + I Im(y),
"1st" = Re(x) + I Im(x)
)
Example
6This example illustrates the meaning of the three
operands of an object returned by rectform.
We start with the expression x+sin(y), for which
rectform is able to compute a complete decomposition into
real and imaginary part:
>> delete x, y: r := rectform(x + sin(y))
(Re(x) + sin(Re(y)) cosh(Im(y))) +
I (Im(x) + cos(Re(y)) sinh(Im(y)))
The first two operands of r are the real
and imaginary part of the expression, and the third operand
is 0:
>> op(r)
Re(x) + sin(Re(y)) cosh(Im(y)),
Im(x) + cos(Re(y)) sinh(Im(y)), 0
Next we consider the expression x+f(y), where
f(y) represents an unknown function in a complex variable.
rectform can split x into its real and
imaginary part, but fails to do this for the subexpression
f(y):
>> delete f: r := rectform(x + f(y))
Re(x) + I Im(x) + f(y)
The first two operands of the returned object are the
real and the imaginary part of x, and the third operand is
the remainder f(y), for which rectform was not
able to extract any information about its real and imaginary part:
>> op(r)
Re(x), Im(x), f(y)
>> Re(r), Im(r)
Re(x) + Re(f(y)), Im(x) + Im(f(y))
Sometimes rectform is not able to extract
any information about the real and imaginary part of the input
expression. Then the third operand contains the whole input expression,
possibly in a rewritten form, due to the recursive mode of operation of
rectform. The first two operands are 0.
Here is an example:
>> r := rectform(sin(x + f(y)))
sin(f(y) + I Im(x) + Re(x))
>> op(r)
0, 0, sin(f(y) + I Im(x) + Re(x))
>> Re(r), Im(r)
Re(sin(f(y) + I Im(x) + Re(x))),
Im(sin(f(y) + I Im(x) + Re(x)))
Example
7Advanced users can extend rectform 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 rectform for this function as
the "rectform" slot of the function environment.
If a subexpression of the form f(u,..) occurs in
z, then rectform issues the call
f::rectform(u,..) to the slot routine to determine the
rectangular form of f(u,..).
For illustration, we show how this works for the sine function. Of
course, the function environment sin already has a
"rectform" slot. We call our function environment
Sin in order not to overwrite the existing system function
sin:
>> Sin := funcenv(Sin):
Sin::rectform := proc(u) // compute rectform(Sin(u))
local r, a, b;
begin
// recursively compute rectform of u
r := rectform(u);
if op(r, 3) <> 0 then
// we cannot split Sin(u)
new(rectform, 0, 0, Sin(u))
else
a := op(r, 1); // real part of u
b := op(r, 2); // imaginary part of u
new(rectform, Sin(a)*cosh(b), cos(a)*sinh(b), 0)
end_if
end:
>> delete z: rectform(Sin(z))
Sin(Re(z)) cosh(Im(z)) + (cos(Re(z)) sinh(Im(z))) I
If the if condition is true, then
rectform is unable to split u completely into
its real and imaginary part. In this case, Sin::rectform
is unable to split Sin(u) into its real and imaginary part
and indicates this by storing the whole expression Sin(u)
in the third operand of the resulting rectform object:
>> delete f: rectform(Sin(f(z)))
Sin(f(z))
>> op(%)
0, 0, Sin(f(z))
Backgroundf(u,..) occurs in
z and f is a function environment, then rectform
attempts to call the slot "rectform" of f to
determine the rectangular form of f(u,..). In this way,
you can extend the functionality of rectform to your own
special mathematical functions.
The slot "rectform" is called with the arguments
u,.. of f. If the slot routine
f::rectform is not able to determine the rectangular form
of f(u,..), then it should return
new(rectform(0,0,f(u,..))). See example 7. If f does not have a slot
"rectform", then rectform returns the object
new(rectform(0,0,f(u,..))) for the corresponding
subexpression.
d of a library domain T occurs as a subexpression of
z, then rectform attempts to call the slot
"rectform" of that domain with d as argument
to compute the rectangular form of d.
If the slot routine T::rectform is not able to
determine the rectangular form of d, then it should return
new(rectform(0,0,d)).
If the domain T does not have a slot
"rectform", then rectform returns the object
new(rectform(0,0,d)) for the corresponding
subexpression.
rectform reacts to of properties of identifiers set via
assume. Hence, the
second argument of rectform (a set of real variables)
became obsolete.