I'm using scipy.interpolate.UnivariateSpline
to smoothly interpolate a large amount of data. Works great. I get an object which acts like a function.
Now I want to save the spline points for later and use them in Matlab (and also Python, but that's less urgent), without needing the original data. How can I do this?
In scipy I have no clue; UnivariateSpline does not seem to offer a constructor with the previously-computed knots and coefficients.
In MATLAB, I've tried the Matlab functions spline()
and pchip()
, and while both come close, they have errors near the endpoints that look kind of like Gibbs ears.
Here is a sample set of data that I have, in Matlab format:
splinedata = struct('coeffs',[-0.0412739180955273 -0.0236463479425733 0.42393753107602 -1.27274336116436 0.255711720888164 1.93923263846732 -2.30438927604816 1.02078680231079 0.997156858475075 -2.35321792387215 0.667027554745454 0.777918416623834],...
'knots',[0 0.125 0.1875 0.25 0.375 0.5 0.625 0.75 0.875 0.9999],...
'y',[-0.0412739180955273 -0.191354308450615 -0.869601364377744 -0.141538578624065 0.895258135865578 -1.04292294390242 0.462652465278345 0.442550440125204 -1.03967756446455 0.777918416623834])
The coefficients and knots are the result of calling get_coeffs()
and get_knots()
on the scipy UnivariateSpline. The 'y' values are the values of the UnivariateSpline at the knots, or more precisely:
y = f(f.get_knots())
where f is my UnivariateSpline.
How can I use this data to make a spline that matches the behavior of the UnivariateSpline, without having to use the Curve-Fitting Toolbox? I don't need to do any data fitting in Matlab, I just need to know how to construct a cubic spline from knots/coefficients/spline values.
Interpolation is a technique of constructing data points between given data points. The scipy. interpolate is a module in Python SciPy consisting of classes, spline functions, and univariate and multivariate interpolation classes. Interpolation is done in many ways some of them are : 1-D Interpolation.
The interp1d() function of scipy. interpolate package is used to interpolate a 1-D function. It takes arrays of values such as x and y to approximate some function y = f(x) and then uses interpolation to find the value of new points.
You can do it by using the functions _eval_args()
and _from_tck()
from the class UnivariateSpline
. The first one gives returns the spline parameters, which you can store and later create a similar spline object using the the second one.
Here is an example:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
x = np.linspace(-3, 3, 50)
y = np.exp(-x**2) + 0.1 * np.random.randn(50)
spl1 = UnivariateSpline(x, y, s=.5)
xi = np.linspace(-3, 3, 1000)
tck = spl1._eval_args
spl2 = UnivariateSpline._from_tck(tck)
plt.plot(x, y, 'ro', ms=5, label='data')
plt.plot(xi, spl1(xi), 'b', label='original spline')
plt.plot(xi, spl2(xi), 'y:', lw=4, label='recovered spline')
plt.legend()
plt.show()
In scipy, try scipy.interpolate.splev, which takes
tck: a sequence ... containing the knots, coefficients, and degree of the spline.
Added: the following python class creates spline functions:
init with (knots, coefs, degree),
then use it just like spline functions created by UnivariateSpline( x, y, s )
:
from scipy.interpolate import splev
# http://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.splev.html
class Splinefunc:
""" splinef = Splinefunc( knots, coefs, degree )
...
y = splinef( x ) # __call__
19june untested
"""
def __init__( self, knots, coefs, degree ):
self.knots = knots
self.coefs = coefs
self.degree = degree
def __call__( self, x ):
return splev( x, (self.knots, self.coefs, self.degree ))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With