Solve inequality in MATLAB (with answer probably be x could be any real number)
12 ビュー (過去 30 日間)
古いコメントを表示
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)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1307165/image.png)
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?
1 件のコメント
回答 (1 件)
Walter Roberson
2023 年 2 月 26 日
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)
eqn3 = lambda_solve == 0;
eqn4 = arrayfun(@(EXPR) solve(EXPR, x), eqn3, 'uniform', 0)
eqn4{1}
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)
rv_subset = trial_points(real_valued);
rv_positive = ls1(real_valued) > 0;
nnz(rv_positive)
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)
rv_subset = trial_points(real_valued);
rv_positive = ls2(real_valued) > 0;
nnz(rv_positive)
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 件のコメント
Walter Roberson
2023 年 2 月 26 日
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
2023 年 2 月 26 日
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:
- 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
- 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.
参考
カテゴリ
Help Center および File Exchange で Assumptions についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!