I define a symbolic expression (dx_3dt) and make an assumption that reduces that expression to one term. By this the function _plus(...) appears in my expression (Output dx_3dt) which is apparently not differentiable by Matlabs definition leading to NaN value. Differentiating the same expression "manually" allows me to obtain the correct solution.
Any advice how to handle this?
MWE:
clear all;
reset(symengine)
theta = sym('theta_%d', [5, 1], {'positive', 'real'});
x = sym('x_%d', [6, 1], {'positive', 'real'});
grav = 9810;
eps = 1e-10;
outflow = piecewise(x(3) <= eps, 0, -theta(5)*sqrt(2*grav*x(3)));
dx_3dt = theta(4)*sign(x(2)-x(3))*sqrt(2*grav*abs(x(2)-x(3)))+theta(2)*x(5)+outflow;
simplify(diff(dx_3dt, x(2)))
assumeAlso(x(2) == x(3))
simplify(dx_3dt)
Output dx_3dt in command window:
piecewise(x_3 <= 1/10000000000, _plus(theta_2*x_5), theta_2*x_5 - 6*545^(1/2)*theta_5*x_3^(1/2) + 6*545^(1/2)*theta_4*abs(x_2 - x_3)^(1/2)*sign(x_2 - x_3))
Expected result:
simplify(diff(dx_3dt, x(2)))
diff(theta(2)*x(5), x(2))
First ideas
The problem seems to be the piecewise function since omitting piecewise gives the expected result:
clear all;
reset(symengine)
theta = sym('theta_%d', [5, 1]);
x = sym('x_%d', [6, 1]);
grav = 9810;
eps = 1e-10;
dx_3dt = theta(4)*sign(x(2)-x(3))*sqrt(2*grav*abs(x(2)-x(3)))+theta(2)*x(5)-theta(5)*sqrt(2*grav*x(3));
simplify(diff(dx_3dt, x(2)))
assumeAlso(x(2) == x(3))
simplify(dx_3dt)
simplify(diff(dx_3dt, x(2)))
diff(theta(2)*x(5), x(2))
Problem with diff and assumptions
Furhtermore if I apply the following workaround with replacing the critical term with a symbolic function of x_3 and assume that x_3 == x_2 and differentiate with respect to x_2 it is zero! So the diff function appears to also not consider assumptions here:
clear all;
reset(symengine)
theta = sym('theta_%d', [5, 1], {'positive', 'real'});
x = sym('x_%d', [6, 1], {'positive', 'real'});
grav = 9810;
eps = 1e-10;
syms x_3 outflow(x_3)
dx_2dt = theta(3)*x(6)*sign(x(1) - x(2))*sqrt(2*grav*abs(x(1)-x(2)))-theta(4)*sign(x(2)-x(3))*sqrt(2*grav*abs(x(2)-x(3)))
dx_3dt = theta(4)*sign(x(2)-x(3))*sqrt(2*grav*abs(x(2)-x(3)))+theta(2)*x(5)+outflow(x_3)
f = [dx_2dt; dx_3dt];
simplify(diff(dx_3dt, x(2)))
simplify(diff(dx_3dt, x(3)))
assumeAlso(x(2) == x(3))
simplify(dx_3dt)
assumptions(x(2))
assumptions(x(3))
simplify(dx_3dt)
simplify(diff(dx_3dt, x(2)))
simplify(diff(dx_3dt, x(3)))
jac = simplify(jacobian(f, x))
0 Comments
Sign in to comment.