在 Matlab 中找到离散数据集的拐点
Find the inflection point of a discrete dataset in Matlab
我有一个数据集(一个包含 x 和 y 值的数组),我最终想要拟合一个非线性模型。为了增加拟合良好和模型收敛的机会,我想提供尽可能接近解决方案的初始参数。我要拟合的模型参数之一对应于曲线的拐点。有没有一种方法可以估计 Matlab 中离散数据集(不是连续函数)的拐点?我不想事先进行曲线拟合,因为这是为了加速曲线拟合并增加其成功的可能性。
想法是分两步进行:
首先定义什么是噪音水平,"simplify"(x
,y
)折线到某个"smooth"子集(xs
, ys
).简化后,曲线特征的每一个变化都会被认为是显着的。
寻找折线的凸度变化(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
函数后,您可以 运行 以下代码(假设 x
和 y
向量已经存在):
%// 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);
我有一个数据集(一个包含 x 和 y 值的数组),我最终想要拟合一个非线性模型。为了增加拟合良好和模型收敛的机会,我想提供尽可能接近解决方案的初始参数。我要拟合的模型参数之一对应于曲线的拐点。有没有一种方法可以估计 Matlab 中离散数据集(不是连续函数)的拐点?我不想事先进行曲线拟合,因为这是为了加速曲线拟合并增加其成功的可能性。
想法是分两步进行:
首先定义什么是噪音水平,"simplify"(
x
,y
)折线到某个"smooth"子集(xs
,ys
).简化后,曲线特征的每一个变化都会被认为是显着的。寻找折线的凸度变化(
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
函数后,您可以 运行 以下代码(假设 x
和 y
向量已经存在):
%// 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);