包括边界点在内的所有采样点的非符号导数

时间:2017-07-06 16:54:40

标签: matlab derivative

假设我有一个向量t = [0 0.1 0.9 1 1.4]和一个向量x = [1 3 5 2 3]。如何根据与原始向量长度相同的时间计算x的导数?

我不应该使用任何符号操作。命令diff(x)./diff(t)不会生成相同长度的向量。我应该先插入x(t)函数然后取其衍生物吗?

1 个答案:

答案 0 :(得分:2)

存在不同的方法来计算与初始数据相同点的导数:

  1. 有限差异:在您的内部点使用中央差异计划,在第一个/最后一个点使用前进/后退计划
    1. 曲线拟合:在曲线中拟合曲线,计算此拟合函数的导数,并在与原始数据相同的点处对其进行采样。典型的拟合函数是多项式或样条函数。
    2. 请注意,曲线拟合方法可以提供更好的结果,但需要更多的调整选项,速度更慢(~100x)。

      <强>示范

      作为一个例子,我将计算正弦函数的导数:

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

      它的确切衍生物是众所周知的:

      dy_dt_exact = cos(t);
      

      导数大致可以计算为:

      1. 有限差异:

        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
        
        1. 多项式拟合:

          p = polyfit(t,y,5); % fit fifth order polynomial
          dp = polyder(p); % calculate derivative of polynomial
          
        2. 结果可视化如下:

          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

          第一张图显示了衍生物本身,第二张图显示了两种方法产生的相对误差。

          <强>讨论

          人们清楚地看到曲线拟合方法比有限差分给出了更好的结果,但它慢了约100倍。曲线拟合方法具有阶10^-5的相对误差。请注意,当您的数据采样更密集或使用更高阶的方案时,有限差分方法会变得更好。曲线拟合方法的缺点是必须选择良好的多项式阶。样条函数通常可能更适合。

          快10倍的采样数据集,即t = 0:0.01:1;,得到以下图表:

          enter image description here enter image description here