问题描述:

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 approach

    here.

  • 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 incorrect

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

相关阅读:
Top