B-spline interpolation with Python

后端 未结 3 1423
小鲜肉
小鲜肉 2021-01-31 21:41

I am trying to reproduce a Mathematica example for a B-spline with Python.

The code of the mathematica example reads

pts = {{0, 0}, {0, 2}, {2, 3}, {4, 0         


        
3条回答
  •  [愿得一人]
    2021-01-31 22:11

    I believe scipy's fitpack Library is doing something more complicated than what Mathematica is doing. I was confused as to what was going on as well.

    There is the smoothing parameter in these functions, and the default interpolation behavior is to try to make points go through lines. That's what this fitpack software does, so I guess scipy just inherited it? (http://www.netlib.org/fitpack/all -- I'm not sure this is the right fitpack)

    I took some ideas from http://research.microsoft.com/en-us/um/people/ablake/contours/ and coded up your example with the B-splines in there.

    Spline fit

    basis functions

    import numpy
    
    import matplotlib.pyplot as plt
    
    # This is the basis function described in eq 3.6 in http://research.microsoft.com/en-us/um/people/ablake/contours/
    def func(x, offset):
        out = numpy.ndarray((len(x)))
    
        for i, v in enumerate(x):
            s = v - offset
    
            if s >= 0 and s < 1:
                out[i] = s * s / 2.0
            elif s >= 1 and s < 2:
                out[i] = 3.0 / 4.0 - (s - 3.0 / 2.0) * (s - 3.0 / 2.0)
            elif s >= 2 and s < 3:
                out[i] = (s - 3.0) * (s - 3.0) / 2.0
            else:
                out[i] = 0.0
    
        return out
    
    # We have 7 things to fit, so let's do 7 basis functions?
    y = numpy.array([0, 2, 3, 0, 3, 2, 0])
    
    # We need enough x points for all the basis functions... That's why the weird linspace max here
    x = numpy.linspace(0, len(y) + 2, 100)
    
    B = numpy.ndarray((len(x), len(y)))
    
    for k in range(len(y)):
        B[:, k] = func(x, k)
    
    plt.plot(x, B.dot(y))
    # The x values in the next statement are the maximums of each basis function. I'm not sure at all this is right
    plt.plot(numpy.array(range(len(y))) + 1.5, y, '-o')
    plt.legend('B-spline', 'Control points')
    plt.show()
    
    for k in range(len(y)):
        plt.plot(x, B[:, k])
    plt.title('Basis functions')
    plt.show()
    

    Anyway I think other folks have the same problems, have a look at: Behavior of scipy's splrep

提交回复
热议问题