Python 细化/最小化三次样条曲线控制点(“自动平滑”) 缩略形式

Python 细化/最小化三次样条曲线控制点(“自动平滑”) 缩略形式,python,scipy,curve-fitting,cubic-spline,Python,Scipy,Curve Fitting,Cubic Spline,给定一组离散的[x,y]点,您能否导出一个连续函数来逼近[x,y]点并满足两个约束条件: 它满足给定的最大均方误差。 它最大限度地减少了控制点的数量。 ? 细节 这确实是一个嵌入式系统的问题,但让我来解释一下。我需要一个接口的模拟硬件,咳嗽本来可以设计得更好。但是,和往常一样,纠正硬件中的缺陷是嵌入式系统工程师的责任 因此,我需要为以下功能制定准确的模型: 蓝色圆点取自实际测量值,红线为圆点之间的scipy立方插值 问题是,由此产生的82+个控制点产生的数据太多,无法塞进客户机小巧的微控制器中

给定一组离散的[x,y]点,您能否导出一个连续函数来逼近[x,y]点并满足两个约束条件:

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

细节 这确实是一个嵌入式系统的问题,但让我来解释一下。我需要一个接口的模拟硬件,咳嗽本来可以设计得更好。但是,和往常一样,纠正硬件中的缺陷是嵌入式系统工程师的责任

因此,我需要为以下功能制定准确的模型:

蓝色圆点取自实际测量值,红线为圆点之间的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]
附言
请注意,我并不特别喜欢三次样条曲线。在微控制器上扩展[x,y]函数时,我愿意使用任何简洁的表示法,因为在微控制器上扩展[x,y]函数在计算上并不昂贵。

当我注意到回路电流大于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

我认为三次样条曲线可能是最能回答你问题的方法,但我也认为这个问题,你能导出一个连续函数吗?你真正想做的事情并不完全相同

对于如何最好地精简数据点,我认为这将需要一些系统知识,例如预期的环路电流分辨率和占空比。从图中可以看出,您可能每隔一个点,甚至每三个点使用一次,就可以得到很好的结果


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

我无意中发现了一个很有希望的地方。但是在数学方面,stackexchange看起来更简单,满足了我的需要。这看起来很棒,但有一个问题:你是如何进行拟合的?我猜您手动选择了分区点,并在每个区域上使用标准曲线拟合。真的吗?我把高端作为一条直线,然后手动拆分低端,这样低端的部分将尽可能大,并且仍然能够很好地拟合二次方程。每个数据段都通过标准线性回归进行拟合。