A Tip for Solving Systems of Equations with solve in the Symbolic Math Toolbox
Recently, I encountered an issue where solve returned no solution for a system of equations, even though the system obviously has solutions. This can be easy to overlook.
For example:
syms a b c x
equs = [a*x^2+b*x+c==0;
a==1];
St = solve(equs,x)
St is returned as an empty set, suggesting that there is no solution???
However, since a is constrained by the equation a == 1, the correct way is:
S = solve(equs,[x,a])
disp(S.x)
disp(S.a)
Here, a must also be included in the list of variables to solve for. Only then will solve treat a as an unknown, apply the constraint a == 1, and substitute it into the equation during the solving process.
symvar(equs)
Based on the output of the symvar function, a is already identified as one of the symbolic variables (unknowns) in the system of equations. However, the actual behavior of solve appears to contradict this expectation. In practice, a must still be explicitly included in the variable list passed to solve; otherwise, it is treated as a symbolic parameter rather than a variable to be solved for.
Takeaway: When using solve for a system of equations, any symbol that appears in the equations and is constrained by additional equations (such as a == 1) should generally be included in the variable list. Otherwise, solve may treat it as a symbolic parameter rather than an unknown, which can lead to an empty solution set or unexpected results.
Am I missing something here? I'd love to hear your thoughts.
12 Comments
Time DescendingThat looks like a bug to me. At minimum it's an unexpected, if not indefensible, result based on the doc page for solve. If you do report it as a bug to Technical Support, would you mind updating your post with their response.
I can see where solve gets confused. Not that it totally should be confused. But I can see where it went.
You gave it a system of 2 equations, in one unknown. It is conceptually no different from this simpler form:
syms a x
eq1 = [x == 2;a == 1];
solve(eq1,x)
If a is not an unknown, then the second clause in the pair becomes a problem, because solve cannot establish if it is true.
I'll instead try a slightly different problem. Does solve succeed now?
eq2 = [x == 2, 2*x == 4];
solve(eq2,x)
And logically, solve is now happy. Two equations, with one unknown. They are redundant of course, but solve did not complain here. Solve can also know when the equations posed are inconsistent, for example here:
eq3 = [x == 2, 2*x == 5];
solve(eq3,x)
In the latter case, solve returns no solution. And we would have no complaints. The issue is why the first problem returns the same empty result as the third. In the latter case, the problem indeed has no solution due to the inconsistency. I suppose it might be nice if solve were able to explain why it found no solution for eq1, ascompared to eq3.
Returning to eq1, here if a is not specified as an unknown, then a apparently is a parameter in the eyes of solve. But it has no known value, and so a lies in a netherworld, in limbo. Can we still have a in the second clause and see solve be happy? Well, apparently yes. For example, consider eq4.
eq4 = [x == 2;a*(x-2) == 0];
solve(eq4,x)
Here the value of a is known to be irrelevant. One might think a==0 is a problem, but not so, since if a were zero, then the second clause is still trivially true. And solve seems to understand that.
s = solve(eq4,x,returnconditions = true)
Anyway, the problem we saw with eq1 is that when a is not listed as an unknown, then the second clause can never be known to be true or not. And then no solution can be known to exist, even though the two clauses are independent. Solve knowns only that you gave it two equations to be solved.
Your understanding is correct.
Sign in to participate
