自动和数学地计算曲线的“弯头”

时间:2010-12-17 15:30:24

标签: math curve

曲线的一个示例如下所示。肘部点可能是x = 3或4。 如何自动和数学地计算曲线的弯头?

alt text

4 个答案:

答案 0 :(得分:11)

您可能希望查找具有最大绝对二阶导数的点,对于一组离散点x[i],可以使用中心差异来近似:

secondDerivative[i] = x[i+1] + x[i-1] - 2 * x[i]

如上所述,你真正想要的是具有最大曲率的点,但是二阶导数会这样做,而这个中心差异是二阶导数的良好代理。

答案 1 :(得分:9)

我创建了一个Python package,试图实现Kneedle algorithm

要重新创建上述函数并检测最大曲率点:

x = range(1,21)
y = [0.065, 0.039, 0.030, 0.024, 0.023, 0.022, 0.019, 0.0185, 0.0187,
     0.016, 0.015, 0.016, 0.0135, 0.0130, 0.0125, 0.0120, 0.0117, 0.0115, 0.0112, 0.013]

kn = KneeLocator(
    x,
    y,
    curve='convex',
    direction='decreasing',
    interp_method='interp1d',
)

print(kn.knee)
7
import matplotlib.pyplot as plt
plt.xlabel('x')
plt.ylabel('f(x)')
plt.xticks(range(1,21))
plt.plot(x, y, 'bx-')
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')

enter image description here

<强>更新
Kneed有一个改进的样条拟合方法来处理局部最小值,使用interp_method='polynomial'

kn = KneeLocator(
    x,
    y,
    curve='convex',
    direction='decreasing',
    interp_method='polynomial',
)

print(kn.knee)
4

新剧情:

plt.xlabel('x')
plt.ylabel('f(x)')
plt.xticks(range(1,21))
plt.plot(x, y, 'bx-')
plt.vlines(kn.knee, plt.ylim()[0], plt.ylim()[1], linestyles='dashed')

enter image description here

答案 2 :(得分:3)

像这样的函数通常称为L-curves形状。它们出现在通过正规化解决不适定问题时。

'肘'点是曲线上具有最大绝对二阶导数的点。

答案 3 :(得分:1)

你真正想要的是最大curvature点。当斜率远小于1时,这可以用二阶导数近似(如@ebo指出的那样),但情况并非总是如此。