>

MatLab 코드를 Scipy로 이식하려고하는데 scipy.interpolate, interp1d 및 UnivariateSpline . interp1d 결과는 interp1d MatLab 함수와 일치하지만 UnivariateSpline 숫자는 다르게 나타납니다. 경우에 따라 매우 다릅니다.

f = interp1d(row1,row2,kind='cubic',bounds_error=False,fill_value=numpy.max(row2))
return  f(interp)
f = UnivariateSpline(row1,row2,k=3,s=0)
return f(interp)

누군가 통찰력을 제공 할 수 있습니까? 내 xval의 간격이 똑같지는 않지만 왜 중요한지 잘 모르겠습니다.


  • 답변 # 1

    방금 같은 문제가 발생했습니다.

    빠른 답변

    대신 InterpolatedUnivariateSpline을 사용하십시오 :

    f = InterpolatedUnivariateSpline(row1, row2)
    return f(interp)
    
    
    긴 답변

    UnivariateSpline은 '지정된 데이터 포인트 세트에 맞는 1 차원 스무딩 스플라인'이며 InterpolatedUnivariateSpline은 '지정된 데이터 포인트 세트에 대한 1 차원 보간 스플라인'입니다. 전자는 데이터를 평활화하고 후자는보다 일반적인 보간법이며 interp1d에서 예상되는 결과를 재현합니다. 아래 그림은 차이점을 보여줍니다.

    그림을 재현하는 코드는 다음과 같습니다.

    import scipy.interpolate as ip
    #Define independent variable
    sparse = linspace(0, 2 * pi, num = 20)
    dense = linspace(0, 2 * pi, num = 200)
    #Define function and calculate dependent variable
    f = lambda x: sin(x) + 2
    fsparse = f(sparse)
    fdense = f(dense)
    ax = subplot(2, 1, 1)
    #Plot the sparse samples and the true function
    plot(sparse, fsparse, label = 'Sparse samples', linestyle = 'None', marker = 'o')
    plot(dense, fdense, label = 'True function')
    #Plot the different interpolation results
    interpolate = ip.InterpolatedUnivariateSpline(sparse, fsparse)
    plot(dense, interpolate(dense), label = 'InterpolatedUnivariateSpline', linewidth = 2)
    smoothing = ip.UnivariateSpline(sparse, fsparse)
    plot(dense, smoothing(dense), label = 'UnivariateSpline', color = 'k', linewidth = 2)
    ip1d = ip.interp1d(sparse, fsparse, kind = 'cubic')
    plot(dense, ip1d(dense), label = 'interp1d')
    ylim(.9, 3.3)
    legend(loc = 'upper right', frameon = False)
    ylabel('f(x)')
    #Plot the fractional error
    subplot(2, 1, 2, sharex = ax)
    plot(dense, smoothing(dense) / fdense - 1, label = 'UnivariateSpline')
    plot(dense, interpolate(dense) / fdense - 1, label = 'InterpolatedUnivariateSpline')
    plot(dense, ip1d(dense) / fdense - 1, label = 'interp1d')
    ylabel('Fractional error')
    xlabel('x')
    ylim(-.1,.15)
    legend(loc = 'upper left', frameon = False)
    tight_layout()
    
    

  • 답변 # 2

    결과가 다른 (그러나 둘 다 맞을 수있는) 이유는 UnivariateSpline 가 사용하는 보간 루틴이기 때문입니다.  그리고 interp1d  다릅니다.

    interp1d   x 를 사용하여 부드러운 B 스플라인을 만듭니다. -매듭으로 준 포인트

    UnivariateSpline  부드러운 B- 스플라인을 구성하는 FITPACK을 기반으로합니다. 그러나 FITPACK은 데이터를 더 잘 맞추기 위해 스플라인에 대해new매듭 점을 선택하려고합니다 (아마도 chi ^ 2와 곡률에 대한 약간의 페널티 등을 최소화하기 위해). g.get_knots() 를 통해 사용한 매듭 점을 확인할 수 있습니다 .

    따라서 결과가 다른 이유는 보간 알고리즘이 다르기 때문입니다. 데이터 포인트에 매듭이있는 B 스플라인을 원하면 interp1d 를 사용하십시오.  또는 splmake . FITPACK의 기능을 원하면 UnivariateSpline 를 사용하십시오. . 밀도가 높은 데이터의 한계에서 두 방법 모두 동일한 결과를 제공하지만 데이터가 드문 경우 다른 결과를 얻을 수 있습니다.

    (이 모든 것을 어떻게 알 수 있습니까 : 코드를 읽으십시오 :-)

  • 답변 # 3

    나를 위해 일하십시오,

    from scipy import allclose, linspace
    from scipy.interpolate import interp1d, UnivariateSpline
    from numpy.random import normal
    from pylab import plot, show
    n = 2**5
    x = linspace(0,3,n)
    y = (2*x**2 + 3*x + 1) + normal(0.0,2.0,n)
    i = interp1d(x,y,kind=3)
    u = UnivariateSpline(x,y,k=3,s=0)
    m = 2**4
    t = linspace(1,2,m)
    plot(x,y,'r,')
    plot(t,i(t),'b')
    plot(t,u(t),'g')
    print allclose(i(t),u(t)) # evaluates to True
    show()
    
    

    이것은 나에게 준다

  • 답변 # 4

    UnivariateSpline: Amore recent wrapper of the FITPACK routines.

    이것은 약간 다른 값을 설명 할 수 있습니까? (또한 UnivariateSpline이 interp1d보다 훨씬 빠릅니다.)

  • 이전 Visual Studio 2010의 설치 프로젝트에는 NET 40이 필요합니다
  • 다음 트리거에서 WPF 설정 테두리 배경