Reducing symbolic expressions with assumptions, but NOT simplify?

9 views (last 30 days)
Hello, I have a very long symbolic expression that I am working with. Here is the relevant part of it:
Note that Om and OmT are each single symbolic variables representing angles (specifically, the RAAN in astrodynamics), i.e. they are NOT separate variables of O, m, and T multiplied together. I want to eliminate the from the denominator, as it produces divide by zero errors when Om = OmT. Given that appears in the numerator, then the ratio should simply reduce to after applying the Pythagorean identity in the denominator.
I cannot use the simplify function here, for two reasons: first, the entire expression is much larger than the snippet I've shown here, so it takes ridiculously long to run the function. Second, the only way simplify would succeed in reducing the ratio is if I passed in the IgnoreAnalyticConstraints flag, however:
  • it would reduce the entire ratio to just 1, but this is not necessarily true if the sine is negative. At the present moment, I believe I need to preserve the sign.
  • it would also reduce the acos(cos(Om-OmT)) term to just Om-OmT. That term is intentionally written as acos(cos(...)) and I need it to remain as it is.
TL;DR: do want simplified to ; do not want acos(cos(Om-OmT)) simplified to Om-OmT. What set of assumptions could I apply to Om and OmT using the assume function to achieve my desired behavior? Or is there a better way of going about this?
  1 Comment
Dyuman Joshi
Dyuman Joshi on 11 Oct 2023
Edited: Dyuman Joshi on 12 Oct 2023
The expected expression is not equivalent to the current expression, as the current expression is not defined for Om-OmT == pi*k, where k is an Integer, as it leads to 0/0 form.
Here, your question regarding assumptions comes into place -
syms Om OmT
x = Om-OmT;
% Let's assume that Om-OmT is not an integral multiple of 2*pi
assume(~in(x/(pi),"integer"))
%Check the assumptions made
assumptions
ans = 
%Define the expression
eqn = sin(x)/sqrt(1-cos(x)^2)
eqn = 
Now let's try to modify the expression and see if we get the expected result or not -
rewrite(eqn,'sin')
ans = 
No luck with rewrite. Let's try simplify() -
simplify(eqn,'Steps',100,'All',true)
ans = 
Unfortunately, simplify() does not help your case either. You are free to increase steps and check every output, but that would be futile.
Why does it not give the output after the assumption? I don't have the answer to that.
However, as the documentation of simplify states - Simplification of mathematical expression is not a clearly defined subject. There is no universal idea as to which form of an expression is simplest. The form of a mathematical expression that is simplest for one problem might be complicated or even unsuitable for another problem.
After all this, let's go with a last ditch attempt and use piecewise to define the expression.
%Using new variables as the older ones already have assumptions on them
syms v1 v2
y = piecewise(~in((v1-v2)/(pi),"integer"), 1, sin(v1-v2)/sqrt(1-cos(v1-v2)^2))
y = 
simplify(y)
ans = 
Well, the SymEngine just refuses to simplify the expression to the expected one. Sigh.
P.S - Take it that @Torsten is speaking from experience, saying that the only way to do what you want is as mentioned in the answer.

Sign in to comment.

Accepted Answer

Paul
Paul on 11 Oct 2023
Hi Aroni,
Consider the simple expression
syms x
f(x) = sin(x)/sqrt(1-cos(x)^2)
f(x) = 
Simplify
simplify(f)
ans(x) = 
If we assume that x is real, we can get a little further (I don't know if Om and OmT are real in your case)
assume(x,'real')
f(x) = simplify(f)
f(x) = 
but I don't think that solves the problem.
The assertion in the Question is that f(x) == sign(sin(x)). That's not true in general because f(x) is not defined when sin(x) == 0, i.e., x an integer multiple of pi, even though sign(sin(x)) is.
Side note: interestingly enough, Matlab actually thinks that equality holds in general
cond = f(x)==sign(sin(x));
isAlways(cond)
ans = logical
1
even though it shouldn't because "isAlways(cond) checks if the condition cond is valid for ALL possible values of the symbolic variables in cond. When verifying cond, the isAlways function considers all assumptions on the variables in cond." (emphasis added). The condtion doesn't hold for x = 0, for example, because the LHS can't even be evaluated for comparison to the RHS
try
f(0)
catch ME
ME.message
end
ans = 'Division by zero.'
Maybe isAlways excludes values of the variables in cond that can't be in the domain of the expressions in cond. IDK.
Anyway, if you want to assert that f(x) == sign(sin(x)) you can try to use subs
f(x) = sin(x)/sqrt(1-cos(x)^2)
f(x) = 
f(x) = subs(f(x),sin(x)/sqrt(1-cos(x)^2),sign(sin(x)))
f(x) = 
  1 Comment
Aroni Gupta
Aroni Gupta on 12 Oct 2023
I think this is the best solution to my answer. I'm still relatively new to the symbolic toolbox, so I wasn't aware that you could substitute for entire expressions in that way. But it seems to do exactly what I want. Thank you so much!

Sign in to comment.

More Answers (1)

Torsten
Torsten on 11 Oct 2023
Moved: Torsten on 11 Oct 2023
Given your expression from above, subtract it from the complete expression and add it with sin(x)/sqrt(1-cos(x)^2) substituted by sign(sin(x)). I think this is the only way to achieve what you want.
syms x
f = sin(x)/sqrt(1-cos(x)^2);
f = f - sin(x)/sqrt(1-cos(x)^2) + sign(sin(x))
f = 
  1 Comment
Aroni Gupta
Aroni Gupta on 12 Oct 2023
While this is a good idea, unfortunately in my specific case the form of my entire equation makes doing this not trivial for me. Thank you for the advice though!

Sign in to comment.

Tags

Products


Release

R2023a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!