Rectangular form of a complex expression
This functionality does not run in MATLAB.
rectform(z) computes the rectangular form of the complex expression z, i.e., it splits z into z = ℜ(z) + i ℑ(z).
rectform(z) tries to split z into its real and imaginary part and to return z in the form z = ℜ(z) + i ℑ(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.
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.
The main use of 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.
If z is an hfarray, then rectform returns z unchanged.
See Example 5.
The result 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). The first two operands are real arithmetical expressions, and the third operand is an expression that cannot be split into its real and imaginary part.
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.
Arithmetical operations with elements of the domain type rectform are possible. The result of an arithmetical operation is again an element of this domain (see Example 4).
The rectangular form of sin(z) for complex values z is:
delete z: r := rectform(sin(z))
The real and the imaginary part can be extracted as follows:
The complex conjugate of r can be obtained directly:
Re(ln(-4)) + I*Im(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 ei sin(z):
delete z: f := exp(I*sin(z)): Re(f), Im(f)
The function rectform is more powerful. It is able to split the expression above into its real and imaginary part:
r := rectform(f)
Now we can extract the real and the imaginary part of f:
Identifiers without properties are considered to be complex variables:
delete z: rectform(ln(z))
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))
We compute the rectangular form of the complex variable x:
delete x: a := rectform(x)
Then we do the same for the real variable y:
delete y: assume(y, Type::Real): b := rectform(y)
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
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)
Use the function expr to convert an element of domain type rectform into an element of a basic domain:
delete x, y: p := poly(ln(-4) + y*x, [x]): rectform(p)
a := array(1..2, [x, y]): rectform(a)
hfarrays are returned unchanged:
a := hfarray(1..2, [1.0, 2.0]): rectform(a)
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: An arithmetical expression is expected. [rectform::new]
Use map to apply rectform to the operands of such an object:
This 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))
The first two operands of r are the real and imaginary part of the expression, and the third operand is 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))
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:
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)))
Advanced users can extend rectform to their own special mathematical functions (see section "Backgrounds" below). To this end, embed your mathematical function into a function environmentf 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))
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)))
Element of the domain rectform if z is an arithmetical expression, and an object of the same type as z otherwise.
Calling an element of rectform as a function yields the object itself, regardless of the arguments. The arguments are not evaluated.
You can apply (almost) any function to elements of rectform which transforms a complex-valued expression into a complex-valued expression.
For example, you may add or multiply those elements, or apply functions such as expand and diff to them. The result of such an operation, which is not explicitely overloaded by a method of rectform (see below), is an element of rectform.
This "automatic overloading" works as follows: Each argument of the operation, which is an element of rectform, is converted to an expression using the method "expr" (see below). Then, the operation is applied and the result is re-converted to an element of rectform.
Use the function expr to convert an element of rectform to an arithmetical expression (as an element of a kernel domain).
An element z of rectform consists of three operands:
the real part of z,
the imaginary part of z,
the part of z, for that the real and imaginary part cannot be computed (possibly the integer 0, if there are not such subexpressions).
If a subexpression of the form f(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.
Similarly, if an element d of a library domainT 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.