expand
-- expand an
expressionexpand(
f)
expands the arithmetical
expression f
.
expand(f)
expand(f, g1, g2, ...)
f, g1, g2, ... |
- | arithmetical expressions |
f
expand
is sensitive to properties of identifiers set via
assume
.
Chapter ``Manipulating Expressions'' of the Tutorial.
collect
, combine
, denom
, factor
, normal
, numer
, partfrac
, rationalize
, rectform
, rewrite
, simplify
expand
is the application of
the distributivity law to rewrite products of sums as sums of products.
In this respect, expand
is the inverse function of
factor
.
Powers of sums with positive integer exponents are expanded as well, but powers of sums with negative integer exponents are not expanded; see example 2.
The numerator of a fraction is expanded, and then the fraction is
rewritten as a sum of fractions with simpler numerators; see
example 1. In a certain sense, this is the
inverse functionality of normal
. Use partfrac
for a more powerful way to
rewrite a fraction as a sum of simpler fractions.
expand(
f)
also applies the following
rewriting rules to powers occurring as subexpressions in
f
:
b
is an integer. Except for the
third rule, this behavior of expand
is the inverse
functionality of combine
. See example 3.expand
works recursively on the subexpressions of an
expression f
. If f
is of one of the container
types array
, list
, set
, or table
, expand
only returns
f
and does not map on the entries. If you want to expand
all entries of one of the containers please use map
. See example 4.g1, g2, ...
are present, then
any subexpression of f
that is equal to one of these
additional arguments is not expanded; see example 5. See section ``Background'' for a description how this
works.assume
). Identifiers without any
properties are assumed to be complex. See example 6.expand
also handles various types of special
mathematical functions. It rewrites a single call of a special function
with a complicated argument as a sum or a product of several calls of
the same function or related functions with simpler arguments. In this
respect, expand
is the inverse function of combine
.
In particular, expand
implements the functional
equations of the exponential function and the logarithm, the gamma function
and the polygamma function, and the addition
theorems for the trigonometric functions
and the hyperbolic functions. See
example 7.
expand
is a function of the system kernel.expand
expands products of sums by
multiplying out:
>> expand((x + 1)*(y + z)^2)
2 2 2 2 2 y z + 2 x y z + y + z + x y + x z
After expansion of the numerator, a fraction is rewritten as a sum of fractions:
>> expand((x + 1)^2*y/(y + z)^2)
2 y 2 x y x y -------- + -------- + -------- 2 2 2 (y + z) (y + z) (y + z)
Powers of sums with positive integer exponents are expanded:
>> expand((x + y)^2)
2 2 2 x y + x + y
Powers of sums with negative integer exponents are regarded as denominators of fractions and are not expanded:
>> expand((x + y)^(-2))
1 -------- 2 (x + y)
A power with a sum in the exponent is rewritten as a product of powers:
>> expand(x^(y + z + 2))
2 y z x x x
If one of the additive terms in the exponent is negative, the power is expanded into a fraction of powers:
>> expand((x + y)^(z - 2))
z (x + y) -------- 2 (x + y)
expand
works in a recursive fashion. In the
following example, the power (x + y)^(z + 2) is first
expanded into a product of two powers. Then the power (x +
y)^2 is expanded into a sum. Finally, the product of the latter
sum and the remaining power (x + y)^2 is multiplied out:
>> expand((x + y)^(z + 2))
z 2 z 2 z 2 x y (x + y) + x (x + y) + y (x + y)
Here is another example:
>> expand(2^((x + y)^2))
2 2 x y 2 x y 2 2 2
expand
does not map on the entries of a
container type:
>> expand([(a + b)^2, c]), expand({(a + b)^2, c})
2 2 [(a + b) , c], {c, (a + b) }
Use map
in
order to expand all entries of a container:
>> map([(a + b)^2, c], expand), map({(a + b)^2, c}, expand)
2 2 2 2 [2 a b + a + b , c], {c, 2 a b + a + b }
If additional arguments are provided,
expand
performs only a partial expansion. These additional
expressions, such as x + 1
in the following example, are
not expanded:
>> expand((x + 1)*(y + z))
y + z + x y + x z
>> expand((x + 1)*(y + z), x + 1)
y (x + 1) + z (x + 1)
The following expansions are not valid for all values
a
, b
from the complex plane. Therefore no
expansion is done:
>> expand(ln(a^2)), expand(ln(a*b))
2 ln(a ), ln(a b)
The expansions are valid under the assumption that
a
is a positive real number:
>> assume(a > 0): expand(ln(a^2)), expand(ln(a*b))
2 ln(a), ln(a) + ln(b)
>> unassume(a):
The addition theorems of trigonometry are implemented by
"
expand"-slots of the trigonometric functions
sin
and cos
:
>> expand(sin(a + b)), expand(sin(2*a))
cos(a) sin(b) + cos(b) sin(a), 2 cos(a) sin(a)
The same is true for the hyperbolic functions sinh
and
cosh
:
>> expand(cosh(a + b)), expand(cosh(2*a))
2 cosh(a) cosh(b) + sinh(a) sinh(b), 2 cosh(a) - 1
The exponential function with a
sum as argument is expanded via exp::expand
:
>> expand(exp(a + b))
exp(a) exp(b)
Here are some more expansion examples for the functions
sum
, fact
, abs
, coth
, sign
, binomial
, beta
, gamma
, log
, cot
, tan
, exp
and psi
:
>> sum(x + exp(x),x); expand(%)
sum(x + exp(x), x) 2 x x exp(x) -- - - + ---------- 2 2 exp(1) - 1
>> fact(x + 1); expand(%)
fact(x + 1) fact(x) (x + 1)
>> abs(a*b); expand(%)
abs(a b) abs(a) abs(b)
>> coth(a + b); expand(%)
coth(a + b) cosh(a) cosh(b) --------------------------------- + cosh(a) sinh(b) + cosh(b) sinh(a) sinh(a) sinh(b) --------------------------------- cosh(a) sinh(b) + cosh(b) sinh(a)
>> coth(a*b); expand(%)
coth(a b) cosh(a b) --------- sinh(a b)
>> sign(a*b); expand(%)
sign(a b) sign(a) sign(b)
>> tan(a); expand(%)
tan(a) sin(a) ------ cos(a)
>> binomial(n, m); expand(%)
binomial(n, m) n gamma(n) ------------------------------- m gamma(m) (n - m) gamma(n - m)
>> beta(n, m); expand(%)
beta(m, n) gamma(m) gamma(n) ----------------- gamma(m + n)
>> gamma(x+1); expand(%)
gamma(x + 1) x gamma(x)
>> log(10, x); expand(%)
log(10, x) ln(x) ------ ln(10)
>> cot(x); expand(%)
cot(x) cos(x) ------ sin(x)
>> exp(x + y); expand(%)
exp(x + y) exp(x) exp(y)
>> psi(x + 2); expand(%)
psi(x + 2) 1 1 psi(x) + - + ----- x x + 1
This example illustrates how to extend the functionality
of expand
to user-defined mathematical functions. As an
example, we consider the sine function. (Of course, the system function
sin
already has an
"
expand" slot; see example 7.)
We first embed our function into a function environment, which we
call Sin
, in order not to overwrite the system function
sin
. Then we implement the
addition theorem sin(x + y) = sin(x)*cos(y) + sin(y)*cos(x)
in the "
expand" slot of the function environment, i.e.,
the slot routine Sin::expand
:
>> Sin := funcenv(Sin): Sin::expand := proc(u) // compute expand(Sin(u)) local x, y; begin // recursively expand the argument u u := expand(u); if type(u) = "_plus" then // u is a sum x := op(u, 1); // the first term y := u - x; // the remaining terms // apply the addition theorem and // expand the result again expand(Sin(x)*cos(y) + cos(x)*Sin(y)) else Sin(u) end_if end_proc:
Now, if expand
encounters a subexpression
of the form Sin(u)
, it calls Sin::expand(u)
to expand Sin(u)
. The following command first expands the
argument a*(b+c)
via the recursive call in
Sin::expand
, then applies the addition theorem, and
finally expand
itself expands the product of the result
with z
:
>> expand(z*Sin(a*(b + c)))
z Sin(a b) cos(a c) + z Sin(a c) cos(a b)
The expansion after the application of the addition
theorem in Sin::expand
is necessary to handle the case
when u
is a sum with more than two terms: then
y
is again a sum, and cos(y)
and
Sin(y)
are expanded recursively:
>> expand(Sin(a + b + c))
Sin(a) cos(b) cos(c) + Sin(b) cos(a) cos(c) + Sin(c) cos(a) cos(b) - Sin(a) sin(b) sin(c)
g1, g2, ...
, the expansion of
certain subexpressions of f
can be prevented. This works
as follows: every occurrence of g1, g2, ...
in
f
is replaced by an auxiliary variable before the
expansion, and afterwards the auxiliary variables are replaced by the
original subexpressions.expand
to their
own special mathematical functions via overloading
. To this end, embed your function
into a function environment
g
and implement the behavior of expand
for
this function in the "
expand" slot of the function
environment.
Whenever expand
encounters a subexpression of the form
g(u,..)
, it issues the call g::expand(u,..)
to the slot routine to expand the subexpression, passing the not yet
expanded arguments u,..
of g
as arguments.
The result of this call is not expanded any further by
expand
. See example 8 above.
"
expand" slot can be defined for a
user-defined library domain T
.
Whenever expand
encounters a subexpression d
of domain type T
, it issues the
call T::expand(d)
to the slot routine to expand
d
. The result of this call is not expanded any further by
expand
. If T
has no "
expand"
slot, then d
remains unchanged.expand
now reacts to properties of identifiers.