Error solving piecewise system of equations
8 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Jeremy Mercer
le 6 Oct 2021
Réponse apportée : Andreas Apostolatos
le 6 Oct 2021
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
0 commentaires
Réponse acceptée
Walter Roberson
le 6 Oct 2021
You can get further if you rewrite to heaviside
piecewise_test
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
Plus de réponses (1)
Andreas Apostolatos
le 6 Oct 2021
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
0 commentaires
Voir également
Catégories
En savoir plus sur Symbolic Math Toolbox dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!