Documentation |
Expand an expression
This functionality does not run in MATLAB.
expand(f, options) expand(f, g1, g2, …, options)
expand(f) expands the arithmetical expression f.
The most important use of 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.
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) applies the following rules when rewriting powers occurring as subexpressions in f:
x^{a + b} = x^{a} x^{b}.
If b is an integer, or x ≥ 0 or y ≥ 0, then (x y)^{b} = x^{b} y^{b}.
If b is an integer, then (x^{a})^{b} = x^{a b}.
Except for the third rule, this behavior of expand is the inverse functionality of combine. See Example 2.
expand works recursively on the subexpressions of an expression f. If f is of the container type array or table, expand only returns f and does not map on the entries. To expand all entries of one of the containers, use map. See Example 3.
If optional arguments g1, g2, ... are present, then any subexpression of f that is equal to one of these additional arguments is not expanded; see Example 4. See section "Background" for a description how this works.
Properties of identifiers are taken into account (see assume). Identifiers without any properties are assumed to be complex. See Example 9.
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 10.
expand expands products of sums by multiplying out:
expand((x + 1)*(y + z)^2)
After expansion of the numerator, a fraction is rewritten as a sum of fractions:
expand((x + 1)^2*y/(y + z)^2)
A power with a sum in the exponent is rewritten as a product of powers:
expand(x^(y + z + 2))
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)^{z} is multiplied out:
expand((x + y)^(z + 2))
Here is another example:
expand(2^((x + y)^2))
expand maps on the entries of lists, sets, and matrices:
expand([(a + b)^2, (a - b)^2]); expand({(a + b)^2, (a - b)^2}); expand(matrix([[(a + b)^2, 0],[0, (a - b)^2]]))
expand does not map on the entries of tables or arrays:
expand(table((a + b)^2=(c + 1)^2)), expand(array(1..1, [(a + b)^2]))
Use map in order to expand all entries of a container:
map(table((a + b)^2=(c + 1)^2), expand), map(array(1..1, [(a + b)^2]), expand)
Note that this call expands only the entries in a table, not the keys. In the (rare) case that you want the keys expanded as well, transform the table to a list or set of equations first:
T := table((a + b)^2=(c + 1)^2): table(expand([op(T)]))
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))
expand((x + 1)*(y + z), x + 1)
By default, expand works on all subexpressions including trigonometric subexpressions:
e := (sin(2*x) + 1)*(1 - cos(2*x)): expand(e)
To prevent expansion of subexpressions, use the ArithmeticOnly option:
expand(e, ArithmeticOnly)
The option does not prevent expansion of powers and roots:
expand((sin(2*x) + 1)^3, ArithmeticOnly)
To keep subexpressions with integer powers unexpanded, use the MaxExponent option.
The IgnoreAnalyticConstraints option applies a set of purely algebraic simplifications including the equality of sum of logarithms and a logarithm of a product. Using the IgnoreAnalyticConstraints option, you get a simpler result, but one that might be incorrect for some of the values of variables:
expand(ln(a*b*c*d), IgnoreAnalyticConstraints)
Without using this option, you get a mathematically correct result:
expand(ln(a*b*c*d))
If the additional MaxExponent provided, expand performs only a partial expansion. Powers with an integer exponent larger than the given bound, are not expanded:
expand((a + b)^3, MaxExponent = 2)
If the exponent is smaller or equal the given bound, the power is expanded:
expand((a + b)^2, MaxExponent = 2)
The expand function can accept several options simultaneously. Suppose you want to expand the following expression:
e := (sin(2*x) + 1)*(x + 1)^3
expand without any options works recursively. The function expands all subexpressions including trigonometric functions and powers:
expand(e)
The ArithmeticOnly option prevents the expansion of the term sin(2x). The MaxExponent option prevents the expansion of (x + 1)^{3}:
expand(e, ArithmeticOnly); expand(e, MaxExponent = 2)
Combining these options in one call of the expand function, you apply both restrictions for the expansion:
expand(e, MaxExponent = 2, ArithmeticOnly)
The following expansions are not valid for all values a, b from the complex plane. Therefore, MuPAD^{®} does not expand these expressions:
expand(ln(a^2)), expand(ln(a*b)), expand((a*b)^n)
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)), expand((a*b)^n)
Clear the assumption for further computations:
unassume(a):
Alternatively, to get the expanded result for the third expression, assume that n is an integer:
expand((a*b)^n) assuming n in Z_
Use the IgnoreAnalyticConstraints option to expand these expressions without explicitly specified assumptions:
expand(ln(a^2), IgnoreAnalyticConstraints), expand(ln(a*b), IgnoreAnalyticConstraints), expand((a*b)^n, IgnoreAnalyticConstraints)
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))
The same is true for the hyperbolic functions sinh and cosh:
expand(cosh(a + b)), expand(cosh(2*a))
The exponential function with a sum as argument is expanded via exp::expand:
expand(exp(a + b))
Here are some more expansion examples for the functions sum, fact, abs, coth, sign, binomial, beta, gamma, cot, tan, exp and psi:
sum(f(x) + g(x),x); expand(%)
fact(x + 1); expand(%)
abs(a*b); expand(%)
coth(a + b); expand(%)
coth(a*b); expand(%)
sign(a*b); expand(%)
binomial(n, m); expand(%)
beta(n, m); expand(%)
gamma(x + 1); expand(%)
tan(a + b); expand(%)
cot(a + b); expand(%)
exp(x + y); expand(%)
psi(x + 2); expand(%)
In contrast to previous versions of MuPAD, expand does not rewrite tan in terms of sin and cos:
expand(tan(a))
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 10.)
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(op(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)))
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))
ArithmeticOnly |
Expand arithmetic part of an expression without expanding trigonometric, hyperbolic, logarithmic and special functions. This option does not prevent expansion of powers and roots. Technically, the option omits overloading the expand function for each term of the original expression. See Example 5. |
IgnoreAnalyticConstraints |
With this option expand applies the following rules when expanding expressions:
Using the option can give you simpler results for the expressions for which the default call to expand returns complicated results. With this option the function does not guarantee the equality of the initial expression and the result for all symbolic parameters. See Example 6. |
MaxExponent |
Option, specified as MaxExponent = n Do not expand powers with integer exponents larger than n. If you call expand with this option, the function expands does not expand powers with integer exponents larger than n. See Example 7. |
With optional arguments 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.
Users can extend the functionality of 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(g(u,..)) to the slot routine to expand the subexpression, passing the not yet expanded arguments g(u,..) as arguments. The result of this call is not expanded any further by expand. See Example 11 above.
Similarly, an "expand" slot can be defined for a user-defined library domainT. Whenever expand encounters a subexpression d of domain typeT, 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.