I am pleased to introduce guest blogger Kai Gehrs. Kai is a developer for the Symbolic Math Toolbox. His main focus in this post is on special approaches to symbolic simplification and equation solving.
Contents
Have You Noticed Results Not Being Simplified Well?
When using the Symbolic Math Toolbox for symbolic simplification, have you ever been wondering why it does not apply certain classic book rules automatically to return the results you have in mind?
Some of these classic book rules are:
Just using simplify to get the result
on input
does not work:
syms a b simplify(log(a)+log(b))
ans = log(a) + log(b)
Using Assumptions on Variables
Of course, we all know that the rule
applies only under appropriate mathematical assumptions on
and
. For example, if we assume that
and
are positive, we will get the desired result:
syms a b positive simplify(log(a)+log(b))
ans = log(a*b)
To get rid of all previously specified assumptions, use
syms a b clear
When Things Get More Complicated
Does it mean that setting the right assumptions is a universal solution here? Well, not always!
Assume
and
appear as intermediate results in some really huge symbolic computations somewhere in, lets say, line 454 of your MATLAB
script. From the context of your application, you know that
and
are positive. Now you want MATLAB to automatically compute a simplified form of
in line 455. How will you manage to set the right assumptions?
As an example, think of
and
as being something like
syms x y a = -(x + 1)^(1/2)/((exp(x - y) - sin(x + y)) * ... (log((x^2 + 1)/(y^2 + 1))/exp(y) + (x - y)^y + ... 1/(x - y)^x)); b = (cos(x)*sin(y))/((x - y)^x*(x + 1)^(1/2)) - ... (exp(x)*(x - y)^y)/(exp(y)*(x + 1)^(1/2)) + ... (cos(y)*sin(x))/((x - y)^x*(x + 1)^(1/2)) - ... (exp(x)*log((x^2 + 1)/(y^2 + 1)))/ ... (exp(2*y)*(x + 1)^(1/2)) - exp(x)/ ... (exp(y)*(x - y)^x*(x + 1)^(1/2)) + ... (cos(x)*sin(y)*(x - y)^y)/(x + 1)^(1/2) + ... (cos(y)*sin(x)*(x - y)^y)/(x + 1)^(1/2) + ... (log((x^2 + 1)/(y^2 + 1))*cos(x)*sin(y))/ ... (exp(y)*(x + 1)^(1/2)) + (log((x^2 + 1)/ ... (y^2 + 1))*cos(y)*sin(x))/(exp(y)*(x + 1)^(1/2));
Now executing the simplify command does not seem to be helpful:
S = simplify(log(a)+log(b)); pretty(S)
/ y
| sin(x + y) sin(x + y) (x - y)
log| ------------------- + ------------------- +
| x 1/2 1/2
\ (x - y) (x + 1) (x + 1)
y
#1 sin(x + y) exp(x) (x - y)
------------- - --------------- -
#2 #2
\
exp(x) #1 exp(x) |
------------------- - -------------------------- | +
1/2 x 1/2 |
exp(2 y) (x + 1) exp(y) (x - y) (x + 1) /
/ 1/2 /
log| - ((x + 1) ) / | (exp(x - y) - sin(x + y))
| |
\ \
/ #1 y 1 \ \ \
| ------ + (x - y) + -------- | | |
| exp(y) x | | |
\ (x - y) / / /
where
/ 2 \
| x + 1 |
#1 = log| ------ |
| 2 |
\ y + 1 /
1/2
#2 = exp(y) (x + 1)
Assuming
and
to be positive does not significantly improve the result either. The reason is that we need to set such assumptions on
and
that would make the expressions
and
positive. We can try to find the right assumptions for this example, but in general it seems like one has to be a genius
to guess what's appropriate.
Using Option IgnoreAnalyticConstraints for Simplification
A possible solution to the problem is to ignore certain analytic constraints, that is, to use the IgnoreAnalyticConstraints option for simplify.
With this option the simplifier internally applies the following rules:
for all values of
and
. In particular
for all values of
,
and
.
for all values of
and
. In particular
for all values of
,
and
.
- If
and
are standard math functions and
holds for all small positive numbers, then
is assumed to be valid for all
(for example as in case of
).
So how does this work in our example?
simplify(log(a)+log(b),'IgnoreAnalyticConstraints',true)ans = 0
The result is
, because
. Hence, under the above assumptions, we get
.
Of course, it is important to keep in mind that the rules applied by IgnoreAnalyticConstraints are not correct in a strict mathematical sense. Nevertheless, in practice these rules are often very helpful to get simpler results. Another nice side effect is that ignoring some analytic constraints often helps you speed up your computations.
This documentation describes more details on IgnoreAnalyticConstraints.
Using IgnoreAnalyticConstraints for Equation Solving
Not surprisingly the concept of ignoring analytic constraints also makes sense for equation solving. Imagine that you want
to solve the equation
for
. Ignoring analytic constraints would certainly mean to write this as
. Assuming
to be nonzero we get
and, finally,
.
Without using any restrictions, Symbolic Math Toolbox returns the result:
syms x n solve(log(x^n),x)
Warning: The solutions are parametrized by the symbols: k = Z_ intersect Dom::Interval([-1/(2*Re(1/n))], 1/(2*Re(1/n))) ans = 1/exp((pi*k*2*i)/n)
So you get a parameterized solution which strongly depends on the values of
. This is reasonable, because, for example, for
you get the four solutions
solve(log(x^4),x)
ans = 1 -1 i -i
whereas for
there only is one solution:
solve(log(x^(1/2)),x)
ans = 1
Applying IgnoreAnalyticConstraints we get
solve(log(x^n),x,'IgnoreAnalyticConstraints',true)ans = 1
Also for equations involving roots where no additional symbolic parameters are present, it may be useful to apply IgnoreAnalyticConstraints to get simpler results:
solve(x^(5/2) - 8^(sym(10/3)), 'IgnoreAnalyticConstraints', true)ans = 16
Here the solver ignores branch cuts during internal simplifications and, hence, returns only one solution.
See the MATLAB doc page on solve for further details.
The IgnoreAnalyticConstraints option can also be used for other Symbolic Math Toolbox functions like the function int for doing symbolic integration. The option is also available for the related MuPAD Notebook Interface functions.
Have You Tried IgnoreAnalyticConstraints?
Have you tried the IgnoreAnalyticConstraints option to get simpler, shorter, and easier to handle results?
Let me know here.
Get
the MATLAB code
Published with MATLAB® 7.13



Two of the listed rules are not completely true. The rule #1 should be replaced by
sqrt(x^2)=abs(x), to take into account the case of x<0
The rule #4 is true only if -pi/2 <= x > asin(sin(x))
ans =
0.7854
Greetings
Vittorio
Hi Vittorio,
you are absolutely right. Also the rules on the logarithm are not correct without any additional assumptions. That is exactly the point of the IgnoreAnalyticConstraints concept: you do not have to specify all necessary assumptions – the internal algorithms ignore certain assumptions automatically. Note that when you use simplify without IgnoreAnalyticConstraints and without setting assumptions like the ones you mentioned, the rules will not be applied (as it should be).
Your example about the square root is a good one to demonstrate the different behaviors. In this case, ignoring analytic constraints means that the simplifier automatically assumes x to be positive real:
Hope this helps to clarify the situation.
Best regards,
– Kai
“Have you tried the IgnoreAnalyticConstraints option to get simpler, shorter, and easier to handle results?”
No, but I will certainly try them now! :) Sometimes it’s frustrating to get complicated results from the symbolic solver, when a little pen & paper takes care of things. This post certainly explains a lot, and I will dig in further in the docs, since there’s a lot happening under the hood.
I’ve used “syms a b real” in the past, it was specially useful when dealing with trigonometric functions. It gets rid of a lot of conj() operations, which usually results in more helpful simplifications!
One question: Has the team considered one day extending the solver to deal with linear algebra operations? Not calculating element-by-element matrices, but applying algebra simplifications to general M-by-N matrices.
Constraints like saying a matrix is square or pos.-def. could help, as well as keeping track of a matrix’s rank and other info through the transformations. Just asking; I know it would be a serious effort on your part of course!
Hi Jotaf,
thanks for your kind reply!
It is great to know that the IgnoreAnalyticConstraints concept is something which you will try out in the future when doing symbolic computations.
I took myself a note about your comment regarding the symbolic linear algebra computations for general matrices. In fact, I remember other people asking questions which go into a similar direction. I will definitely take your comment/question to our team discussions.
Thanks again and best regards,
– Kai