symbolic math - Partial differential equation in Matlab (incorrect solution)

Let's define function `x(t)`, its time derivative `xdot(t)`, and expression `T` that is dependent on them:

``syms t x(t)xdot(t) = diff(x,t);T = (xdot + x)^2;``

We can all agree that partial derivative of `T` with respect to `x` is `∂T/∂x = 2*(xdot+x)`. However, if I do this in Matlab I get wrong answer:

``dT_dx = subs( diff( subs(T,x,'x'), 'x' ), 'x', x);>> dT_dx = 2 x(t)``

Note that it returns the correct answer for `∂T/∂xdot`:

``dT_dxdot = subs( diff( subs(T,xdot,'x1'), 'x1' ), 'x1', xdot);>> dT_dxdot = 2*x(t) + 2*diff(x(t), t)``

It looks like Matlab ignores the product `2*x*xdot`, when calculating derivatives in terms of lower order variables (`x`), but it doesn't ignore this product when calculating derivative in terms of higher order variables (`xdot`). If we redefined the expression `T` as `T = (100 + x)^2`, we would get `∂T/∂x`:

``>> ans = 2 x(t) + 200``

Thus, after having swapped `xdot` with a constant we now obtain correct answer.

• I utilized double substitution in order to use the `diff` function,

because `diff(T,x)` returns an error. I found this approach

here.

• Expanding the expression `T` before calculating the derivative does not work –

• I also tried the `functionalDerivative` function, but it returns the incorrect

Question

How can one reliably calculate partial and absolute derivatives of `T`, especially `∂T/∂x`?

Is `subs( diff(subs() ) )` a good approach, or is there a better way, and, if so, what is it?

As you've noticed, taking the derivative of an abstract `symfun` like `x(t)` is not the same as taking the derivative of a symbolic variable like `x` (assuming `x(t)` hasn't already been declared in the scope) – see my answer here for more. One needs to be very careful substituting like you're doing. The problem arrises because `x(t)` gets substituted for `'x'` inside of `diff(x,t)` (`xdot(t)`) too, i.e., the first substitution in your code, `subs(T,x,'x')`, already returns an incorrect result relative to what you expect.

You can try this:

``````syms x(t)
xdot(t) = diff(x,t);
T = (xdot + x)^2;
x1 = {x,xdot};
x2 = {'x','xdot'};
dT_dx = subs(diff(subs(T,x1,x2),'x'),x2,x1)
``````

which returns `2*x(t) + 2*diff(x(t), t)`.