why Solve function does not give correct solution?

20 views (last 30 days)
I use the following code to obtain the solutions, however, some given solutions do not satisfy the equations, for example, the first one.
syms a b c
eqns = [(a)+(b)+(c)==0, sin(a)==sin(b), sin(b)==sin(c)];
S = solve(eqns);
sol = [S.a,S.b,S.c]
sol =
[ (2*pi)/3, -(2*pi)/3, 0]
[-(2*pi)/3, (2*pi)/3, 0]
[ pi, 0, -pi]
[ 0, pi, -pi]
[ (2*pi)/3, (2*pi)/3, -(4*pi)/3]
[-(2*pi)/3, -(2*pi)/3, (4*pi)/3]
[ 0, 0, 0]
[ (2*pi)/3, 0, -(2*pi)/3]
[ 0, (2*pi)/3, -(2*pi)/3]
[-(2*pi)/3, 0, (2*pi)/3]
[ 0, -(2*pi)/3, (2*pi)/3]
Can anyone help? Thank you so much!

Accepted Answer

John D'Errico
John D'Errico on 5 Feb 2022
Edited: John D'Errico on 6 Feb 2022
When you solve a nonlinear system of equations, at times, some solutions are spurious. They fail, because some operation in the solve created additional "solutions" that satisy a transformed version of the problem, yet not the original equations.
An example of this is to solve the problem:
x - 1 == 0
However, I'll do it by first by adding 1 to both sides, then I'll square it. Now we have
x^2 == 1^2
If the first was true, then so must be the second. But now if we solve that transformed problem, there are two solutions, we would now report x = +/-1. And only one of those solutions is valid. Spurious solutions have been created. While squaring the above equation as I did was a silly thing to do in context, it is often necessary when we have trig functions, because most trig identities involve squares of trig functions. This is likely the cause of your problem.
syms a b c
eqns = [(a)+(b)+(c)==0, sin(a)==sin(b), sin(b)==sin(c)];
S = solve(eqns);
S.a
ans = 
Is it true that all of these are solutions to the equations given? Which were validly solutions?
ind = find((S.a + S.b + S.c == 0) & (sin(S.a) == sin(S.b)) & (sin(S.b) == sin(S.c)))
ind = 5×1
3 4 5 6 7
[S.a(ind),S.b(ind),S.c(ind)]
ans = 
Such is life. While I'm a bit surprised that so many spurious solutions were generated in the solve, it happens. A good idea is to verify that all solutions presented are indeed valid solutions. Could solve have done the same test itself, weeding out those solutions that are not truly solutions? Perhaps. Certainly in this case it could have done so, but on some more complex problems, that might be itself an issue. Think of this as a good thing - you are getting free solutions, a 2 for 1 sale! Twice as many solutions for the same price! I can offer you some prime swamp land in Florida too, for a great price. ;-)
  4 Comments
Walter Roberson
Walter Roberson on 6 Feb 2022
solve() can make use of identies that simplify() does not always know, or which can be difficult for simplify() to find.
Imagine, for example, that looking at one of the terms, solve() can factor X^2-Y^2 to (X+Y)*(X-Y) and that in context that turns out to be important (for example, matching against terms on the other side of the equality.). But other simulatenous equalities might require (for example) that X and Y are Bessel J and Hankel functions. In the X^2-Y^2 form after substituting in the Bessel and Hankel functions and squaring, elements of the imaginary part of the Hankel function become real, and could combine with the Bessel J function for X in a way that might be difficult to split apart later in order to verify an equality...
Paul
Paul on 6 Feb 2022
Edited: Paul on 6 Feb 2022
I'm not familiar enough (not really at all) with Bessel or Hankel functions to follow that example, but I'll take your word for it. But just because there may be cases where solve() can't verify its solutions doesn't necessarily mean that it should return results that can be veified to not be solutions. Or am I still missing something?
To me, the key statement is "solve() can make use of identities that simplify() does not always know." Does that mean simplify() needs to be improved? More importantly, it sounds like there may be a case where solve() returns a correct solution that can't be verified by subbing it back into the equation and using simplify() and other operations? It seems like that could be the case if solve() can use an identity that none of the other functions know.
Using the same example, it does appear that isAlways(), by itself, doesn't take advantage of the same identities as simplify()
Generate all apparent solutions:
syms a b c
eqns(a,b,c) = [(a)+(b)+(c)==0, sin(a)==sin(b), sin(b)==sin(c)];
S = solve(eqns,'ReturnConditions',true);
S.conditions
ans = 
Define k and l
syms k l integer
Sub solutions into the equations
check = eqns(S.a, S.b, S.c);
check = [check{:}]
check = 
Use simplify() to see which checks are true
simplify(check,100)
ans = 
Only solutions 3,4 an 7, seem to satisfy all three equations. But expanding first brings in two additional solutions. At least the doc page for simplify does say that using expand() first can be advantageous
simplify(expand(check))
ans = 
Use isAlways() to check the solutions
verify = isAlways(check,'Unknown','false')
verify = 11×3 logical array
1 0 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 0 0 1 0 0 1 0 0
Apparently only the third, fourth, and seventh solutions satisfy all three equations. But,obviously
verify = isAlways(simplify(expand(check)))
verify = 11×3 logical array
1 0 0 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 0 1 0 0
picks up the fifth and sixth solutions as well. The doc page for isAlways() doesn't say anything about simplifying, etc. the expression to be checked.
verified = all(verify,2);
sol(k,l) = [S.a(verified), S.b(verified), S.c(verified)]
sol(k, l) = 
So not only can solve() return extraneous results, care has to be taken in verifying the results.

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

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

Start Hunting!