假设我有一个向量t = [0 0.1 0.9 1 1.4]
和一个向量x = [1 3 5 2 3]
。如何根据与原始向量长度相同的时间计算x
的导数?
我不应该使用任何符号操作。命令diff(x)./diff(t)
不会生成相同长度的向量。我应该先插入x(t)
函数然后取其衍生物吗?
答案 0 :(得分:2)
存在不同的方法来计算与初始数据相同点的导数:
或
请注意,曲线拟合方法可以提供更好的结果,但需要更多的调整选项,速度更慢(~100x)。
<强>示范强>
作为一个例子,我将计算正弦函数的导数:
t = 0:0.1:1;
y = sin(t);
它的确切衍生物是众所周知的:
dy_dt_exact = cos(t);
导数大致可以计算为:
有限差异:
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
或
多项式拟合:
p = polyfit(t,y,5); % fit fifth order polynomial
dp = polyder(p); % calculate derivative of polynomial
结果可视化如下:
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
第一张图显示了衍生物本身,第二张图显示了两种方法产生的相对误差。
<强>讨论强>
人们清楚地看到曲线拟合方法比有限差分给出了更好的结果,但它慢了约100倍。曲线拟合方法具有阶10^-5
的相对误差。请注意,当您的数据采样更密集或使用更高阶的方案时,有限差分方法会变得更好。曲线拟合方法的缺点是必须选择良好的多项式阶。样条函数通常可能更适合。
快10倍的采样数据集,即t = 0:0.01:1;
,得到以下图表: