1
votes

Suppose I have a vector t = [0 0.1 0.9 1 1.4], and a vector x = [1 3 5 2 3]. How can I compute the derivative of x with respect to time that has the same length as the original vectors?

I should not use any symbolic operations. The command diff(x)./diff(t) does not produce a vector of the same length. Should I first interpolate the x(t) function and then take its derivative?

1
the differential can never have the same length unless you define its value at some initial point. Something like dx/dt = 0 at t = 0. Then you can append this initial value at the beginning of diff(x) ./ diff(t) - ammportal
@ammportal I do not agree with you, see my answer. Do you agree? - m7913d
i think i was a little unclear in my comment. The differential will never have the same length with the approach used by the OP, i.e., using diff(x) ./ diff(t). Of-course the method you have described is better suited. - ammportal

1 Answers

2
votes

Different approaches exist to calculate the derivative at the same points as your initial data:

  1. Finite differences: Use a central difference scheme at your inner points and a forward/backward scheme at your first/last point

or

  1. Curve fitting: Fit a curve through your points, calculate the derivative of this fitted function and sample them at the same points as the original data. Typical fitting functions are polynomials or spline functions.

Note that the curve fitting approach gives better results, but needs more tuning options and is slower (~100x).

Demonstration

As an example, I will calculate the derivative of a sine function:

t = 0:0.1:1;
y = sin(t);

Its exact derivative is well known:

dy_dt_exact = cos(t);

The derivative can approximately been calculated as:

  1. Finite differences:

    dy_dt_approx = zeros(size(y));
    dy_dt_approx(1) = (y(2) - y(1))/(t(2) - t(1)); % forward difference
    dy_dt_approx(end) = (y(end) - y(end-1))/(t(end) - t(end-1)); % backward difference
    dy_dt_approx(2:end-1) = (y(3:end) - y(1:end-2))./(t(3:end) - t(1:end-2)); % central difference
    

or

  1. Polynomial fitting:

    p = polyfit(t,y,5); % fit fifth order polynomial
    dp = polyder(p); % calculate derivative of polynomial
    

The results can be visualised as follows:

figure('Name', 'Derivative')
hold on
plot(t, dy_dt_exact, 'DisplayName', 'eyact');
plot(t, dy_dt_approx, 'DisplayName', 'finite difference');
plot(t, polyval(dp, t), 'DisplayName', 'polynomial');
legend show

figure('Name', 'Error')
hold on
plot(t, abs(dy_dt_approx - dy_dt_exact)/max(dy_dt_exact), 'DisplayName', 'finite difference');
plot(t, abs(polyval(dp, t) - dy_dt_exact)/max(dy_dt_exact), 'DisplayName', 'polynomial');
legend show

enter image description here enter image description here

The first graph shows the derivatives itself and the second graph plots the relative errors made by both methods.

Discussion

One clearly sees that the curve fitting method gives better results than the finite differences, but it is ~100x slower. The curve fitting methods has a relative error of order 10^-5. Note that the finite differences approach becomes better when your data is sampled more densely or you use a higher order scheme. The disadvantage of the curve fitting approach is that one has to choose a good polynomial order. Spline functions may be better suited in general.

A 10x faster sampled dataset, i.e. t = 0:0.01:1;, results in the following graphs:

enter image description here enter image description here