or
Почему splprep
не работает с собственными узлами?
Я пытаюсь понять, как завязать узлы в scipy.interpolate.splprep
. В непериодическом случае мне это удается, т.е. я могу воспроизвести этот пример SE.
Однако в случае периодических граничных условий (PBC) у меня есть проблема. Здесь scipy.interpolate.splprep
даже не работает со своими собственными узлами, как показывает этот пример:
import numpy as np
from scipy.interpolate import splev, splrep
import scipy
print "my scipy version: ", scipy.__version__
srate = 192000.
freq = 1200.
timeList = [ i / srate for i in range( int( srate / freq + 1 ) ) ]
signal = np.fromiter( ( np.sin( 2 * np.pi * freq * t ) for t in timeList ), np.float )
spl = splrep( timeList, signal, per=1 )
knots = spl[0]
spl = splrep( timeList, signal, t=knots, per=1 )
дает:
my scipy version: 1.0.0
Traceback (most recent call last):
File "splrevtest.py", line 15, in <module>
spl = splrep( timeList, signal, t=knots, per=1 )
File "/somepath/python2.7/site-packages/scipy-1.0.0-py2.7-linux-/python2.7/site-packages/scipy-1.0.0-py2.7-linux-x86_64.egg/scipy/interpolate/fitpack.py", line 289, in splrep
res = _impl.splrep(x, y, w, xb, xe, k, task, s, t, full_output, per, quiet)
File "/somepath/python2.7/site-packages/scipy-1.0.0-py2.7-linux-x86_64.egg/scipy/interpolate/_fitpack_impl.py", line 514, in splrep
raise _iermess[ier][1](_iermess[ier][0])
ValueError: Error on input data
Более того, если вы построите первый и последний узлы вроде:
print timeList[-1]
print knots[:4]
print knots[-4:]
ты получаешь
>> 0.000833333333333
>> [-1.56250000e-05 -1.04166667e-05 -5.20833333e-06 0.00000000e+00]
>> [0.00083333 0.00083854 0.00084375 0.00084896]
Это означает, что есть шесть точек за пределами фактического диапазона данных, три до и три после. Это, вероятно, нормально, поскольку у нас есть PBC, и узлы идентичны узлам внутри модуля диапазона данных периода, но в любом случае странно. (Кстати, пример не работает даже при установке per=0
.) Более того, установка точек вне диапазона данных не работает, если я устанавливаю точки вручную. Он работает даже с per=1
, если точки находятся внутри диапазона данных. Например, например:
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import splev, splrep
import scipy
x = np.linspace( 0, 1, 120 )
timeList = np.linspace( 0, 1, 15 )
signal = np.fromiter( ( np.sin( 2 * np.pi * t +.3 ) for t in timeList ), np.float )
signal[ -1 ] -= .15
myKnots=np.linspace( .05, .95, 8 )
spl = splrep( timeList, signal, t=myKnots, per=1 )
fit = splev(x,spl)
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.plot( timeList, signal, marker='o' )
ax.plot( x, fit , 'r' )
for i in myKnots:
ax.axvline( i )
plt.show()
предоставление:
где также можно увидеть, что последняя точка игнорируется в PBC.
Итак, что на самом деле scipy.interpolate.splprep
здесь делается, и почему он не принимает аналогичную конструкцию узла для узлов, устанавливаемых вручную, если per=1
. Это ошибка?
Я надеюсь, что ответ на последний вопрос - «нет», иначе я бы ошибался, задавая это здесь.
y[m-1]
и т. Д. На самом деле кажется мне логичным. Не удивился, просто добавил в вопрос для полноты. Однако первая часть - как вы говорите - не так интуитивно понятна. 16.08.2018