python - scipy splrep() with weights not fitting the given curve -
using scipy's splrep can fit test sinewave:
import numpy np scipy.interpolate import splrep, splev import matplotlib.pyplot plt plt.style.use("ggplot") # generate test sinewave x = np.arange(0, 20, .1) y = np.sin(x) # interpolate tck = splrep(x, y) x_spl = x + 0.05 # show wors y_spl = splev(x_spl, tck) plt.plot(x_spl, y_spl)
the splrep documentation states default value weight parameter np.ones(len(x))
. however, plotting results in totally different plot:
tck = splrep(x, y, w=np.ones(len(x_spl))) y_spl = splev(x_spl, tck) plt.plot(x_spl, y_spl)
the documentation states smoothing condition s
different when weight array given - when setting s=len(x_spl) - np.sqrt(2*len(x_spl))
(the default value without weight array) result not strictly correspond original curve shown in plot.
what need change in code listed above in order make interpolation weight array (as listed above) output same result interpolation without weights? have tested scipy 0.17.0. gist test ipython notebook
you have change 1 line of code identical output:
tck = splrep(x, y, w=np.ones(len(x_spl)))
should become
tck = splrep(x, y, w=np.ones(len(x_spl)), s=0)
so, difference have specify s
instead of using default one.
when @ source code of splrep
see why necessary:
if w none: w = ones(m, float) if s none: s = 0.0 else: w = atleast_1d(w) if s none: s = m - sqrt(2*m)
which means that, if neither weights nor s
provided, s
set 0 , if provide weights no s
s = m - sqrt(2*m)
m = len(x)
.
so, in example above compare outputs same weights different s
(which 0
, m - sqrt(2*m)
, respectively).
Comments
Post a Comment