Solve inequality in MATLAB (with answer probably be x could be any real number)

20 views (last 30 days)
I am trying to set up a solver for a symbolic matrix so its eigenvalue could be positive. This is my matrix [x^2+2 1; 1 1].
syms x lambda
A = [(x^2)+2 1; 1 1];
eqn1 = A-lambda*eye(2);
eqn2 = det(eqn1) == 0;
eqn3 = solve(eqn2, lambda) > 0;
eqn4 = solve(eqn3, x)
Warning: Unable to find explicit solution. For options, see help.
eqn4 = Empty sym: 0-by-1
I am given the answer that x could be any real number. I tested the equation in Desmos and it is true. But in MATLAB, the answer is:
Warning: Unable to find explicit solution. For options, see help.
> In sym/solve (line 317)
In AE504eigen (line 9)
eqn4 =
Empty sym: 0-by-1
Could you tell me what is going on?

Answers (1)

Walter Roberson
Walter Roberson on 26 Feb 2023
Over real values, all of the solutions are > 0 in both branches.
Over imaginary values, the first branch has some non-positive solutions -- indeed, over imaginary values, almost everything comes out complex-valued.
syms x lambda
A = [(x^2)+2 1; 1 1];
eqn1 = A-lambda*eye(2);
eqn2 = det(eqn1) == 0;
lambda_solve = solve(eqn2, lambda)
lambda_solve = 
eqn3 = lambda_solve == 0;
eqn4 = arrayfun(@(EXPR) solve(EXPR, x), eqn3, 'uniform', 0)
eqn4 = 2×1 cell array
{2×1 sym} {0×1 sym}
eqn4{1}
ans = 
trial_points = [randn(1,50) + 1i*randn(1,50), linspace(-2,2)];
ls1 = double(subs(lambda_solve(1), x, trial_points));
real_valued = imag(ls1) == 0;
nnz(real_valued)
ans = 100
rv_subset = trial_points(real_valued);
rv_positive = ls1(real_valued) > 0;
nnz(rv_positive)
ans = 100
rv_pos_subset = rv_subset(rv_positive);
rv_net_subset = rv_subset(~rv_positive);
scatter(real(rv_pos_subset), imag(rv_pos_subset), [], 'b^');
hold on
scatter(real(rv_net_subset), imag(rv_net_subset), [], 'kv');
nr_subset = trial_points(~real_valued);
scatter(real(nr_subset), imag(nr_subset), [], 'rx');
hold off
xlim auto; ylim auto
title('first solution')
legend({'>0', '<0', 'complex'})
ls2 = double(subs(lambda_solve(2), x, trial_points));
real_valued = imag(ls2) == 0;
nnz(real_valued)
ans = 100
rv_subset = trial_points(real_valued);
rv_positive = ls2(real_valued) > 0;
nnz(rv_positive)
ans = 100
rv_pos_subset = rv_subset(rv_positive);
rv_net_subset = rv_subset(~rv_positive);
scatter(real(rv_pos_subset), imag(rv_pos_subset), [], 'b^');
hold on
scatter(real(rv_net_subset), imag(rv_net_subset), [], 'kv');
nr_subset = trial_points(~real_valued);
scatter(real(nr_subset), imag(nr_subset), [], 'rx');
hold off
xlim auto; ylim auto
title('second solution')
legend({'>0', '<0', 'complex'})
  2 Comments
Walter Roberson
Walter Roberson on 26 Feb 2023
If the point isthat you are looking for solve() to explicitly tell you "the solution is all elements of R" then you will never get that when using solve() when 'returnconditions' is false (the default).
In every case where solve() without returnconditions internally returns a range or inequality or restriction on the solution, the interface layer between the symbolic engine and the presentation for display, converts the ranges or restrictions to a single "representative sample" -- one particular value that fits within the restrictions. There is a series of steps it takes to figure out which representative value to use; I worked through them a few years ago and posted my best approximation of the algorithm (I could not figure out some of the details.) But the first rule is that if 0 is valid within the range or restrictions then it uses 0 as the representative.
If you ask for 'returnconditions', true then you can sometimes read the boundaries from the conditions field of the result. But sometimes when you ask to return conditions, the solve() call takes much much longer (because it tries to nail down all possible conditions), and sometimes it just gives up and returns nothing even though the solution without return conditions was perfectly valid.
Walter Roberson
Walter Roberson on 26 Feb 2023
When you have an inequality for solve(), it is common that solve() cannot handle the situation at all well. And it is common that the inequality part is counted as a full equation for the point of "number of equations must match the number of variables being solved for".
There are two common strategies for working with inequalities in the Symbolic Toolbox:
  1. ask to solve() the equality, and then explore right "beside" the provided solution to try to determine which side of the boundary the inequality holds on; or
  2. add an extra variable with syms EXTRAVARIABLE; assume(EXTRAVARIABLE >= 0); and then rewrite the inequalities as equalities. f(x) <= c is f(x) - c <= 0 and so it follows that f(x) - c + EXTRAVARIABLE == 0 for some non-negative EXTRAVARIABLE and now you have an equality. Now you can solve the system leaving EXTRAVARIABLE as something not solved for (or solve for it if you need the number of variables to match the number of equations.) 'returnconditions' will typically pay attention to the assumption on EXTRAVARIABLE... which can lead to a lot of extra processing time... and can lead to unnecessary conditions on the solutions that are found because the symbolic engine does not bother trying to determine whether the same solution would be valid without the condition. So adding extra variables is not always smooth sailing, but when it works it can get you closed form solutions that are would not be obvious otherwise. It might, for example, tell you that EXTRAVARIABLE had to be within the two roots of a polynomial.

Sign in to comment.

Categories

Find more on Symbolic Math Toolbox in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!