Loren on the Art of MATLAB

October 25th, 2011

Simplifying Symbolic Results

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

4 Responses to “Simplifying Symbolic Results”

  1. Vittorio Casella replied on :

    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

  2. Kai Gehrs replied on :

    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:

    >> syms x
    >> withoutAssumption = simplify(sqrt(x^2))
    
    withoutAssumption =
    
    (x^2)^(1/2)
    
    >> syms x real
    >> assumingReal = simplify(sqrt(x^2))
    
    assumingReal =
    
    abs(x)
    
    >> syms x positive
    >> assumingPositive = simplify(sqrt(x^2))
    
    assumingPositive =
    
    x
    
    >> ignoringConstraints = simplify(sqrt(x^2),'IgnoreAnalyticConstraints',true)
    
    ignoringConstraints =
    
    x
    

    Hope this helps to clarify the situation.

    Best regards,
    – Kai

  3. Jotaf replied on :

    “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!

  4. Kai Gehrs replied on :

    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


MathWorks
Loren Shure works on design of the MATLAB language at MathWorks. She writes here about once a week on MATLAB programming and related topics.

These postings are the author's and don't necessarily represent the opinions of The MathWorks.