<p>我相信scipy的fitpack库做的事情比Mathematica做的更复杂。我也不知道发生了什么事。</p>
<p>这些函数中有平滑参数,默认的插值行为是尝试使点穿过直线。这就是fitpack软件的功能,所以我想scipy是继承了它?(<a href="http://www.netlib.org/fitpack/all" rel="nofollow noreferrer">http://www.netlib.org/fitpack/all</a>——我不确定这是不是正确的fitpack)</p>
<p>我从<a href="http://research.microsoft.com/en-us/um/people/ablake/contours/" rel="nofollow noreferrer">http://research.microsoft.com/en-us/um/people/ablake/contours/</a>中获得了一些想法,并用其中的B样条对您的示例进行了编码。</p>
<p><img src="https://i.stack.imgur.com/BmEpp.png" alt="Spline fit"/></p>
<p><img src="https://i.stack.imgur.com/MMqOo.png" alt="basis functions"/></p>
<pre><code>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()
</code></pre>
<p>不管怎样,我认为其他人也有同样的问题,看看:
<a href="https://stackoverflow.com/questions/13489925/behavior-of-scipys-splrep">Behavior of scipy's splrep</a></p>