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.
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

Accepted Answer

Walter Roberson
Walter Roberson on 6 Oct 2021
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

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)];
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

Categories

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

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!