在 Matlab 中找到离散数据集的拐点

Find the inflection point of a discrete dataset in Matlab

我有一个数据集(一个包含 x 和 y 值的数组),我最终想要拟合一个非线性模型。为了增加拟合良好和模型收敛的机会,我想提供尽可能接近解决方案的初始参数。我要拟合的模型参数之一对应于曲线的拐点。有没有一种方法可以估计 Matlab 中离散数据集(不是连续函数)的拐点?我不想事先进行曲线拟合,因为这是为了加速曲线拟合并增加其成功的可能性。

想法是分两步进行:

  1. 首先定义什么是噪音水平,"simplify"(xy)折线到某个"smooth"子集(xs, ys).简化后,曲线特征的每一个变化都会被认为是显着的。

  2. 寻找折线的凸度变化(xs,ys).

对于第一点,您可以使用 Douglas-Peucker algorithm, implemented here

第二个点是根据折线的3个连续点构造的有符号区域:

      | x0   y0   1 |
    1 |             |
A = - | x1   y1   1 |
    2 |             |
      | x2   y2   1 |

折线是 "convex" - 即正曲率 - 当这些区域为正时,以及 "concave" - 即负曲率 - 当区域为负时。曲率的变化就是拐点所在的地方。

从 File Exchange 下载 dpsimplify 函数后,您可以 运行 以下代码(假设 xy 向量已经存在):

%// Part 1.
[ps,~] = dpsimplify([x(:),y(:)], 1e-3);  %// adjust "tol" above noise level
xs = ps(:,1);
ys = ps(:,2);

%// Part 2
I = 1:numel(xs)-2;
sgnA = sign( ...
    xs(I+0).*ys(I+1) ...
  + xs(I+1).*ys(I+2) ...
  + xs(I+2).*ys(I+0) ...
  - xs(I+0).*ys(I+2) ...
  - xs(I+1).*ys(I+0) ...
  - xs(I+2).*ys(I+1) ...
);
k_inflex = find(2 == abs(diff(sgnA)));
x_inflex = xs(k_inflex);
y_inflex = ys(k_inflex);