| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → Symbolic Math Toolbox |
| Contents | Index |
| Learn more about Symbolic Math Toolbox |
| On this page… |
|---|
Here are three different symbolic expressions.
syms x f = x^3 - 6*x^2 + 11*x - 6; g = (x - 1)*(x - 2)*(x - 3); h = -6 + (11 + (-6 + x)*x)*x;
Here are their prettyprinted forms, generated by
pretty(f); pretty(g); pretty(h)
3 2 x - 6 x + 11 x - 6 (x - 1) (x - 2) (x - 3) x (x (x - 6) + 11) - 6
These expressions are three different representations of the same mathematical function, a cubic polynomial in x.
Each of the three forms is preferable to the others in different situations. The first form, f, is the most commonly used representation of a polynomial. It is simply a linear combination of the powers of x. The second form, g, is the factored form. It displays the roots of the polynomial and is the most accurate for numerical evaluation near the roots. But, if a polynomial does not have such simple roots, its factored form may not be so convenient. The third form, h, is the Horner, or nested, representation. For numerical evaluation, it involves the fewest arithmetic operations and is the most accurate for some other ranges of x.
The symbolic simplification problem involves the verification that these three expressions represent the same function. It also involves a less clearly defined objective — which of these representations is "the simplest"?
This toolbox provides several functions that apply various algebraic and trigonometric identities to transform one representation of a function into another, possibly simpler, representation. These functions are collect, expand, horner, factor, simplify, and simple.
The statementcollect(f) views f as a polynomial in its symbolic variable, say x, and collects all the coefficients with the same power of x. A second argument can specify the variable in which to collect terms if there is more than one candidate. Here are a few examples.
f | collect(f) |
|---|---|
syms x; f = (x-1)*(x-2)*(x-3); | collect(f) ans = x^3 - 6*x^2 + 11*x - 6 |
syms x; f = x*(x*(x - 6) + 11) - 6; | collect(f) ans = x^3 - 6*x^2 + 11*x - 6 |
syms x t; f = (1+x)*t + x*t; | collect(f) ans = (2*t)*x + t |
The statement expand(f) distributes products over sums and applies other identities involving functions of sums as shown in the examples below.
f | expand(f) |
|---|---|
syms a x y; f = a*(x + y); | expand(f) ans = a*x + a*y |
syms x; f = (x - 1)*(x - 2)*(x - 3); | expand(f) ans = x^3 - 6*x^2 + 11*x - 6 |
syms x; f = x*(x*(x - 6) + 11) - 6; | expand(f) ans = x^3 - 6*x^2 + 11*x - 6 |
syms a b; f = exp(a + b); | expand(f) ans = exp(a)*exp(b) |
syms x y; f = cos(x + y); | expand(f) ans = cos(x)*cos(y) - sin(x)*sin(y) |
syms x; f = cos(3*acos(x)); | expand(f) ans = 3*x*(x^2 - 1) + x^3 |
syms x; f = 3*x*(x^2 - 1) + x^3; | expand(f) ans = 4*x^3 - 3*x |
The statement horner(f) transforms a symbolic polynomial f into its Horner, or nested, representation as shown in the following examples.
f | horner(f) |
|---|---|
syms x; f = x^3 - 6*x^2 + 11*x - 6; | horner(f) ans = x*(x*(x - 6) + 11) - 6 |
syms x; f = 1.1 + 2.2*x + 3.3*x^2; | horner(f) ans = x*((33*x)/10 + 11/5) + 11/10 |
If f is a polynomial with rational coefficients, the statement
factor(f)
expresses f as a product of polynomials of lower degree with rational coefficients. If f cannot be factored over the rational numbers, the result is f itself. Here are several examples.
f | factor(f) |
|---|---|
syms x; f = x^3 - 6*x^2 + 11*x - 6; | factor(f) ans = (x - 3)*(x - 1)*(x - 2) |
syms x; f = x^3 - 6*x^2 + 11*x - 5; | factor(f) ans = x^3 - 6*x^2 + 11*x - 5 |
syms x; f = x^6 + 1; | factor(f) ans = (x^2 + 1)*(x^4 - x^2 + 1) |
Here is another example involving factor. It factors polynomials of the form x^n + 1. This code
syms x; n = (1:9)'; p = x.^n + 1; f = factor(p); [p, f]
returns a matrix with the polynomials in its first column and their factored forms in its second.
ans = [ x + 1, x + 1] [ x^2 + 1, x^2 + 1] [ x^3 + 1, (x + 1)*(x^2 - x + 1)] [ x^4 + 1, x^4 + 1] [ x^5 + 1, (x + 1)*(x^4 - x^3 + x^2 - x + 1)] [ x^6 + 1, (x^2 + 1)*(x^4 - x^2 + 1)] [ x^7 + 1, (x + 1)*(x^6 - x^5 + x^4 - x^3 + x^2 - x + 1)] [ x^8 + 1, x^8 + 1] [ x^9 + 1, (x + 1)*(x^2 - x + 1)*(x^6 - x^3 + 1)]
As an aside at this point, factor can also factor symbolic objects containing integers. This is an alternative to using the factor function in the MATLAB specfun directory. For example, the following code segment
N = sym(1); for k = 2:11 N(k) = 10*N(k-1)+1; end [N' factor(N')]
displays the factors of symbolic integers consisting of 1s:
ans = [ 1, 1] [ 11, 11] [ 111, 3*37] [ 1111, 11*101] [ 11111, 41*271] [ 111111, 3*7*11*13*37] [ 1111111, 239*4649] [ 11111111, 11*73*101*137] [ 111111111, 3^2*37*333667] [ 1111111111, 11*41*271*9091] [ 11111111111, 21649*513239]
The simplify function is a powerful, general purpose tool that applies a number of algebraic identities involving sums, integral powers, square roots and other fractional powers, as well as a number of functional identities involving trig functions, exponential and log functions, Bessel functions, hypergeometric functions, and the gamma function. Here are some examples.
f | simplify(f) |
|---|---|
syms x; f = x*(x*(x - 6) + 11) - 6; | simplify(f) ans = (x - 1)*(x - 2)*(x - 3) |
syms x; f = (1 - x^2)/(1 - x); | simplify(f) ans = x + 1 |
syms a; f = (1/a^3 + 6/a^2 + 12/a + 8)^(1/3); | simplify(f) ans = ((2*a + 1)^3/a^3)^(1/3) |
syms x y; f = exp(x) * exp(y); | simplify(f) ans = exp(x + y) |
syms x; f = besselj(2, x) + besselj(0, x); | simplify(f) ans = (2*besselj(1, x))/x |
syms x; f = gamma(x + 1) - x*gamma(x); | simplify(f) ans = 0 |
syms x; f = cos(x)^2 + sin(x)^2; | simplify(f) ans = 1 |
You can also use the syntax simplify(f, n) where n is a positive integer that controls how many steps simplify takes. The default, when you don't provide an argument n, is 100 steps. For example,
z = diff(x/cos(x), 3)
z = 3/cos(x) + (6*sin(x)^2)/cos(x)^3 +... (6*x*sin(x)^3)/cos(x)^4 + (5*x*sin(x))/cos(x)^2
simplify(z)
ans = (- 3*cos(x)^3 - x*sin(x)*cos(x)^2 + 6*cos(x) + 6*x*sin(x))/cos(x)^4
simplify(z, 200)
ans = (6*cos(x) - 3*cos(x)^3 + sin(x)*(6*x-x*cos(x)^2))/cos(x)^4
The simple function has the unorthodox mathematical goal of finding a simplification of an expression that has the fewest number of characters. Of course, there is little mathematical justification for claiming that one expression is "simpler" than another just because its ASCII representation is shorter, but this often proves satisfactory in practice.
The simple function achieves its goal by independently applying simplify, collect, factor, and other simplification functions to an expression and keeping track of the lengths of the results. The simple function then returns the shortest result.
The simple function has several forms, each returning different output. The form simple(f) displays each trial simplification and the simplification function that produced it in the MATLAB command window. The simple function then returns the shortest result. For example, the command
syms x; simple(cos(x)^2 + sin(x)^2)
displays the following alternative simplifications in the MATLAB command window along with the result:
simplify: 1 radsimp: cos(x)^2 + sin(x)^2 simplify(100): 1 combine(sincos): 1 combine(sinhcosh): cos(x)^2 + sin(x)^2 combine(ln): cos(x)^2 + sin(x)^2 factor: cos(x)^2 + sin(x)^2 expand: cos(x)^2 + sin(x)^2 combine: cos(x)^2 + sin(x)^2 rewrite(exp): ((i*exp(i*x))/2 - i/(2*exp(i*x)))^2 + (exp(i*x)/2 + 1/(2*exp(i*x)))^2 rewrite(sincos): cos(x)^2 + sin(x)^2 rewrite(sinhcosh): cosh(-i*x)^2 - sinh(-i*x)^2 rewrite(tan): (tan(x/2)^2 - 1)^2/(tan(x/2)^2 + 1)^2 + (4*tan(x/2)^2)/(tan(x/2)^2 + 1)^2 mwcos2sin: 1 collect(x): cos(x)^2 + sin(x)^2 ans = 1
This form is useful when you want to check, for example, whether the shortest form is indeed the simplest. If you are not interested in how simple achieves its result, use the form f = simple(f). This form simply returns the shortest expression found. For example, the statement
f = simple(cos(x)^2 + sin(x)^2)
returns
f = 1
If you want to know which simplification returned the shortest result, use the multiple output form [f, how] = simple(f). This form returns the shortest result in the first variable and the simplification method used to achieve the result in the second variable. For example, the statement
[f, how] = simple(cos(x)^2 + sin(x)^2)
returns
f = 1 how = simplify
The simple function sometimes improves on the result returned by simplify, one of the simplifications that it tries. For example, when applied to the examples given for simplify, simple returns a simpler (or at least shorter) result as shown:
f | simplify(f) | simple(f) |
|---|---|---|
syms a positive; f = (1/a^3 + 6/a^2 + 12/a + 8)^(1/3); | simplify(f) ans = ((2*a + 1)^3/a^3)^(1/3) | g = simple(f) g = 1/a + 2 |
syms x; f = cos(x) + i*sin(x); | simplify(f) ans = cos(x) + i*sin(x) | g = simple(f) g = exp(i*x) |
In some cases, it is advantageous to apply simple twice to obtain the effect of two different simplification functions. For example:
z = diff(x/cos(x),3)
z = 3/cos(x) + (6*sin(x)^2)/cos(x)^3 + (6*x*sin(x)^3)/cos(x)^4 + (5*x*sin(x))/cos(x)^2
z1 = simple(z)
z1 = (6*cos(x) - 3*cos(x)^3 + sin(x)*(6*x - x*cos(x)^2))/(sin(x)^2 - 1)^2
z2 = simple(simple(z))
z2 = (6*cos(x) - 3*cos(x)^3 + sin(x)*(6*x - x*cos(x)^2))/cos(x)^4
The simple function is particularly effective on expressions involving trigonometric functions:
f | simple(f) |
|---|---|
syms x; f = cos(x)^2 + sin(x)^2; | f = simple(f) f = 1 |
syms x; f = 2*cos(x)^2 - sin(x)^2; | f = simple(f) f = 3*cos(x)^2 - 1 |
syms x; f = cos(x)^2 - sin(x)^2; | f = simple(f) f = cos(2*x) |
syms x; f = cos(x) + i*sin(x); | f = simple(f) f = exp(i*x) |
syms x; f = cos(3*acos(x)); | f = simple(f) f = 4*x^3 - 3*x |
There are two functions for symbolic substitution: subexpr and subs.
These commands
syms a x s = solve(x^3 + a*x + 1)
solve the equation x^3 + a*x + 1 = 0 for the variable x:
s = ((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3) - a/(3*((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)) a/(6*((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)) - ((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)/2... - (3^(1/2)*i*(a/(3*((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3))... + ((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)))/2 a/(6*((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)) - ((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)/2... + (3^(1/2)*i*(a/(3*((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3))... + ((a^3/27 + 1/4)^(1/2) - 1/2)^(1/3)))/2
This long expression has many repeated pieces, or subexpressions. The subexpr function allows you to save these common subexpressions as well as the symbolic object rewritten in terms of the subexpressions. The subexpressions are saved in a column vector called sigma.
Continuing with the example
r = subexpr(s)
returns
sigma =
(a^3/27 + 1/4)^(1/2) - 1/2
r =
sigma^(1/3) - a/(3*sigma^(1/3))
a/(6*sigma^(1/3)) - sigma^(1/3)/2 - (3^(1/2)*i*(a/(3*sigma^(1/3)) + sigma^(1/3)))/2
a/(6*sigma^(1/3)) - sigma^(1/3)/2 + (3^(1/2)*i*(a/(3*sigma^(1/3)) + sigma^(1/3)))/2Notice that subexpr creates the variable sigma in the MATLAB workspace. You can verify this by typing whos, or the command
sigma
which returns
sigma = (a^3/27 + 1/4)^(1/2) - 1/2
The following code finds the eigenvalues and eigenvectors of a circulant matrix A:
syms a b c A = [a b c; b c a; c a b]; [v,E] = eig(A)
v =
[ (a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2)/(a - c) - (a - b)/(a - c),...
- (a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2)/(a - c) - (a - b)/(a - c),...
1]
[ - (a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2)/(a - c) - (b - c)/(a - c),...
(a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2)/(a - c) - (b - c)/(a - c),...
1]
[ 1, 1, 1]
E =
[-(a^2-a*b-a*c+b^2-b*c+c^2)^(1/2), 0, 0]
[ 0, (a^2-a*b-a*c+b^2-b*c+c^2)^(1/2), 0]
[ 0, 0, a+b+c]Note MATLAB might return the eigenvalues that appear on the diagonal of E in a different order. In this case, the corresponding eigenvectors, which are the columns of v, will also appear in a different order. |
Suppose you want to replace the rather lengthy expression (a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2) throughout v and E. First, use subexpr:
E = subexpr(E,'S')
which returns
S = (a^2 - a*b - a*c + b^2 - b*c + c^2)^(1/2) E = [ -S, 0, 0] [ 0, S, 0] [ 0, 0, a + b + c]
Next, substitute the symbol S into v with
v = simplify(subs(v, S, 'S'))
v = [ (S - a + b)/(a - c), -(S + a - b)/(a - c), 1] [ -(S + b - c)/(a - c), (S - b + c)/(a - c), 1] [ 1, 1, 1]
Now suppose you want to evaluate v at a = 10. Use the subs command:
subs(v, a, 10)
This replaces all occurrences of a in v with 10:
ans = [ -(S + b - 10)/(c - 10), (S - b + 10)/(c - 10), 1] [ (S + b - c)/(c - 10), -(S - b + c)/(c - 10), 1] [ 1, 1, 1]
Notice, however, that the symbolic expression that S represents is unaffected by this substitution. That is, the symbol a in S is not replaced by 10. The subs command is also a useful function for substituting in a variety of values for several variables in a particular expression. For example, suppose that in addition to substituting a = 10 in S, you also want to substitute the values for 2 and 10 for b and c, respectively. The way to do this is to set values for a, b, and c in the workspace. Then subs evaluates its input using the existing symbolic and double variables in the current workspace. In the example, you first set
a = 10; b = 2; c = 10; subs(S)
ans =
8To look at the contents of the workspace, type:
whos
which gives
Name Size Bytes Class Attributes A 3x3 622 sym E 3x3 1144 sym S 1x1 184 sym a 1x1 8 double ans 1x1 8 double b 1x1 8 double c 1x1 8 double v 3x3 1144 sym
a, b, and c are now variables of class double while A, E, S, and v remain symbolic expressions (class sym).
If you want to preserve a, b, and c as symbolic variables, but still alter their value within S, use this procedure.
syms a b c
subs(S, {a, b, c}, {10, 2, 10})ans =
8Typing whos reveals that a, b, and c remain 1-by-1 sym objects.
The subs command can be combined with double to evaluate a symbolic expression numerically. Suppose you have the following expressions
syms t M = (1 - t^2)*exp(-1/2*t^2); P = (1 - t^2)*sech(t);
and want to see how M and P differ graphically.
One approach is to type
ezplot(M); hold on; ezplot(P); hold off;
but this plot does not readily help you identify the curves.

Instead, combine subs, double, and plot:
T = -6:0.05:6;
MT = double(subs(M, t, T));
PT = double(subs(P, t, T));
plot(T, MT, 'b', T, PT, 'r-.');
title(' ');
legend('M','P');
xlabel('t'); grid;to produce a multicolored graph that indicates the difference between M and P.

Finally the use of subs with strings greatly facilitates the solution of problems involving the Fourier, Laplace, or z-transforms. See the section Integral Transforms and Z-Transforms for complete details.
![]() | Calculus | Variable-Precision Arithmetic | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |