簡體   English   中英

如何為“scipy.interpolate.make_lsq_spline”制作 select 好的結序列

[英]How to select good knot sequences for "scipy.interpolate.make_lsq_spline"

我想使用scipy.interpolate.make_lsq_spline創建一個平滑二維數據序列的 B 樣條曲線。

x = [0., 0.37427465, 0.68290943, 0.83261929, 1. ]
y = [-1.0, 3.0, 4.0, 2.0, 1.0] 

但是,我不知道如何 select 正確t ,錯誤消息對我來說沒有意義。

In [1]: import numpy as np

In [2]: from scipy.interpolate import make_lsq_spline

In [3]: x = [0., 0.37427465, 0.68290943, 0.83261929, 1. ]

In [4]: y = [-1.0, 3.0, 4.0, 2.0, 1.0]

In [5]: t = [0.,0.,0.,0.,0.25,0.5,0.75,1.,1.,1.,1 ]

In [6]: spl = make_lsq_spline(x, y, t)
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-6-4440a73d26f0> in <cell line: 1>()
----> 1 spl = make_lsq_spline(x, y, t)

/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/scipy/interpolate/_bsplines.py in make_lsq_spline(x, y, t, k, w, axis, check_finite)
   1513
   1514     # have observation matrix & rhs, can solve the LSQ problem
-> 1515     cho_decomp = cholesky_banded(ab, overwrite_ab=True, lower=lower,
   1516                                  check_finite=check_finite)
   1517     c = cho_solve_banded((cho_decomp, lower), rhs, overwrite_b=True,

/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/scipy/linalg/_decomp_cholesky.py in cholesky_banded(ab, overwrite_ab, lower, check_finite)
    280     c, info = pbtrf(ab, lower=lower, overwrite_ab=overwrite_ab)
    281     if info > 0:
--> 282         raise LinAlgError("%d-th leading minor not positive definite" % info)
    283     if info < 0:
    284         raise ValueError('illegal value in %d-th argument of internal pbtrf'

LinAlgError: 5-th leading minor not positive definite

是否有選擇合適的結序列t的指南?

我有一個類似的問題。 由於你的榜樣,我想我可以知道出了什么問題。 從線性代數的角度來看,您要求解決無法唯一解決的問題。 您提供 11 knots t,這意味着有 11-3-1 = 7 個系數要確定,因為您嘗試擬合 k=3 度的樣條曲線(make_lsq_spline 的默認值)。 對 5 個點 x 進行評估,方程系統的左側由 5 x 7 矩陣 D 給出。D 在示例中具有滿秩,但這無濟於事。 7 x 7 矩陣 N = DT@D 僅為半正定矩陣。 兩個特征值為 0。它不能倒置,因此你的問題不能唯一解決。 一種解決方案是擺脫 2 節,比如 0.25 和 0.75 的節。 在使用 3 階樣條曲線時,邊界處的四折結應該保留,因為您很可能希望插值樣條曲線跳到那里。 總而言之,必須以插值問題唯一可解的方式選擇節點。 我還嘗試添加一些代碼來說明我想說的話。 希望有所幫助。

import numpy as np
import scipy.interpolate as sciint
import matplotlib.pyplot as plt

x = [0., 0.37427465, 0.68290943, 0.83261929, 1.]
y = [-1.0, 3.0, 4.0, 2.0, 1.0]
t = [0.,0.,0.,0.,0.25,0.5,0.75,1.,1.,1.,1 ]

splines = []

for k in range(7):
    coeff    = np.zeros(7)
    coeff[k] = 1.
    splines.append(sciint.BSpline(t,coeff,3))

fig,ax = plt.subplots(3,3)
dom    = np.linspace(0.,1.,1000)

for count,axes in enumerate(ax.flat):
    axes.plot(dom,splines[count](dom))
    if count == len(splines)-1:
        break
    
data = []

for spline in splines:
    data.append(np.vstack(spline(x)))
    
D = np.hstack(tuple(data))    
N = D.T @ D

sing = np.linalg.eigvalsh(N)

print(sing)

t2 = [0.,0.,0.,0.,0.5,1.,1.,1.,1 ]

bspline = sciint.make_lsq_spline(x,y,t2)

ax[2,1].plot(x,y,'r')
ax[2,2].plot(dom,bspline(dom),'m')

不是我的問題的直接答案,而是scipy.interpolate.make_smoothing_splinehttps://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.make_smoothing_spline.html#scipy.interpolate.make_smoothing_spline從樣條中引入scipy 1.10.0 可用於我的用例。

In [1]: import numpy as np

In [2]: from scipy.interpolate import make_smoothing_spline

In [3]: import matplotlib.pyplot as plt

In [4]: x = [0., 0.37427465, 0.68290943, 0.83261929, 1. ]

In [5]: y = [-1.0, 3.0, 4.0, 2.0, 1.0]

In [6]: spl = make_smoothing_spline(x, y)

In [7]: plt.plot(x, y, "rx")
Out[7]: [<matplotlib.lines.Line2D at 0x12f101e70>]

In [8]: x_grid = np.linspace(x[0], x[-1], 400)

In [9]: plt.plot(x_grid, spl(x_grid), label='Smoothing Spline')
Out[9]: [<matplotlib.lines.Line2D at 0x12f102830>]

In [10]: plt.legend(loc="best")
Out[10]: <matplotlib.legend.Legend at 0x12473bc40>

In [11]: plt.show()

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM