细化/最小化三次样条控制点('自动平滑')

时间:2018-01-28 03:56:51

标签: python scipy curve-fitting cubic-spline

简短形式

给定离散[x,y]点的集合,你能得到一个近似于[x,y]点并满足两个约束的连续函数:

  • 满足给定(最大)均方误差。
  • 它最大限度地减少了控制点的数量。

细节

这实际上是一个嵌入式系统问题,但让我解释一下。我需要连接一块可以更好地设计 cough 的模拟硬件。但是 - 像往常一样 - 嵌入式系统工程师有责任纠正硬件中的缺点。

因此,我需要为以下功能制定一个准确的模型: duty cycle vs loop current

蓝点取自实际测量值,红线是点之间的scipy立方插值。

问题在于,由此产生的82个控制点会产生太多数据,无法填充到客户端的微型微控制器中。 (我正在显示总数据集的子集。)

所以我的问题是:如何最小化样条控制点的数量并保持在某个给定的MSE内?

为有动力的

以下是上图中使用的x和y点的集合。

x = [ 3.387,  3.552,  3.714,  3.868,  4.012,  4.15 ,  4.278,  4.407,
      4.529,  4.646,  4.757,  4.852,  4.924,  4.974,  5.012,  5.046,
      5.084,  5.148,  5.267,  5.426,  5.593,  5.75 ,  5.9  ,  6.03 ,
      6.145,  6.26 ,  6.37 ,  6.48 ,  6.6  ,  6.72 ,  6.83 ,  6.945,
      7.055,  7.175,  7.29 ,  7.405,  7.52 ,  7.63 ,  7.75 ,  7.86 ,
      7.98 ,  8.09 ]
y = [ 0.05 ,  0.055,  0.06 ,  0.065,  0.07 ,  0.075,  0.08 ,  0.085,
      0.09 ,  0.095,  0.1  ,  0.105,  0.11 ,  0.115,  0.12 ,  0.125,
      0.13 ,  0.135,  0.14 ,  0.145,  0.15 ,  0.155,  0.16 ,  0.165,
      0.17 ,  0.175,  0.18 ,  0.185,  0.19 ,  0.195,  0.2  ,  0.205,
      0.21 ,  0.215,  0.22 ,  0.225,  0.23 ,  0.235,  0.24 ,  0.245,
      0.25 ,  0.255]

PS

请注意,我并不特别强调三次样条。我愿意接近任何紧凑的表示来近似[x,y]函数,这在微控制器上扩展的计算成本并不高。

2 个答案:

答案 0 :(得分:1)

当我注意到循环电流大于6.0的图形部分看起来是线性的时,我认为一种可能的方法是将数据集分成几部分并单独拟合。这是我尝试这样做的,包括一个高端件,一个低端件和两个中间件。单精度应该没问题,客户端硬件已经可以为样条线执行数字乘法:

if x > 6.0
    a = -9.7949290874469949E-02
    b =  4.3620505659335194E-02
    y = a + bx
else if x < 4.5:
    a =  2.0780250294624176E-02
    b = -1.1030255807503962E-02
    c =  5.8098518234878981E-03
    y = a + bx + cx^2
else if x < 5.2:
    a =  1.9299476875427801E+00
    b = -8.2789734912004187E-01
    c =  9.3133373338805447E-02
    y = a + bx + cx^2
else:
    a =  5.2371635939198503E-02
    b =  3.4449759555560976E-03
    c =  2.5067846229176044E-03
    y = a + bx + cx^2

答案 1 :(得分:0)

我认为三次样条可能是最能回答你问题的方法但是我也认为这个问题&#34;你可以得到一个连续的函数&#34;你真正想做的事情并不完全一样。

关于如何最好地削减数据点,我认为这需要一些系统知识,例如环路电流和占空比的预期分辨率。从图表中,您可以使用所有其他甚至每三个点并获得良好的结果。

但正如@JamesPhillips建议的那样,看起来您也可以找到响应的分段线性或立方区域。如果这足够了,那么您可以记录子曲线的区域边界和斜率/截距/二次曲线,您可能可以将其放入微控制器存储器中。