Search code examples
matlabtrigonometrysymbolic-math

Using symbolic toolbox to simplify expressions of known functions (e.g. trigonometric functions)


I would like to use matlab to simplify expressions of e.g. trigonometric functions for me. For example I tried this:

syms x;
simplify(sin(x)/cos(x))

My expected output would have been

tan(x)

but instead I just got

sin(x)/cos(x)

again. So I did a little research and found rewrite which KIND OF does what I want. I can use

syms(x);
simplify(rewrite(sin(x)/cos(x),`tan`))

and I will get

tan(x)

which is what I wanted in this case. The thing is that I will not always know, what target function I want to achieve. On wolframalpha.com these kind of things are easy to achieve. You just put your expression there and it will give you the best simplification of it. Is there any way to achieve this in matlab, too?


Solution

  • MATLAB is just being safe.

    The symbolic toolbox can do some incredible simplifications, including those that use trigonometric functions. Most of the simplifications you want MATLAB to do will happen when you call simplify, but the one you've posted has a minor problem.

    The issue here can be shown if you try to simplify your equality. Look at this simple example:

    simplify(x==x) % Returns symbolic "TRUE"
    

    On that note, I'd expect the line below to also return TRUE.

    simplify(tan(x) == sin(x) / cos(x))
    

    But instead, it returns ~x in Dom::ImageSet(pi*(k + 1/2), k, Z_)

    When x is in the set described above {..., -pi/2, pi/2, 3pi/2, ...}, it means cos(x) == 0, and sin(x)/cos(x) causes a division by zero error, whereas tan(x) approaches a value of inf. Therefore, at those values, tan(x) ~= sin(x)/cos(x).

    Experiment

    Out of curiosity, I ran the following script:

    clc, clear;
    
    % Create the symbolic variable and remove all assumptions placed on it.
    syms x; 
    assume(x,'clear');
    
    % Define the function, and test MATLAB's behavior
    y = sin(x)/cos(x);
    disp('Before assuming:');
    disp(simplify(y));
    disp(simplify(tan(x) == y));
    
    % Place restriction on cos(x), and re-test MATLAB's behavior
    assume(cos(x) ~= 0);
    disp('After assuming:');
    disp(simplify(y));
    disp(simplify(tan(x) == y));
    

    And the output was:

    Before assuming:
    sin(x)/cos(x)
    ~x in Dom::ImageSet(pi*(k + 1/2), k, Z_)
    
    After assuming:
    sin(x)/cos(x)
    TRUE
    

    As expected, it didn't simplify the function the first time because cos(x) may equal zero. The second result was surprising, though. After the assumption is made that cos(x) ~= 0, MATLAB properly stated that tan(x) == sin(x)/cos(x) is true, yet it still didn't simplify the expression. This could be due to complexity in the simplification process, or it could still be a safety concern, since I could at any point clear the assumption, and the equality would no longer hold.