MATLAB Answers

Error solving piecewise system of equations

7 views (last 30 days)
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.
function [Out] = piecewise_test
% 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];
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)

Accepted Answer

Walter Roberson
Walter Roberson on 6 Oct 2021
You can get further if you rewrite to heaviside
Eqn2 = 
sol = struct with fields:
x: 0.5 y: 0.25
ans = 
function [Out] = piecewise_test
syms x y
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];

More Answers (1)

Andreas Apostolatos
Andreas Apostolatos on 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)];
y = [x(1, 1) + a - x(2, 1);
x(1, 1)^2 - x(2, 1)];
opts = optimoptions("fsolve", "Algorithm", "levenberg-marquardt");
sol = fsolve(@my_non_differentiable_function, [0.0; 0.0], opts);
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 =
i.e. the expected one. I hope this also helps you to get forward.
Kind regards,




Community Treasure Hunt

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

Start Hunting!

Translated by