MATLAB 中微分实现的差异

Differences in Differentiation Implementations in MATLAB

我试图找到特定点的(数值)曲率。我将数据存储在一个数组中,我基本上想找到每个单独点的局部曲率。我四处搜索,在 MATLAB 中找到了三种不同的实现方式:diffgradientdel2.

如果我的数组名称是 arr 我已经尝试了以下实现:

curvature = diff(diff(arr));
curvature = diff(arr,2); 
curvature = gradient(gradient(arr)); 
curvature = del2(arr); 

前两个似乎输出相同的值。这是有道理的,因为它们本质上是相同的实现。但是,gradientdel2 实现给出了彼此不同的值以及与 diff 不同的值。

我无法从文档中准确了解实现的工作原理。我的猜测是,其中一些是某种类型的双向导数,而另一些则不是双向导数。另一件让我感到困惑的事情是,我当前的实现仅使用来自 arr 的数据。 arr 是我的 y 轴数据,x 轴基本上是时间。这些函数的步长是否默认为 1 或类似值?

如果有帮助,我想要一个仅使用 previous 数组元素获取当前点曲率的实现。对于上下文,我的数据是基于当前点未来数据的曲率计算对我的目的没有用。

tl;dr 我需要一个严格的点曲率实现,它只使用点左侧的数据。

编辑:由于下面的回答,我更好地理解了基于此发生的事情。这就是我所指的:

gradient calculates the central difference for interior data points. For example, consider a matrix with unit-spaced data, A, that has horizontal gradient G = gradient(A). The interior gradient values, G(:,j), are

G(:,j) = 0.5*(A(:,j+1) - A(:,j-1)); The subscript j varies between 2 and N-1, with N = size(A,2).

即便如此,我还是想知道如何进行"lefthand"计算。

diff 只是 arr 中两个相邻元素之间的差异,这正是你使用一次 diff 会丢失 1 个元素的原因。例如,一个数组中的10个元素只有9个不同。

gradient 和 del2 用于导数。当然,你可以用 diff 来近似求导,将差值除以步长。通常步长是 equally-spaced,但也不是必须的。这回答了您为什么在计算中不使用 x 的问题。我的意思是,你的 x 不统一也没关系-spaced.

那么,为什么梯度给我们一个与原始数组长度相同的数组?手册中清楚地解释了边界是如何处理的,

The gradient values along the edges of the matrix are calculated with single->sided differences, so that

G(:,1) = A(:,2) - A(:,1);

G(:,N) = A(:,N) - A(:,N-1);

double-gradient和del2虽然高度相关,但不一定相同。这都是因为你如何 calculate/approximate 二阶导数。不同的是,前者通过两次一阶导数逼近二阶导数,而后者直接逼近二阶导数。请参考帮助手册,公式都有说明。

好的,你真的想要 arr 上每个点的曲率或二阶导数吗?他们非常不同。 https://en.wikipedia.org/wiki/Curvature#Precise_definition

你可以使用 diff 从左边得到二阶导数。由于 diff 从右到左取差,例如x(2)-x(1),可以先把x从左到右翻转,再用diff。一些代码,例如,

x=fliplr(x)
first=x./h
second=diff(first)./h

其中 h 是 x 之间的 space。请注意,我使用 ./,它表示 h 可以是一个数组(即非均匀 spaced)。