问题描述:

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.

*Comments:*

- I utilized double substitution in order to use the
`diff`

function,because

`diff(T,x)`

returns an error. I found this approachhere.

- Expanding the expression
`T`

before calculating the derivative does not work –we still get incorrect answer.

- I also tried the
`functionalDerivative`

function, but it returns the incorrectanswer as well.

**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)`

.