MATLAB Answers

Error solving piecewise system of equations

7 ビュー (過去 30 日間)
Jeremy Mercer
Jeremy Mercer 2021 年 10 月 6 日
回答済み: Andreas Apostolatos 2021 年 10 月 6 日
I am using vpasolve to numerically solve systems of equations. I tried to solve a problem that had a piecewise function in it and it did not work. I made the simplest problem I could that replicated the issue below to troubleshoot the issue. If I set the initial parameters to the exact answer ([0.5,0.25]), MATLAB confirms the solution. If I set the initial parameters slightly away from the solution (for example [0.5,0.24999]), the function fails to find a solution.
piecewise_test
function [Out] = piecewise_test
a=-0.25;
% a=1;
syms x y
eqn1 = y == x+a;
% if abs(x)>=1
% eqn2 = y == abs(x);
% else
% eqn2 = y == x^2;
% end
eqn2 = y == piecewise(abs(x)>=1,abs(x),x^2);
sol=vpasolve([eqn1, eqn2],[x, y],[0.0,0.0])
Out=[sol.x, sol.y];
end
In the full problem, the solution can be predicted decently within a range, so using initial parameters is fine as long as it can find the answer within 1 order of magnitude of the initial parameter.
I am looking to calculate a numerical solution and I am ignoring any complex or negative solutions. I want to keep solve time down if possible as the function runs at least 200 times in my code.
I tried updating MATLAB to R2021a (I was using R2020a before) and now the function gives me an error even if the initial conditions match the solution
Error using mupadengine/feval_internal
Unable to differentiate the equation.
Error in sym/vpasolve (line 172)
sol = eng.feval_internal('symobj::vpasolve',eqns,vars,X0);
Error in Piecewise_Test>piecewise_test (line 18)
sol=vpasolve([eqn1, eqn2],[x, y],[0.5,0.25])
Error in Piecewise_Test (line 5)
piecewise_test

採用された回答

Walter Roberson
Walter Roberson 2021 年 10 月 6 日
You can get further if you rewrite to heaviside
piecewise_test
Eqn2 = 
sol = struct with fields:
x: 0.5 y: 0.25
ans = 
function [Out] = piecewise_test
syms x y
a=-0.25;
eqn1 = y == x+a;
%eqn2 = y == piecewise(abs(x)>=1,abs(x),x^2)
Eqn2 = y == heaviside(abs(x)-1) .* abs(x) + heaviside(1-abs(x)) .* x^2
sol=vpasolve([eqn1, Eqn2],[x, y],[0.0,0.0])
Out=[sol.x, sol.y];
end
  1 件のコメント
Jeremy Mercer
Jeremy Mercer 2021 年 10 月 6 日
Thanks this appears to work.

サインインしてコメントする。

その他の回答 (1 件)

Andreas Apostolatos
Andreas Apostolatos 2021 年 10 月 6 日
Hi Jeremy,
Adding to the excellent recommendation of Walter, there is also the possibility to use function 'fsolve()' to solve your system of nonlinear equations without considering symbolic expressions, especially since you are only concerned with the numerical solution of the problem, namely,
sol = piecewise_test
function sol = piecewise_test
a = -0.25;
function y = my_non_differentiable_function(x)
if abs(x(1, 1)) >= 1
y = [x(1, 1) + a - x(2, 1);
abs(x(1, 1)) - x(2, 1)];
else
y = [x(1, 1) + a - x(2, 1);
x(1, 1)^2 - x(2, 1)];
end
end
opts = optimoptions("fsolve", "Algorithm", "levenberg-marquardt");
sol = fsolve(@my_non_differentiable_function, [0.0; 0.0], opts);
end
where your piecewise expression is herein rewritten by means of a nested function 'my_non_differentiable_function()'. The result of the latter code snippet in this case is,
sol =
0.5000
0.2500
i.e. the expected one. I hope this also helps you to get forward.
Kind regards,
Andreas

製品


リリース

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by