Static code analysis and corrections
This commit is contained in:
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,463 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_equal, assert_allclose, assert_,
|
||||
assert_almost_equal, assert_array_almost_equal)
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from numpy import array, asarray, pi, sin, cos, arange, dot, ravel, sqrt, round
|
||||
from scipy import interpolate
|
||||
from scipy.interpolate.fitpack import (splrep, splev, bisplrep, bisplev,
|
||||
sproot, splprep, splint, spalde, splder, splantider, insert, dblint)
|
||||
from scipy.interpolate.dfitpack import regrid_smth
|
||||
|
||||
|
||||
def data_file(basename):
|
||||
return os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||
'data', basename)
|
||||
|
||||
|
||||
def norm2(x):
|
||||
return sqrt(dot(x.T,x))
|
||||
|
||||
|
||||
def f1(x,d=0):
|
||||
if d is None:
|
||||
return "sin"
|
||||
if x is None:
|
||||
return "sin(x)"
|
||||
if d % 4 == 0:
|
||||
return sin(x)
|
||||
if d % 4 == 1:
|
||||
return cos(x)
|
||||
if d % 4 == 2:
|
||||
return -sin(x)
|
||||
if d % 4 == 3:
|
||||
return -cos(x)
|
||||
|
||||
|
||||
def f2(x,y=0,dx=0,dy=0):
|
||||
if x is None:
|
||||
return "sin(x+y)"
|
||||
d = dx+dy
|
||||
if d % 4 == 0:
|
||||
return sin(x+y)
|
||||
if d % 4 == 1:
|
||||
return cos(x+y)
|
||||
if d % 4 == 2:
|
||||
return -sin(x+y)
|
||||
if d % 4 == 3:
|
||||
return -cos(x+y)
|
||||
|
||||
|
||||
def makepairs(x, y):
|
||||
"""Helper function to create an array of pairs of x and y."""
|
||||
# Or itertools.product (>= python 2.6)
|
||||
xy = array([[a, b] for a in asarray(x) for b in asarray(y)])
|
||||
return xy.T
|
||||
|
||||
|
||||
def put(*a):
|
||||
"""Produce some output if file run directly"""
|
||||
import sys
|
||||
if hasattr(sys.modules['__main__'], '__put_prints'):
|
||||
sys.stderr.write("".join(map(str, a)) + "\n")
|
||||
|
||||
|
||||
class TestSmokeTests(object):
|
||||
"""
|
||||
Smoke tests (with a few asserts) for fitpack routines -- mostly
|
||||
check that they are runnable
|
||||
"""
|
||||
|
||||
def check_1(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,at=0,xb=None,xe=None):
|
||||
if xb is None:
|
||||
xb = a
|
||||
if xe is None:
|
||||
xe = b
|
||||
x = a+(b-a)*arange(N+1,dtype=float)/float(N) # nodes
|
||||
x1 = a+(b-a)*arange(1,N,dtype=float)/float(N-1) # middle points of the nodes
|
||||
v,v1 = f(x),f(x1)
|
||||
nk = []
|
||||
|
||||
def err_est(k, d):
|
||||
# Assume f has all derivatives < 1
|
||||
h = 1.0/float(N)
|
||||
tol = 5 * h**(.75*(k-d))
|
||||
if s > 0:
|
||||
tol += 1e5*s
|
||||
return tol
|
||||
|
||||
for k in range(1,6):
|
||||
tck = splrep(x,v,s=s,per=per,k=k,xe=xe)
|
||||
if at:
|
||||
t = tck[0][k:-k]
|
||||
else:
|
||||
t = x1
|
||||
nd = []
|
||||
for d in range(k+1):
|
||||
tol = err_est(k, d)
|
||||
err = norm2(f(t,d)-splev(t,tck,d)) / norm2(f(t,d))
|
||||
assert_(err < tol, (k, d, err, tol))
|
||||
nd.append((err, tol))
|
||||
nk.append(nd)
|
||||
put("\nf = %s s=S_k(x;t,c) x in [%s, %s] > [%s, %s]" % (f(None),
|
||||
repr(round(xb,3)),repr(round(xe,3)),
|
||||
repr(round(a,3)),repr(round(b,3))))
|
||||
if at:
|
||||
str = "at knots"
|
||||
else:
|
||||
str = "at the middle of nodes"
|
||||
put(" per=%d s=%s Evaluation %s" % (per,repr(s),str))
|
||||
put(" k : |f-s|^2 |f'-s'| |f''-.. |f'''-. |f''''- |f'''''")
|
||||
k = 1
|
||||
for l in nk:
|
||||
put(' %d : ' % k)
|
||||
for r in l:
|
||||
put(' %.1e %.1e' % r)
|
||||
put('\n')
|
||||
k = k+1
|
||||
|
||||
def check_2(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,xb=None,xe=None,
|
||||
ia=0,ib=2*pi,dx=0.2*pi):
|
||||
if xb is None:
|
||||
xb = a
|
||||
if xe is None:
|
||||
xe = b
|
||||
x = a+(b-a)*arange(N+1,dtype=float)/float(N) # nodes
|
||||
v = f(x)
|
||||
|
||||
def err_est(k, d):
|
||||
# Assume f has all derivatives < 1
|
||||
h = 1.0/float(N)
|
||||
tol = 5 * h**(.75*(k-d))
|
||||
if s > 0:
|
||||
tol += 1e5*s
|
||||
return tol
|
||||
|
||||
nk = []
|
||||
for k in range(1,6):
|
||||
tck = splrep(x,v,s=s,per=per,k=k,xe=xe)
|
||||
nk.append([splint(ia,ib,tck),spalde(dx,tck)])
|
||||
put("\nf = %s s=S_k(x;t,c) x in [%s, %s] > [%s, %s]" % (f(None),
|
||||
repr(round(xb,3)),repr(round(xe,3)),
|
||||
repr(round(a,3)),repr(round(b,3))))
|
||||
put(" per=%d s=%s N=%d [a, b] = [%s, %s] dx=%s" % (per,repr(s),N,repr(round(ia,3)),repr(round(ib,3)),repr(round(dx,3))))
|
||||
put(" k : int(s,[a,b]) Int.Error Rel. error of s^(d)(dx) d = 0, .., k")
|
||||
k = 1
|
||||
for r in nk:
|
||||
if r[0] < 0:
|
||||
sr = '-'
|
||||
else:
|
||||
sr = ' '
|
||||
put(" %d %s%.8f %.1e " % (k,sr,abs(r[0]),
|
||||
abs(r[0]-(f(ib,-1)-f(ia,-1)))))
|
||||
d = 0
|
||||
for dr in r[1]:
|
||||
err = abs(1-dr/f(dx,d))
|
||||
tol = err_est(k, d)
|
||||
assert_(err < tol, (k, d))
|
||||
put(" %.1e %.1e" % (err, tol))
|
||||
d = d+1
|
||||
put("\n")
|
||||
k = k+1
|
||||
|
||||
def check_3(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,xb=None,xe=None,
|
||||
ia=0,ib=2*pi,dx=0.2*pi):
|
||||
if xb is None:
|
||||
xb = a
|
||||
if xe is None:
|
||||
xe = b
|
||||
x = a+(b-a)*arange(N+1,dtype=float)/float(N) # nodes
|
||||
v = f(x)
|
||||
put(" k : Roots of s(x) approx %s x in [%s,%s]:" %
|
||||
(f(None),repr(round(a,3)),repr(round(b,3))))
|
||||
for k in range(1,6):
|
||||
tck = splrep(x, v, s=s, per=per, k=k, xe=xe)
|
||||
if k == 3:
|
||||
roots = sproot(tck)
|
||||
assert_allclose(splev(roots, tck), 0, atol=1e-10, rtol=1e-10)
|
||||
assert_allclose(roots, pi*array([1, 2, 3, 4]), rtol=1e-3)
|
||||
put(' %d : %s' % (k, repr(roots.tolist())))
|
||||
else:
|
||||
assert_raises(ValueError, sproot, tck)
|
||||
|
||||
def check_4(self,f=f1,per=0,s=0,a=0,b=2*pi,N=20,xb=None,xe=None,
|
||||
ia=0,ib=2*pi,dx=0.2*pi):
|
||||
if xb is None:
|
||||
xb = a
|
||||
if xe is None:
|
||||
xe = b
|
||||
x = a+(b-a)*arange(N+1,dtype=float)/float(N) # nodes
|
||||
x1 = a + (b-a)*arange(1,N,dtype=float)/float(N-1) # middle points of the nodes
|
||||
v,v1 = f(x),f(x1)
|
||||
put(" u = %s N = %d" % (repr(round(dx,3)),N))
|
||||
put(" k : [x(u), %s(x(u))] Error of splprep Error of splrep " % (f(0,None)))
|
||||
for k in range(1,6):
|
||||
tckp,u = splprep([x,v],s=s,per=per,k=k,nest=-1)
|
||||
tck = splrep(x,v,s=s,per=per,k=k)
|
||||
uv = splev(dx,tckp)
|
||||
err1 = abs(uv[1]-f(uv[0]))
|
||||
err2 = abs(splev(uv[0],tck)-f(uv[0]))
|
||||
assert_(err1 < 1e-2)
|
||||
assert_(err2 < 1e-2)
|
||||
put(" %d : %s %.1e %.1e" %
|
||||
(k,repr([round(z,3) for z in uv]),
|
||||
err1,
|
||||
err2))
|
||||
put("Derivatives of parametric cubic spline at u (first function):")
|
||||
k = 3
|
||||
tckp,u = splprep([x,v],s=s,per=per,k=k,nest=-1)
|
||||
for d in range(1,k+1):
|
||||
uv = splev(dx,tckp,d)
|
||||
put(" %s " % (repr(uv[0])))
|
||||
|
||||
def check_5(self,f=f2,kx=3,ky=3,xb=0,xe=2*pi,yb=0,ye=2*pi,Nx=20,Ny=20,s=0):
|
||||
x = xb+(xe-xb)*arange(Nx+1,dtype=float)/float(Nx)
|
||||
y = yb+(ye-yb)*arange(Ny+1,dtype=float)/float(Ny)
|
||||
xy = makepairs(x,y)
|
||||
tck = bisplrep(xy[0],xy[1],f(xy[0],xy[1]),s=s,kx=kx,ky=ky)
|
||||
tt = [tck[0][kx:-kx],tck[1][ky:-ky]]
|
||||
t2 = makepairs(tt[0],tt[1])
|
||||
v1 = bisplev(tt[0],tt[1],tck)
|
||||
v2 = f2(t2[0],t2[1])
|
||||
v2.shape = len(tt[0]),len(tt[1])
|
||||
err = norm2(ravel(v1-v2))
|
||||
assert_(err < 1e-2, err)
|
||||
put(err)
|
||||
|
||||
def test_smoke_splrep_splev(self):
|
||||
put("***************** splrep/splev")
|
||||
self.check_1(s=1e-6)
|
||||
self.check_1()
|
||||
self.check_1(at=1)
|
||||
self.check_1(per=1)
|
||||
self.check_1(per=1,at=1)
|
||||
self.check_1(b=1.5*pi)
|
||||
self.check_1(b=1.5*pi,xe=2*pi,per=1,s=1e-1)
|
||||
|
||||
def test_smoke_splint_spalde(self):
|
||||
put("***************** splint/spalde")
|
||||
self.check_2()
|
||||
self.check_2(per=1)
|
||||
self.check_2(ia=0.2*pi,ib=pi)
|
||||
self.check_2(ia=0.2*pi,ib=pi,N=50)
|
||||
|
||||
def test_smoke_sproot(self):
|
||||
put("***************** sproot")
|
||||
self.check_3(a=0.1,b=15)
|
||||
|
||||
def test_smoke_splprep_splrep_splev(self):
|
||||
put("***************** splprep/splrep/splev")
|
||||
self.check_4()
|
||||
self.check_4(N=50)
|
||||
|
||||
def test_smoke_bisplrep_bisplev(self):
|
||||
put("***************** bisplev")
|
||||
self.check_5()
|
||||
|
||||
|
||||
class TestSplev(object):
|
||||
def test_1d_shape(self):
|
||||
x = [1,2,3,4,5]
|
||||
y = [4,5,6,7,8]
|
||||
tck = splrep(x, y)
|
||||
z = splev([1], tck)
|
||||
assert_equal(z.shape, (1,))
|
||||
z = splev(1, tck)
|
||||
assert_equal(z.shape, ())
|
||||
|
||||
def test_2d_shape(self):
|
||||
x = [1, 2, 3, 4, 5]
|
||||
y = [4, 5, 6, 7, 8]
|
||||
tck = splrep(x, y)
|
||||
t = np.array([[1.0, 1.5, 2.0, 2.5],
|
||||
[3.0, 3.5, 4.0, 4.5]])
|
||||
z = splev(t, tck)
|
||||
z0 = splev(t[0], tck)
|
||||
z1 = splev(t[1], tck)
|
||||
assert_equal(z, np.row_stack((z0, z1)))
|
||||
|
||||
def test_extrapolation_modes(self):
|
||||
# test extrapolation modes
|
||||
# * if ext=0, return the extrapolated value.
|
||||
# * if ext=1, return 0
|
||||
# * if ext=2, raise a ValueError
|
||||
# * if ext=3, return the boundary value.
|
||||
x = [1,2,3]
|
||||
y = [0,2,4]
|
||||
tck = splrep(x, y, k=1)
|
||||
|
||||
rstl = [[-2, 6], [0, 0], None, [0, 4]]
|
||||
for ext in (0, 1, 3):
|
||||
assert_array_almost_equal(splev([0, 4], tck, ext=ext), rstl[ext])
|
||||
|
||||
assert_raises(ValueError, splev, [0, 4], tck, ext=2)
|
||||
|
||||
|
||||
class TestSplder(object):
|
||||
def setup_method(self):
|
||||
# non-uniform grid, just to make it sure
|
||||
x = np.linspace(0, 1, 100)**3
|
||||
y = np.sin(20 * x)
|
||||
self.spl = splrep(x, y)
|
||||
|
||||
# double check that knots are non-uniform
|
||||
assert_(np.diff(self.spl[0]).ptp() > 0)
|
||||
|
||||
def test_inverse(self):
|
||||
# Check that antiderivative + derivative is identity.
|
||||
for n in range(5):
|
||||
spl2 = splantider(self.spl, n)
|
||||
spl3 = splder(spl2, n)
|
||||
assert_allclose(self.spl[0], spl3[0])
|
||||
assert_allclose(self.spl[1], spl3[1])
|
||||
assert_equal(self.spl[2], spl3[2])
|
||||
|
||||
def test_splder_vs_splev(self):
|
||||
# Check derivative vs. FITPACK
|
||||
|
||||
for n in range(3+1):
|
||||
# Also extrapolation!
|
||||
xx = np.linspace(-1, 2, 2000)
|
||||
if n == 3:
|
||||
# ... except that FITPACK extrapolates strangely for
|
||||
# order 0, so let's not check that.
|
||||
xx = xx[(xx >= 0) & (xx <= 1)]
|
||||
|
||||
dy = splev(xx, self.spl, n)
|
||||
spl2 = splder(self.spl, n)
|
||||
dy2 = splev(xx, spl2)
|
||||
if n == 1:
|
||||
assert_allclose(dy, dy2, rtol=2e-6)
|
||||
else:
|
||||
assert_allclose(dy, dy2)
|
||||
|
||||
def test_splantider_vs_splint(self):
|
||||
# Check antiderivative vs. FITPACK
|
||||
spl2 = splantider(self.spl)
|
||||
|
||||
# no extrapolation, splint assumes function is zero outside
|
||||
# range
|
||||
xx = np.linspace(0, 1, 20)
|
||||
|
||||
for x1 in xx:
|
||||
for x2 in xx:
|
||||
y1 = splint(x1, x2, self.spl)
|
||||
y2 = splev(x2, spl2) - splev(x1, spl2)
|
||||
assert_allclose(y1, y2)
|
||||
|
||||
def test_order0_diff(self):
|
||||
assert_raises(ValueError, splder, self.spl, 4)
|
||||
|
||||
def test_kink(self):
|
||||
# Should refuse to differentiate splines with kinks
|
||||
|
||||
spl2 = insert(0.5, self.spl, m=2)
|
||||
splder(spl2, 2) # Should work
|
||||
assert_raises(ValueError, splder, spl2, 3)
|
||||
|
||||
spl2 = insert(0.5, self.spl, m=3)
|
||||
splder(spl2, 1) # Should work
|
||||
assert_raises(ValueError, splder, spl2, 2)
|
||||
|
||||
spl2 = insert(0.5, self.spl, m=4)
|
||||
assert_raises(ValueError, splder, spl2, 1)
|
||||
|
||||
def test_multidim(self):
|
||||
# c can have trailing dims
|
||||
for n in range(3):
|
||||
t, c, k = self.spl
|
||||
c2 = np.c_[c, c, c]
|
||||
c2 = np.dstack((c2, c2))
|
||||
|
||||
spl2 = splantider((t, c2, k), n)
|
||||
spl3 = splder(spl2, n)
|
||||
|
||||
assert_allclose(t, spl3[0])
|
||||
assert_allclose(c2, spl3[1])
|
||||
assert_equal(k, spl3[2])
|
||||
|
||||
|
||||
class TestBisplrep(object):
|
||||
def test_overflow(self):
|
||||
a = np.linspace(0, 1, 620)
|
||||
b = np.linspace(0, 1, 620)
|
||||
x, y = np.meshgrid(a, b)
|
||||
z = np.random.rand(*x.shape)
|
||||
assert_raises(OverflowError, bisplrep, x.ravel(), y.ravel(), z.ravel(), s=0)
|
||||
|
||||
def test_regression_1310(self):
|
||||
# Regression test for gh-1310
|
||||
data = np.load(data_file('bug-1310.npz'))['data']
|
||||
|
||||
# Shouldn't crash -- the input data triggers work array sizes
|
||||
# that caused previously some data to not be aligned on
|
||||
# sizeof(double) boundaries in memory, which made the Fortran
|
||||
# code to crash when compiled with -O3
|
||||
bisplrep(data[:,0], data[:,1], data[:,2], kx=3, ky=3, s=0,
|
||||
full_output=True)
|
||||
|
||||
|
||||
def test_dblint():
|
||||
# Basic test to see it runs and gives the correct result on a trivial
|
||||
# problem. Note that `dblint` is not exposed in the interpolate namespace.
|
||||
x = np.linspace(0, 1)
|
||||
y = np.linspace(0, 1)
|
||||
xx, yy = np.meshgrid(x, y)
|
||||
rect = interpolate.RectBivariateSpline(x, y, 4 * xx * yy)
|
||||
tck = list(rect.tck)
|
||||
tck.extend(rect.degrees)
|
||||
|
||||
assert_almost_equal(dblint(0, 1, 0, 1, tck), 1)
|
||||
assert_almost_equal(dblint(0, 0.5, 0, 1, tck), 0.25)
|
||||
assert_almost_equal(dblint(0.5, 1, 0, 1, tck), 0.75)
|
||||
assert_almost_equal(dblint(-100, 100, -100, 100, tck), 1)
|
||||
|
||||
|
||||
def test_splev_der_k():
|
||||
# regression test for gh-2188: splev(x, tck, der=k) gives garbage or crashes
|
||||
# for x outside of knot range
|
||||
|
||||
# test case from gh-2188
|
||||
tck = (np.array([0., 0., 2.5, 2.5]),
|
||||
np.array([-1.56679978, 2.43995873, 0., 0.]),
|
||||
1)
|
||||
t, c, k = tck
|
||||
x = np.array([-3, 0, 2.5, 3])
|
||||
|
||||
# an explicit form of the linear spline
|
||||
assert_allclose(splev(x, tck), c[0] + (c[1] - c[0]) * x/t[2])
|
||||
assert_allclose(splev(x, tck, 1), (c[1]-c[0]) / t[2])
|
||||
|
||||
# now check a random spline vs splder
|
||||
np.random.seed(1234)
|
||||
x = np.sort(np.random.random(30))
|
||||
y = np.random.random(30)
|
||||
t, c, k = splrep(x, y)
|
||||
|
||||
x = [t[0] - 1., t[-1] + 1.]
|
||||
tck2 = splder((t, c, k), k)
|
||||
assert_allclose(splev(x, (t, c, k), k), splev(x, tck2))
|
||||
|
||||
|
||||
def test_bisplev_integer_overflow():
|
||||
np.random.seed(1)
|
||||
|
||||
x = np.linspace(0, 1, 11)
|
||||
y = x
|
||||
z = np.random.randn(11, 11).ravel()
|
||||
kx = 1
|
||||
ky = 1
|
||||
|
||||
nx, tx, ny, ty, c, fp, ier = regrid_smth(
|
||||
x, y, z, None, None, None, None, kx=kx, ky=ky, s=0.0)
|
||||
tck = (tx[:nx], ty[:ny], c[:(nx - kx - 1) * (ny - ky - 1)], kx, ky)
|
||||
|
||||
xp = np.zeros([2621440])
|
||||
yp = np.zeros([2621440])
|
||||
|
||||
assert_raises((RuntimeError, MemoryError), bisplev, xp, yp, tck)
|
||||
|
||||
@@ -0,0 +1,511 @@
|
||||
# Created by Pearu Peterson, June 2003
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_equal, assert_almost_equal, assert_array_equal,
|
||||
assert_array_almost_equal, assert_allclose)
|
||||
from scipy._lib._numpy_compat import suppress_warnings
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from numpy import array, diff, linspace, meshgrid, ones, pi, shape
|
||||
from scipy.interpolate.fitpack import bisplrep, bisplev
|
||||
from scipy.interpolate.fitpack2 import (UnivariateSpline,
|
||||
LSQUnivariateSpline, InterpolatedUnivariateSpline,
|
||||
LSQBivariateSpline, SmoothBivariateSpline, RectBivariateSpline,
|
||||
LSQSphereBivariateSpline, SmoothSphereBivariateSpline,
|
||||
RectSphereBivariateSpline)
|
||||
|
||||
|
||||
class TestUnivariateSpline(object):
|
||||
def test_linear_constant(self):
|
||||
x = [1,2,3]
|
||||
y = [3,3,3]
|
||||
lut = UnivariateSpline(x,y,k=1)
|
||||
assert_array_almost_equal(lut.get_knots(),[1,3])
|
||||
assert_array_almost_equal(lut.get_coeffs(),[3,3])
|
||||
assert_almost_equal(lut.get_residual(),0.0)
|
||||
assert_array_almost_equal(lut([1,1.5,2]),[3,3,3])
|
||||
|
||||
def test_preserve_shape(self):
|
||||
x = [1, 2, 3]
|
||||
y = [0, 2, 4]
|
||||
lut = UnivariateSpline(x, y, k=1)
|
||||
arg = 2
|
||||
assert_equal(shape(arg), shape(lut(arg)))
|
||||
assert_equal(shape(arg), shape(lut(arg, nu=1)))
|
||||
arg = [1.5, 2, 2.5]
|
||||
assert_equal(shape(arg), shape(lut(arg)))
|
||||
assert_equal(shape(arg), shape(lut(arg, nu=1)))
|
||||
|
||||
def test_linear_1d(self):
|
||||
x = [1,2,3]
|
||||
y = [0,2,4]
|
||||
lut = UnivariateSpline(x,y,k=1)
|
||||
assert_array_almost_equal(lut.get_knots(),[1,3])
|
||||
assert_array_almost_equal(lut.get_coeffs(),[0,4])
|
||||
assert_almost_equal(lut.get_residual(),0.0)
|
||||
assert_array_almost_equal(lut([1,1.5,2]),[0,1,2])
|
||||
|
||||
def test_subclassing(self):
|
||||
# See #731
|
||||
|
||||
class ZeroSpline(UnivariateSpline):
|
||||
def __call__(self, x):
|
||||
return 0*array(x)
|
||||
|
||||
sp = ZeroSpline([1,2,3,4,5], [3,2,3,2,3], k=2)
|
||||
assert_array_equal(sp([1.5, 2.5]), [0., 0.])
|
||||
|
||||
def test_empty_input(self):
|
||||
# Test whether empty input returns an empty output. Ticket 1014
|
||||
x = [1,3,5,7,9]
|
||||
y = [0,4,9,12,21]
|
||||
spl = UnivariateSpline(x, y, k=3)
|
||||
assert_array_equal(spl([]), array([]))
|
||||
|
||||
def test_resize_regression(self):
|
||||
"""Regression test for #1375."""
|
||||
x = [-1., -0.65016502, -0.58856235, -0.26903553, -0.17370892,
|
||||
-0.10011001, 0., 0.10011001, 0.17370892, 0.26903553, 0.58856235,
|
||||
0.65016502, 1.]
|
||||
y = [1.,0.62928599, 0.5797223, 0.39965815, 0.36322694, 0.3508061,
|
||||
0.35214793, 0.3508061, 0.36322694, 0.39965815, 0.5797223,
|
||||
0.62928599, 1.]
|
||||
w = [1.00000000e+12, 6.88875973e+02, 4.89314737e+02, 4.26864807e+02,
|
||||
6.07746770e+02, 4.51341444e+02, 3.17480210e+02, 4.51341444e+02,
|
||||
6.07746770e+02, 4.26864807e+02, 4.89314737e+02, 6.88875973e+02,
|
||||
1.00000000e+12]
|
||||
spl = UnivariateSpline(x=x, y=y, w=w, s=None)
|
||||
desired = array([0.35100374, 0.51715855, 0.87789547, 0.98719344])
|
||||
assert_allclose(spl([0.1, 0.5, 0.9, 0.99]), desired, atol=5e-4)
|
||||
|
||||
def test_out_of_range_regression(self):
|
||||
# Test different extrapolation modes. See ticket 3557
|
||||
x = np.arange(5, dtype=float)
|
||||
y = x**3
|
||||
|
||||
xp = linspace(-8, 13, 100)
|
||||
xp_zeros = xp.copy()
|
||||
xp_zeros[np.logical_or(xp_zeros < 0., xp_zeros > 4.)] = 0
|
||||
xp_clip = xp.copy()
|
||||
xp_clip[xp_clip < x[0]] = x[0]
|
||||
xp_clip[xp_clip > x[-1]] = x[-1]
|
||||
|
||||
for cls in [UnivariateSpline, InterpolatedUnivariateSpline]:
|
||||
spl = cls(x=x, y=y)
|
||||
for ext in [0, 'extrapolate']:
|
||||
assert_allclose(spl(xp, ext=ext), xp**3, atol=1e-16)
|
||||
assert_allclose(cls(x, y, ext=ext)(xp), xp**3, atol=1e-16)
|
||||
for ext in [1, 'zeros']:
|
||||
assert_allclose(spl(xp, ext=ext), xp_zeros**3, atol=1e-16)
|
||||
assert_allclose(cls(x, y, ext=ext)(xp), xp_zeros**3, atol=1e-16)
|
||||
for ext in [2, 'raise']:
|
||||
assert_raises(ValueError, spl, xp, **dict(ext=ext))
|
||||
for ext in [3, 'const']:
|
||||
assert_allclose(spl(xp, ext=ext), xp_clip**3, atol=1e-16)
|
||||
assert_allclose(cls(x, y, ext=ext)(xp), xp_clip**3, atol=1e-16)
|
||||
|
||||
# also test LSQUnivariateSpline [which needs explicit knots]
|
||||
t = spl.get_knots()[3:4] # interior knots w/ default k=3
|
||||
spl = LSQUnivariateSpline(x, y, t)
|
||||
assert_allclose(spl(xp, ext=0), xp**3, atol=1e-16)
|
||||
assert_allclose(spl(xp, ext=1), xp_zeros**3, atol=1e-16)
|
||||
assert_raises(ValueError, spl, xp, **dict(ext=2))
|
||||
assert_allclose(spl(xp, ext=3), xp_clip**3, atol=1e-16)
|
||||
|
||||
# also make sure that unknown values for `ext` are caught early
|
||||
for ext in [-1, 'unknown']:
|
||||
spl = UnivariateSpline(x, y)
|
||||
assert_raises(ValueError, spl, xp, **dict(ext=ext))
|
||||
assert_raises(ValueError, UnivariateSpline,
|
||||
**dict(x=x, y=y, ext=ext))
|
||||
|
||||
def test_lsq_fpchec(self):
|
||||
xs = np.arange(100) * 1.
|
||||
ys = np.arange(100) * 1.
|
||||
knots = np.linspace(0, 99, 10)
|
||||
bbox = (-1, 101)
|
||||
assert_raises(ValueError, LSQUnivariateSpline, xs, ys, knots,
|
||||
bbox=bbox)
|
||||
|
||||
def test_derivative_and_antiderivative(self):
|
||||
# Thin wrappers to splder/splantider, so light smoke test only.
|
||||
x = np.linspace(0, 1, 70)**3
|
||||
y = np.cos(x)
|
||||
|
||||
spl = UnivariateSpline(x, y, s=0)
|
||||
spl2 = spl.antiderivative(2).derivative(2)
|
||||
assert_allclose(spl(0.3), spl2(0.3))
|
||||
|
||||
spl2 = spl.antiderivative(1)
|
||||
assert_allclose(spl2(0.6) - spl2(0.2),
|
||||
spl.integral(0.2, 0.6))
|
||||
|
||||
def test_nan(self):
|
||||
# bail out early if the input data contains nans
|
||||
x = np.arange(10, dtype=float)
|
||||
y = x**3
|
||||
w = np.ones_like(x)
|
||||
# also test LSQUnivariateSpline [which needs explicit knots]
|
||||
spl = UnivariateSpline(x, y, check_finite=True)
|
||||
t = spl.get_knots()[3:4] # interior knots w/ default k=3
|
||||
y_end = y[-1]
|
||||
for z in [np.nan, np.inf, -np.inf]:
|
||||
y[-1] = z
|
||||
assert_raises(ValueError, UnivariateSpline,
|
||||
**dict(x=x, y=y, check_finite=True))
|
||||
assert_raises(ValueError, InterpolatedUnivariateSpline,
|
||||
**dict(x=x, y=y, check_finite=True))
|
||||
assert_raises(ValueError, LSQUnivariateSpline,
|
||||
**dict(x=x, y=y, t=t, check_finite=True))
|
||||
y[-1] = y_end # check valid y but invalid w
|
||||
w[-1] = z
|
||||
assert_raises(ValueError, UnivariateSpline,
|
||||
**dict(x=x, y=y, w=w, check_finite=True))
|
||||
assert_raises(ValueError, InterpolatedUnivariateSpline,
|
||||
**dict(x=x, y=y, w=w, check_finite=True))
|
||||
assert_raises(ValueError, LSQUnivariateSpline,
|
||||
**dict(x=x, y=y, t=t, w=w, check_finite=True))
|
||||
|
||||
def test_increasing_x(self):
|
||||
xx = np.arange(10, dtype=float)
|
||||
yy = xx**3
|
||||
x = np.arange(10, dtype=float)
|
||||
x[1] = x[0]
|
||||
y = x**3
|
||||
w = np.ones_like(x)
|
||||
# also test LSQUnivariateSpline [which needs explicit knots]
|
||||
spl = UnivariateSpline(xx, yy, check_finite=True)
|
||||
t = spl.get_knots()[3:4] # interior knots w/ default k=3
|
||||
assert_raises(ValueError, UnivariateSpline,
|
||||
**dict(x=x, y=y, check_finite=True))
|
||||
assert_raises(ValueError, InterpolatedUnivariateSpline,
|
||||
**dict(x=x, y=y, check_finite=True))
|
||||
assert_raises(ValueError, LSQUnivariateSpline,
|
||||
**dict(x=x, y=y, t=t, w=w, check_finite=True))
|
||||
|
||||
|
||||
class TestLSQBivariateSpline(object):
|
||||
# NOTE: The systems in this test class are rank-deficient
|
||||
def test_linear_constant(self):
|
||||
x = [1,1,1,2,2,2,3,3,3]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = [3,3,3,3,3,3,3,3,3]
|
||||
s = 0.1
|
||||
tx = [1+s,3-s]
|
||||
ty = [1+s,3-s]
|
||||
with suppress_warnings() as sup:
|
||||
r = sup.record(UserWarning, "\nThe coefficients of the spline")
|
||||
lut = LSQBivariateSpline(x,y,z,tx,ty,kx=1,ky=1)
|
||||
assert_equal(len(r), 1)
|
||||
|
||||
assert_almost_equal(lut(2,2), 3.)
|
||||
|
||||
def test_bilinearity(self):
|
||||
x = [1,1,1,2,2,2,3,3,3]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = [0,7,8,3,4,7,1,3,4]
|
||||
s = 0.1
|
||||
tx = [1+s,3-s]
|
||||
ty = [1+s,3-s]
|
||||
with suppress_warnings() as sup:
|
||||
# This seems to fail (ier=1, see ticket 1642).
|
||||
sup.filter(UserWarning, "\nThe coefficients of the spline")
|
||||
lut = LSQBivariateSpline(x,y,z,tx,ty,kx=1,ky=1)
|
||||
|
||||
tx, ty = lut.get_knots()
|
||||
for xa, xb in zip(tx[:-1], tx[1:]):
|
||||
for ya, yb in zip(ty[:-1], ty[1:]):
|
||||
for t in [0.1, 0.5, 0.9]:
|
||||
for s in [0.3, 0.4, 0.7]:
|
||||
xp = xa*(1-t) + xb*t
|
||||
yp = ya*(1-s) + yb*s
|
||||
zp = (+ lut(xa, ya)*(1-t)*(1-s)
|
||||
+ lut(xb, ya)*t*(1-s)
|
||||
+ lut(xa, yb)*(1-t)*s
|
||||
+ lut(xb, yb)*t*s)
|
||||
assert_almost_equal(lut(xp,yp), zp)
|
||||
|
||||
def test_integral(self):
|
||||
x = [1,1,1,2,2,2,8,8,8]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = array([0,7,8,3,4,7,1,3,4])
|
||||
|
||||
s = 0.1
|
||||
tx = [1+s,3-s]
|
||||
ty = [1+s,3-s]
|
||||
with suppress_warnings() as sup:
|
||||
r = sup.record(UserWarning, "\nThe coefficients of the spline")
|
||||
lut = LSQBivariateSpline(x, y, z, tx, ty, kx=1, ky=1)
|
||||
assert_equal(len(r), 1)
|
||||
tx, ty = lut.get_knots()
|
||||
tz = lut(tx, ty)
|
||||
trpz = .25*(diff(tx)[:,None]*diff(ty)[None,:]
|
||||
* (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
|
||||
|
||||
assert_almost_equal(lut.integral(tx[0], tx[-1], ty[0], ty[-1]),
|
||||
trpz)
|
||||
|
||||
def test_empty_input(self):
|
||||
# Test whether empty inputs returns an empty output. Ticket 1014
|
||||
x = [1,1,1,2,2,2,3,3,3]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = [3,3,3,3,3,3,3,3,3]
|
||||
s = 0.1
|
||||
tx = [1+s,3-s]
|
||||
ty = [1+s,3-s]
|
||||
with suppress_warnings() as sup:
|
||||
r = sup.record(UserWarning, "\nThe coefficients of the spline")
|
||||
lut = LSQBivariateSpline(x, y, z, tx, ty, kx=1, ky=1)
|
||||
assert_equal(len(r), 1)
|
||||
|
||||
assert_array_equal(lut([], []), np.zeros((0,0)))
|
||||
assert_array_equal(lut([], [], grid=False), np.zeros((0,)))
|
||||
|
||||
|
||||
class TestSmoothBivariateSpline(object):
|
||||
def test_linear_constant(self):
|
||||
x = [1,1,1,2,2,2,3,3,3]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = [3,3,3,3,3,3,3,3,3]
|
||||
lut = SmoothBivariateSpline(x,y,z,kx=1,ky=1)
|
||||
assert_array_almost_equal(lut.get_knots(),([1,1,3,3],[1,1,3,3]))
|
||||
assert_array_almost_equal(lut.get_coeffs(),[3,3,3,3])
|
||||
assert_almost_equal(lut.get_residual(),0.0)
|
||||
assert_array_almost_equal(lut([1,1.5,2],[1,1.5]),[[3,3],[3,3],[3,3]])
|
||||
|
||||
def test_linear_1d(self):
|
||||
x = [1,1,1,2,2,2,3,3,3]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = [0,0,0,2,2,2,4,4,4]
|
||||
lut = SmoothBivariateSpline(x,y,z,kx=1,ky=1)
|
||||
assert_array_almost_equal(lut.get_knots(),([1,1,3,3],[1,1,3,3]))
|
||||
assert_array_almost_equal(lut.get_coeffs(),[0,0,4,4])
|
||||
assert_almost_equal(lut.get_residual(),0.0)
|
||||
assert_array_almost_equal(lut([1,1.5,2],[1,1.5]),[[0,0],[1,1],[2,2]])
|
||||
|
||||
def test_integral(self):
|
||||
x = [1,1,1,2,2,2,4,4,4]
|
||||
y = [1,2,3,1,2,3,1,2,3]
|
||||
z = array([0,7,8,3,4,7,1,3,4])
|
||||
|
||||
with suppress_warnings() as sup:
|
||||
# This seems to fail (ier=1, see ticket 1642).
|
||||
sup.filter(UserWarning, "\nThe required storage space")
|
||||
lut = SmoothBivariateSpline(x, y, z, kx=1, ky=1, s=0)
|
||||
|
||||
tx = [1,2,4]
|
||||
ty = [1,2,3]
|
||||
|
||||
tz = lut(tx, ty)
|
||||
trpz = .25*(diff(tx)[:,None]*diff(ty)[None,:]
|
||||
* (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
|
||||
assert_almost_equal(lut.integral(tx[0], tx[-1], ty[0], ty[-1]), trpz)
|
||||
|
||||
lut2 = SmoothBivariateSpline(x, y, z, kx=2, ky=2, s=0)
|
||||
assert_almost_equal(lut2.integral(tx[0], tx[-1], ty[0], ty[-1]), trpz,
|
||||
decimal=0) # the quadratures give 23.75 and 23.85
|
||||
|
||||
tz = lut(tx[:-1], ty[:-1])
|
||||
trpz = .25*(diff(tx[:-1])[:,None]*diff(ty[:-1])[None,:]
|
||||
* (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
|
||||
assert_almost_equal(lut.integral(tx[0], tx[-2], ty[0], ty[-2]), trpz)
|
||||
|
||||
def test_rerun_lwrk2_too_small(self):
|
||||
# in this setting, lwrk2 is too small in the default run. Here we
|
||||
# check for equality with the bisplrep/bisplev output because there,
|
||||
# an automatic re-run of the spline representation is done if ier>10.
|
||||
x = np.linspace(-2, 2, 80)
|
||||
y = np.linspace(-2, 2, 80)
|
||||
z = x + y
|
||||
xi = np.linspace(-1, 1, 100)
|
||||
yi = np.linspace(-2, 2, 100)
|
||||
tck = bisplrep(x, y, z)
|
||||
res1 = bisplev(xi, yi, tck)
|
||||
interp_ = SmoothBivariateSpline(x, y, z)
|
||||
res2 = interp_(xi, yi)
|
||||
assert_almost_equal(res1, res2)
|
||||
|
||||
|
||||
class TestLSQSphereBivariateSpline(object):
|
||||
def setup_method(self):
|
||||
# define the input data and coordinates
|
||||
ntheta, nphi = 70, 90
|
||||
theta = linspace(0.5/(ntheta - 1), 1 - 0.5/(ntheta - 1), ntheta) * pi
|
||||
phi = linspace(0.5/(nphi - 1), 1 - 0.5/(nphi - 1), nphi) * 2. * pi
|
||||
data = ones((theta.shape[0], phi.shape[0]))
|
||||
# define knots and extract data values at the knots
|
||||
knotst = theta[::5]
|
||||
knotsp = phi[::5]
|
||||
knotdata = data[::5, ::5]
|
||||
# calculate spline coefficients
|
||||
lats, lons = meshgrid(theta, phi)
|
||||
lut_lsq = LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
|
||||
data.T.ravel(), knotst, knotsp)
|
||||
self.lut_lsq = lut_lsq
|
||||
self.data = knotdata
|
||||
self.new_lons, self.new_lats = knotsp, knotst
|
||||
|
||||
def test_linear_constant(self):
|
||||
assert_almost_equal(self.lut_lsq.get_residual(), 0.0)
|
||||
assert_array_almost_equal(self.lut_lsq(self.new_lats, self.new_lons),
|
||||
self.data)
|
||||
|
||||
def test_empty_input(self):
|
||||
assert_array_almost_equal(self.lut_lsq([], []), np.zeros((0,0)))
|
||||
assert_array_almost_equal(self.lut_lsq([], [], grid=False), np.zeros((0,)))
|
||||
|
||||
|
||||
class TestSmoothSphereBivariateSpline(object):
|
||||
def setup_method(self):
|
||||
theta = array([.25*pi, .25*pi, .25*pi, .5*pi, .5*pi, .5*pi, .75*pi,
|
||||
.75*pi, .75*pi])
|
||||
phi = array([.5 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi, .5 * pi, pi,
|
||||
1.5 * pi])
|
||||
r = array([3, 3, 3, 3, 3, 3, 3, 3, 3])
|
||||
self.lut = SmoothSphereBivariateSpline(theta, phi, r, s=1E10)
|
||||
|
||||
def test_linear_constant(self):
|
||||
assert_almost_equal(self.lut.get_residual(), 0.)
|
||||
assert_array_almost_equal(self.lut([1, 1.5, 2],[1, 1.5]),
|
||||
[[3, 3], [3, 3], [3, 3]])
|
||||
|
||||
def test_empty_input(self):
|
||||
assert_array_almost_equal(self.lut([], []), np.zeros((0,0)))
|
||||
assert_array_almost_equal(self.lut([], [], grid=False), np.zeros((0,)))
|
||||
|
||||
|
||||
class TestRectBivariateSpline(object):
|
||||
def test_defaults(self):
|
||||
x = array([1,2,3,4,5])
|
||||
y = array([1,2,3,4,5])
|
||||
z = array([[1,2,1,2,1],[1,2,1,2,1],[1,2,3,2,1],[1,2,2,2,1],[1,2,1,2,1]])
|
||||
lut = RectBivariateSpline(x,y,z)
|
||||
assert_array_almost_equal(lut(x,y),z)
|
||||
|
||||
def test_evaluate(self):
|
||||
x = array([1,2,3,4,5])
|
||||
y = array([1,2,3,4,5])
|
||||
z = array([[1,2,1,2,1],[1,2,1,2,1],[1,2,3,2,1],[1,2,2,2,1],[1,2,1,2,1]])
|
||||
lut = RectBivariateSpline(x,y,z)
|
||||
|
||||
xi = [1, 2.3, 5.3, 0.5, 3.3, 1.2, 3]
|
||||
yi = [1, 3.3, 1.2, 4.0, 5.0, 1.0, 3]
|
||||
zi = lut.ev(xi, yi)
|
||||
zi2 = array([lut(xp, yp)[0,0] for xp, yp in zip(xi, yi)])
|
||||
|
||||
assert_almost_equal(zi, zi2)
|
||||
|
||||
def test_derivatives_grid(self):
|
||||
x = array([1,2,3,4,5])
|
||||
y = array([1,2,3,4,5])
|
||||
z = array([[1,2,1,2,1],[1,2,1,2,1],[1,2,3,2,1],[1,2,2,2,1],[1,2,1,2,1]])
|
||||
dx = array([[0,0,-20,0,0],[0,0,13,0,0],[0,0,4,0,0],
|
||||
[0,0,-11,0,0],[0,0,4,0,0]])/6.
|
||||
dy = array([[4,-1,0,1,-4],[4,-1,0,1,-4],[0,1.5,0,-1.5,0],
|
||||
[2,.25,0,-.25,-2],[4,-1,0,1,-4]])
|
||||
dxdy = array([[40,-25,0,25,-40],[-26,16.25,0,-16.25,26],
|
||||
[-8,5,0,-5,8],[22,-13.75,0,13.75,-22],[-8,5,0,-5,8]])/6.
|
||||
lut = RectBivariateSpline(x,y,z)
|
||||
assert_array_almost_equal(lut(x,y,dx=1),dx)
|
||||
assert_array_almost_equal(lut(x,y,dy=1),dy)
|
||||
assert_array_almost_equal(lut(x,y,dx=1,dy=1),dxdy)
|
||||
|
||||
def test_derivatives(self):
|
||||
x = array([1,2,3,4,5])
|
||||
y = array([1,2,3,4,5])
|
||||
z = array([[1,2,1,2,1],[1,2,1,2,1],[1,2,3,2,1],[1,2,2,2,1],[1,2,1,2,1]])
|
||||
dx = array([0,0,2./3,0,0])
|
||||
dy = array([4,-1,0,-.25,-4])
|
||||
dxdy = array([160,65,0,55,32])/24.
|
||||
lut = RectBivariateSpline(x,y,z)
|
||||
assert_array_almost_equal(lut(x,y,dx=1,grid=False),dx)
|
||||
assert_array_almost_equal(lut(x,y,dy=1,grid=False),dy)
|
||||
assert_array_almost_equal(lut(x,y,dx=1,dy=1,grid=False),dxdy)
|
||||
|
||||
def test_broadcast(self):
|
||||
x = array([1,2,3,4,5])
|
||||
y = array([1,2,3,4,5])
|
||||
z = array([[1,2,1,2,1],[1,2,1,2,1],[1,2,3,2,1],[1,2,2,2,1],[1,2,1,2,1]])
|
||||
lut = RectBivariateSpline(x,y,z)
|
||||
assert_allclose(lut(x, y), lut(x[:,None], y[None,:], grid=False))
|
||||
|
||||
|
||||
class TestRectSphereBivariateSpline(object):
|
||||
def test_defaults(self):
|
||||
y = linspace(0.01, 2*pi-0.01, 7)
|
||||
x = linspace(0.01, pi-0.01, 7)
|
||||
z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
|
||||
[1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
|
||||
[1,2,1,2,1,2,1]])
|
||||
lut = RectSphereBivariateSpline(x,y,z)
|
||||
assert_array_almost_equal(lut(x,y),z)
|
||||
|
||||
def test_evaluate(self):
|
||||
y = linspace(0.01, 2*pi-0.01, 7)
|
||||
x = linspace(0.01, pi-0.01, 7)
|
||||
z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
|
||||
[1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
|
||||
[1,2,1,2,1,2,1]])
|
||||
lut = RectSphereBivariateSpline(x,y,z)
|
||||
yi = [0.2, 1, 2.3, 2.35, 3.0, 3.99, 5.25]
|
||||
xi = [1.5, 0.4, 1.1, 0.45, 0.2345, 1., 0.0001]
|
||||
zi = lut.ev(xi, yi)
|
||||
zi2 = array([lut(xp, yp)[0,0] for xp, yp in zip(xi, yi)])
|
||||
assert_almost_equal(zi, zi2)
|
||||
|
||||
def test_derivatives_grid(self):
|
||||
y = linspace(0.01, 2*pi-0.01, 7)
|
||||
x = linspace(0.01, pi-0.01, 7)
|
||||
z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
|
||||
[1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
|
||||
[1,2,1,2,1,2,1]])
|
||||
|
||||
lut = RectSphereBivariateSpline(x,y,z)
|
||||
|
||||
y = linspace(0.02, 2*pi-0.02, 7)
|
||||
x = linspace(0.02, pi-0.02, 7)
|
||||
|
||||
assert_allclose(lut(x, y, dtheta=1), _numdiff_2d(lut, x, y, dx=1),
|
||||
rtol=1e-4, atol=1e-4)
|
||||
assert_allclose(lut(x, y, dphi=1), _numdiff_2d(lut, x, y, dy=1),
|
||||
rtol=1e-4, atol=1e-4)
|
||||
assert_allclose(lut(x, y, dtheta=1, dphi=1), _numdiff_2d(lut, x, y, dx=1, dy=1, eps=1e-6),
|
||||
rtol=1e-3, atol=1e-3)
|
||||
|
||||
def test_derivatives(self):
|
||||
y = linspace(0.01, 2*pi-0.01, 7)
|
||||
x = linspace(0.01, pi-0.01, 7)
|
||||
z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
|
||||
[1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
|
||||
[1,2,1,2,1,2,1]])
|
||||
|
||||
lut = RectSphereBivariateSpline(x,y,z)
|
||||
|
||||
y = linspace(0.02, 2*pi-0.02, 7)
|
||||
x = linspace(0.02, pi-0.02, 7)
|
||||
|
||||
assert_equal(lut(x, y, dtheta=1, grid=False).shape, x.shape)
|
||||
assert_allclose(lut(x, y, dtheta=1, grid=False),
|
||||
_numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dx=1),
|
||||
rtol=1e-4, atol=1e-4)
|
||||
assert_allclose(lut(x, y, dphi=1, grid=False),
|
||||
_numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dy=1),
|
||||
rtol=1e-4, atol=1e-4)
|
||||
assert_allclose(lut(x, y, dtheta=1, dphi=1, grid=False),
|
||||
_numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dx=1, dy=1, eps=1e-6),
|
||||
rtol=1e-3, atol=1e-3)
|
||||
|
||||
|
||||
def _numdiff_2d(func, x, y, dx=0, dy=0, eps=1e-8):
|
||||
if dx == 0 and dy == 0:
|
||||
return func(x, y)
|
||||
elif dx == 1 and dy == 0:
|
||||
return (func(x + eps, y) - func(x - eps, y)) / (2*eps)
|
||||
elif dx == 0 and dy == 1:
|
||||
return (func(x, y + eps) - func(x, y - eps)) / (2*eps)
|
||||
elif dx == 1 and dy == 1:
|
||||
return (func(x + eps, y + eps) - func(x - eps, y + eps)
|
||||
- func(x + eps, y - eps) + func(x - eps, y - eps)) / (2*eps)**2
|
||||
else:
|
||||
raise ValueError("invalid derivative order")
|
||||
@@ -0,0 +1,67 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import itertools
|
||||
import threading
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal
|
||||
import pytest
|
||||
import scipy.interpolate
|
||||
|
||||
|
||||
class TestGIL(object):
|
||||
"""Check if the GIL is properly released by scipy.interpolate functions."""
|
||||
|
||||
def setup_method(self):
|
||||
self.messages = []
|
||||
|
||||
def log(self, message):
|
||||
self.messages.append(message)
|
||||
|
||||
def make_worker_thread(self, target, args):
|
||||
log = self.log
|
||||
|
||||
class WorkerThread(threading.Thread):
|
||||
def run(self):
|
||||
log('interpolation started')
|
||||
target(*args)
|
||||
log('interpolation complete')
|
||||
|
||||
return WorkerThread()
|
||||
|
||||
@pytest.mark.slow
|
||||
@pytest.mark.xfail(reason='race conditions, may depend on system load')
|
||||
def test_rectbivariatespline(self):
|
||||
def generate_params(n_points):
|
||||
x = y = np.linspace(0, 1000, n_points)
|
||||
x_grid, y_grid = np.meshgrid(x, y)
|
||||
z = x_grid * y_grid
|
||||
return x, y, z
|
||||
|
||||
def calibrate_delay(requested_time):
|
||||
for n_points in itertools.count(5000, 1000):
|
||||
args = generate_params(n_points)
|
||||
time_started = time.time()
|
||||
interpolate(*args)
|
||||
if time.time() - time_started > requested_time:
|
||||
return args
|
||||
|
||||
def interpolate(x, y, z):
|
||||
scipy.interpolate.RectBivariateSpline(x, y, z)
|
||||
|
||||
args = calibrate_delay(requested_time=3)
|
||||
worker_thread = self.make_worker_thread(interpolate, args)
|
||||
worker_thread.start()
|
||||
for i in range(3):
|
||||
time.sleep(0.5)
|
||||
self.log('working')
|
||||
worker_thread.join()
|
||||
assert_equal(self.messages, [
|
||||
'interpolation started',
|
||||
'working',
|
||||
'working',
|
||||
'working',
|
||||
'interpolation complete',
|
||||
])
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal, assert_allclose, assert_almost_equal
|
||||
from pytest import raises as assert_raises
|
||||
import pytest
|
||||
from scipy._lib._numpy_compat import suppress_warnings
|
||||
|
||||
import scipy.interpolate.interpnd as interpnd
|
||||
import scipy.spatial.qhull as qhull
|
||||
|
||||
import pickle
|
||||
|
||||
|
||||
def data_file(basename):
|
||||
return os.path.join(os.path.abspath(os.path.dirname(__file__)),
|
||||
'data', basename)
|
||||
|
||||
|
||||
class TestLinearNDInterpolation(object):
|
||||
def test_smoketest(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
|
||||
yi = interpnd.LinearNDInterpolator(x, y)(x)
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_smoketest_alternate(self):
|
||||
# Test at single points, alternate calling convention
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
|
||||
yi = interpnd.LinearNDInterpolator((x[:,0], x[:,1]), y)(x[:,0], x[:,1])
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_complex_smoketest(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
yi = interpnd.LinearNDInterpolator(x, y)(x)
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_tri_input(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
yi = interpnd.LinearNDInterpolator(tri, y)(x)
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_square(self):
|
||||
# Test barycentric interpolation on a square against a manual
|
||||
# implementation
|
||||
|
||||
points = np.array([(0,0), (0,1), (1,1), (1,0)], dtype=np.double)
|
||||
values = np.array([1., 2., -3., 5.], dtype=np.double)
|
||||
|
||||
# NB: assume triangles (0, 1, 3) and (1, 2, 3)
|
||||
#
|
||||
# 1----2
|
||||
# | \ |
|
||||
# | \ |
|
||||
# 0----3
|
||||
|
||||
def ip(x, y):
|
||||
t1 = (x + y <= 1)
|
||||
t2 = ~t1
|
||||
|
||||
x1 = x[t1]
|
||||
y1 = y[t1]
|
||||
|
||||
x2 = x[t2]
|
||||
y2 = y[t2]
|
||||
|
||||
z = 0*x
|
||||
|
||||
z[t1] = (values[0]*(1 - x1 - y1)
|
||||
+ values[1]*y1
|
||||
+ values[3]*x1)
|
||||
|
||||
z[t2] = (values[2]*(x2 + y2 - 1)
|
||||
+ values[1]*(1 - x2)
|
||||
+ values[3]*(1 - y2))
|
||||
return z
|
||||
|
||||
xx, yy = np.broadcast_arrays(np.linspace(0, 1, 14)[:,None],
|
||||
np.linspace(0, 1, 14)[None,:])
|
||||
xx = xx.ravel()
|
||||
yy = yy.ravel()
|
||||
|
||||
xi = np.array([xx, yy]).T.copy()
|
||||
zi = interpnd.LinearNDInterpolator(points, values)(xi)
|
||||
|
||||
assert_almost_equal(zi, ip(xx, yy))
|
||||
|
||||
def test_smoketest_rescale(self):
|
||||
# Test at single points
|
||||
x = np.array([(0, 0), (-5, -5), (-5, 5), (5, 5), (2.5, 3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
|
||||
yi = interpnd.LinearNDInterpolator(x, y, rescale=True)(x)
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_square_rescale(self):
|
||||
# Test barycentric interpolation on a rectangle with rescaling
|
||||
# agaings the same implementation without rescaling
|
||||
|
||||
points = np.array([(0,0), (0,100), (10,100), (10,0)], dtype=np.double)
|
||||
values = np.array([1., 2., -3., 5.], dtype=np.double)
|
||||
|
||||
xx, yy = np.broadcast_arrays(np.linspace(0, 10, 14)[:,None],
|
||||
np.linspace(0, 100, 14)[None,:])
|
||||
xx = xx.ravel()
|
||||
yy = yy.ravel()
|
||||
xi = np.array([xx, yy]).T.copy()
|
||||
zi = interpnd.LinearNDInterpolator(points, values)(xi)
|
||||
zi_rescaled = interpnd.LinearNDInterpolator(points, values,
|
||||
rescale=True)(xi)
|
||||
|
||||
assert_almost_equal(zi, zi_rescaled)
|
||||
|
||||
def test_tripoints_input_rescale(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-5,-5), (-5,5), (5, 5), (2.5, 3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
yi = interpnd.LinearNDInterpolator(tri.points, y)(x)
|
||||
yi_rescale = interpnd.LinearNDInterpolator(tri.points, y,
|
||||
rescale=True)(x)
|
||||
assert_almost_equal(yi, yi_rescale)
|
||||
|
||||
def test_tri_input_rescale(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-5,-5), (-5,5), (5, 5), (2.5, 3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
match = ("Rescaling is not supported when passing a "
|
||||
"Delaunay triangulation as ``points``.")
|
||||
with pytest.raises(ValueError, match=match):
|
||||
interpnd.LinearNDInterpolator(tri, y, rescale=True)(x)
|
||||
|
||||
def test_pickle(self):
|
||||
# Test at single points
|
||||
np.random.seed(1234)
|
||||
x = np.random.rand(30, 2)
|
||||
y = np.random.rand(30) + 1j*np.random.rand(30)
|
||||
|
||||
ip = interpnd.LinearNDInterpolator(x, y)
|
||||
ip2 = pickle.loads(pickle.dumps(ip))
|
||||
|
||||
assert_almost_equal(ip(0.5, 0.5), ip2(0.5, 0.5))
|
||||
|
||||
|
||||
class TestEstimateGradients2DGlobal(object):
|
||||
def test_smoketest(self):
|
||||
x = np.array([(0, 0), (0, 2),
|
||||
(1, 0), (1, 2), (0.25, 0.75), (0.6, 0.8)], dtype=float)
|
||||
tri = qhull.Delaunay(x)
|
||||
|
||||
# Should be exact for linear functions, independent of triangulation
|
||||
|
||||
funcs = [
|
||||
(lambda x, y: 0*x + 1, (0, 0)),
|
||||
(lambda x, y: 0 + x, (1, 0)),
|
||||
(lambda x, y: -2 + y, (0, 1)),
|
||||
(lambda x, y: 3 + 3*x + 14.15*y, (3, 14.15))
|
||||
]
|
||||
|
||||
for j, (func, grad) in enumerate(funcs):
|
||||
z = func(x[:,0], x[:,1])
|
||||
dz = interpnd.estimate_gradients_2d_global(tri, z, tol=1e-6)
|
||||
|
||||
assert_equal(dz.shape, (6, 2))
|
||||
assert_allclose(dz, np.array(grad)[None,:] + 0*dz,
|
||||
rtol=1e-5, atol=1e-5, err_msg="item %d" % j)
|
||||
|
||||
def test_regression_2359(self):
|
||||
# Check regression --- for certain point sets, gradient
|
||||
# estimation could end up in an infinite loop
|
||||
points = np.load(data_file('estimate_gradients_hang.npy'))
|
||||
values = np.random.rand(points.shape[0])
|
||||
tri = qhull.Delaunay(points)
|
||||
|
||||
# This should not hang
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(interpnd.GradientEstimationWarning,
|
||||
"Gradient estimation did not converge")
|
||||
interpnd.estimate_gradients_2d_global(tri, values, maxiter=1)
|
||||
|
||||
|
||||
class TestCloughTocher2DInterpolator(object):
|
||||
|
||||
def _check_accuracy(self, func, x=None, tol=1e-6, alternate=False, rescale=False, **kw):
|
||||
np.random.seed(1234)
|
||||
if x is None:
|
||||
x = np.array([(0, 0), (0, 1),
|
||||
(1, 0), (1, 1), (0.25, 0.75), (0.6, 0.8),
|
||||
(0.5, 0.2)],
|
||||
dtype=float)
|
||||
|
||||
if not alternate:
|
||||
ip = interpnd.CloughTocher2DInterpolator(x, func(x[:,0], x[:,1]),
|
||||
tol=1e-6, rescale=rescale)
|
||||
else:
|
||||
ip = interpnd.CloughTocher2DInterpolator((x[:,0], x[:,1]),
|
||||
func(x[:,0], x[:,1]),
|
||||
tol=1e-6, rescale=rescale)
|
||||
|
||||
p = np.random.rand(50, 2)
|
||||
|
||||
if not alternate:
|
||||
a = ip(p)
|
||||
else:
|
||||
a = ip(p[:,0], p[:,1])
|
||||
b = func(p[:,0], p[:,1])
|
||||
|
||||
try:
|
||||
assert_allclose(a, b, **kw)
|
||||
except AssertionError:
|
||||
print(abs(a - b))
|
||||
print(ip.grad)
|
||||
raise
|
||||
|
||||
def test_linear_smoketest(self):
|
||||
# Should be exact for linear functions, independent of triangulation
|
||||
funcs = [
|
||||
lambda x, y: 0*x + 1,
|
||||
lambda x, y: 0 + x,
|
||||
lambda x, y: -2 + y,
|
||||
lambda x, y: 3 + 3*x + 14.15*y,
|
||||
]
|
||||
|
||||
for j, func in enumerate(funcs):
|
||||
self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
|
||||
err_msg="Function %d" % j)
|
||||
self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
|
||||
alternate=True,
|
||||
err_msg="Function (alternate) %d" % j)
|
||||
# check rescaling
|
||||
self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
|
||||
err_msg="Function (rescaled) %d" % j, rescale=True)
|
||||
self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
|
||||
alternate=True, rescale=True,
|
||||
err_msg="Function (alternate, rescaled) %d" % j)
|
||||
|
||||
def test_quadratic_smoketest(self):
|
||||
# Should be reasonably accurate for quadratic functions
|
||||
funcs = [
|
||||
lambda x, y: x**2,
|
||||
lambda x, y: y**2,
|
||||
lambda x, y: x**2 - y**2,
|
||||
lambda x, y: x*y,
|
||||
]
|
||||
|
||||
for j, func in enumerate(funcs):
|
||||
self._check_accuracy(func, tol=1e-9, atol=0.22, rtol=0,
|
||||
err_msg="Function %d" % j)
|
||||
self._check_accuracy(func, tol=1e-9, atol=0.22, rtol=0,
|
||||
err_msg="Function %d" % j, rescale=True)
|
||||
|
||||
def test_tri_input(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
yi = interpnd.CloughTocher2DInterpolator(tri, y)(x)
|
||||
assert_almost_equal(y, yi)
|
||||
|
||||
def test_tri_input_rescale(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-5,-5), (-5,5), (5, 5), (2.5, 3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
match = ("Rescaling is not supported when passing a "
|
||||
"Delaunay triangulation as ``points``.")
|
||||
with pytest.raises(ValueError, match=match):
|
||||
interpnd.CloughTocher2DInterpolator(tri, y, rescale=True)(x)
|
||||
|
||||
def test_tripoints_input_rescale(self):
|
||||
# Test at single points
|
||||
x = np.array([(0,0), (-5,-5), (-5,5), (5, 5), (2.5, 3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 3j*y
|
||||
|
||||
tri = qhull.Delaunay(x)
|
||||
yi = interpnd.CloughTocher2DInterpolator(tri.points, y)(x)
|
||||
yi_rescale = interpnd.CloughTocher2DInterpolator(tri.points, y, rescale=True)(x)
|
||||
assert_almost_equal(yi, yi_rescale)
|
||||
|
||||
def test_dense(self):
|
||||
# Should be more accurate for dense meshes
|
||||
funcs = [
|
||||
lambda x, y: x**2,
|
||||
lambda x, y: y**2,
|
||||
lambda x, y: x**2 - y**2,
|
||||
lambda x, y: x*y,
|
||||
lambda x, y: np.cos(2*np.pi*x)*np.sin(2*np.pi*y)
|
||||
]
|
||||
|
||||
np.random.seed(4321) # use a different seed than the check!
|
||||
grid = np.r_[np.array([(0,0), (0,1), (1,0), (1,1)], dtype=float),
|
||||
np.random.rand(30*30, 2)]
|
||||
|
||||
for j, func in enumerate(funcs):
|
||||
self._check_accuracy(func, x=grid, tol=1e-9, atol=5e-3, rtol=1e-2,
|
||||
err_msg="Function %d" % j)
|
||||
self._check_accuracy(func, x=grid, tol=1e-9, atol=5e-3, rtol=1e-2,
|
||||
err_msg="Function %d" % j, rescale=True)
|
||||
|
||||
def test_wrong_ndim(self):
|
||||
x = np.random.randn(30, 3)
|
||||
y = np.random.randn(30)
|
||||
assert_raises(ValueError, interpnd.CloughTocher2DInterpolator, x, y)
|
||||
|
||||
def test_pickle(self):
|
||||
# Test at single points
|
||||
np.random.seed(1234)
|
||||
x = np.random.rand(30, 2)
|
||||
y = np.random.rand(30) + 1j*np.random.rand(30)
|
||||
|
||||
ip = interpnd.CloughTocher2DInterpolator(x, y)
|
||||
ip2 = pickle.loads(pickle.dumps(ip))
|
||||
|
||||
assert_almost_equal(ip(0.5, 0.5), ip2(0.5, 0.5))
|
||||
|
||||
def test_boundary_tri_symmetry(self):
|
||||
# Interpolation at neighbourless triangles should retain
|
||||
# symmetry with mirroring the triangle.
|
||||
|
||||
# Equilateral triangle
|
||||
points = np.array([(0, 0), (1, 0), (0.5, np.sqrt(3)/2)])
|
||||
values = np.array([1, 0, 0])
|
||||
|
||||
ip = interpnd.CloughTocher2DInterpolator(points, values)
|
||||
|
||||
# Set gradient to zero at vertices
|
||||
ip.grad[...] = 0
|
||||
|
||||
# Interpolation should be symmetric vs. bisector
|
||||
alpha = 0.3
|
||||
p1 = np.array([0.5 * np.cos(alpha), 0.5 * np.sin(alpha)])
|
||||
p2 = np.array([0.5 * np.cos(np.pi/3 - alpha), 0.5 * np.sin(np.pi/3 - alpha)])
|
||||
|
||||
v1 = ip(p1)
|
||||
v2 = ip(p2)
|
||||
assert_allclose(v1, v2)
|
||||
|
||||
# ... and affine invariant
|
||||
np.random.seed(1)
|
||||
A = np.random.randn(2, 2)
|
||||
b = np.random.randn(2)
|
||||
|
||||
points = A.dot(points.T).T + b[None,:]
|
||||
p1 = A.dot(p1) + b
|
||||
p2 = A.dot(p2) + b
|
||||
|
||||
ip = interpnd.CloughTocher2DInterpolator(points, values)
|
||||
ip.grad[...] = 0
|
||||
|
||||
w1 = ip(p1)
|
||||
w2 = ip(p2)
|
||||
assert_allclose(w1, v1)
|
||||
assert_allclose(w2, v2)
|
||||
File diff suppressed because it is too large
Load Diff
+81
@@ -0,0 +1,81 @@
|
||||
""" module to test interpolate_wrapper.py
|
||||
"""
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
from numpy import arange, allclose, ones, isnan
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_, assert_allclose)
|
||||
from scipy._lib._numpy_compat import suppress_warnings
|
||||
|
||||
# functionality to be tested
|
||||
from scipy.interpolate.interpolate_wrapper import (linear, logarithmic,
|
||||
block_average_above, nearest)
|
||||
|
||||
|
||||
class Test(object):
|
||||
|
||||
def assertAllclose(self, x, y, rtol=1.0e-5):
|
||||
for i, xi in enumerate(x):
|
||||
assert_(allclose(xi, y[i], rtol) or (isnan(xi) and isnan(y[i])))
|
||||
|
||||
def test_nearest(self):
|
||||
N = 5
|
||||
x = arange(N)
|
||||
y = arange(N)
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(DeprecationWarning, "`nearest` is deprecated")
|
||||
assert_allclose(y, nearest(x, y, x+.1))
|
||||
assert_allclose(y, nearest(x, y, x-.1))
|
||||
|
||||
def test_linear(self):
|
||||
N = 3000.
|
||||
x = arange(N)
|
||||
y = arange(N)
|
||||
new_x = arange(N)+0.5
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(DeprecationWarning, "`linear` is deprecated")
|
||||
new_y = linear(x, y, new_x)
|
||||
|
||||
assert_allclose(new_y[:5], [0.5, 1.5, 2.5, 3.5, 4.5])
|
||||
|
||||
def test_block_average_above(self):
|
||||
N = 3000
|
||||
x = arange(N, dtype=float)
|
||||
y = arange(N, dtype=float)
|
||||
|
||||
new_x = arange(N // 2) * 2
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(DeprecationWarning, "`block_average_above` is deprecated")
|
||||
new_y = block_average_above(x, y, new_x)
|
||||
assert_allclose(new_y[:5], [0.0, 0.5, 2.5, 4.5, 6.5])
|
||||
|
||||
def test_linear2(self):
|
||||
N = 3000
|
||||
x = arange(N, dtype=float)
|
||||
y = ones((100,N)) * arange(N)
|
||||
new_x = arange(N) + 0.5
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(DeprecationWarning, "`linear` is deprecated")
|
||||
new_y = linear(x, y, new_x)
|
||||
assert_allclose(new_y[:5,:5],
|
||||
[[0.5, 1.5, 2.5, 3.5, 4.5],
|
||||
[0.5, 1.5, 2.5, 3.5, 4.5],
|
||||
[0.5, 1.5, 2.5, 3.5, 4.5],
|
||||
[0.5, 1.5, 2.5, 3.5, 4.5],
|
||||
[0.5, 1.5, 2.5, 3.5, 4.5]])
|
||||
|
||||
def test_logarithmic(self):
|
||||
N = 4000.
|
||||
x = arange(N)
|
||||
y = arange(N)
|
||||
new_x = arange(N)+0.5
|
||||
with suppress_warnings() as sup:
|
||||
sup.filter(DeprecationWarning, "`logarithmic` is deprecated")
|
||||
new_y = logarithmic(x, y, new_x)
|
||||
correct_y = [np.NaN, 1.41421356, 2.44948974, 3.46410162, 4.47213595]
|
||||
assert_allclose(new_y[:5], correct_y)
|
||||
|
||||
def runTest(self):
|
||||
test_list = [name for name in dir(self) if name.find('test_') == 0]
|
||||
for test_name in test_list:
|
||||
exec("self.%s()" % test_name)
|
||||
@@ -0,0 +1,177 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal, assert_array_equal, assert_allclose
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.interpolate import griddata, NearestNDInterpolator
|
||||
|
||||
|
||||
class TestGriddata(object):
|
||||
def test_fill_value(self):
|
||||
x = [(0,0), (0,1), (1,0)]
|
||||
y = [1, 2, 3]
|
||||
|
||||
yi = griddata(x, y, [(1,1), (1,2), (0,0)], fill_value=-1)
|
||||
assert_array_equal(yi, [-1., -1, 1])
|
||||
|
||||
yi = griddata(x, y, [(1,1), (1,2), (0,0)])
|
||||
assert_array_equal(yi, [np.nan, np.nan, 1])
|
||||
|
||||
def test_alternative_call(self):
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = (np.arange(x.shape[0], dtype=np.double)[:,None]
|
||||
+ np.array([0,1])[None,:])
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
for rescale in (True, False):
|
||||
msg = repr((method, rescale))
|
||||
yi = griddata((x[:,0], x[:,1]), y, (x[:,0], x[:,1]), method=method,
|
||||
rescale=rescale)
|
||||
assert_allclose(y, yi, atol=1e-14, err_msg=msg)
|
||||
|
||||
def test_multivalue_2d(self):
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = (np.arange(x.shape[0], dtype=np.double)[:,None]
|
||||
+ np.array([0,1])[None,:])
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
for rescale in (True, False):
|
||||
msg = repr((method, rescale))
|
||||
yi = griddata(x, y, x, method=method, rescale=rescale)
|
||||
assert_allclose(y, yi, atol=1e-14, err_msg=msg)
|
||||
|
||||
def test_multipoint_2d(self):
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
|
||||
xi = x[:,None,:] + np.array([0,0,0])[None,:,None]
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
for rescale in (True, False):
|
||||
msg = repr((method, rescale))
|
||||
yi = griddata(x, y, xi, method=method, rescale=rescale)
|
||||
|
||||
assert_equal(yi.shape, (5, 3), err_msg=msg)
|
||||
assert_allclose(yi, np.tile(y[:,None], (1, 3)),
|
||||
atol=1e-14, err_msg=msg)
|
||||
|
||||
def test_complex_2d(self):
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 2j*y[::-1]
|
||||
|
||||
xi = x[:,None,:] + np.array([0,0,0])[None,:,None]
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
for rescale in (True, False):
|
||||
msg = repr((method, rescale))
|
||||
yi = griddata(x, y, xi, method=method, rescale=rescale)
|
||||
|
||||
assert_equal(yi.shape, (5, 3), err_msg=msg)
|
||||
assert_allclose(yi, np.tile(y[:,None], (1, 3)),
|
||||
atol=1e-14, err_msg=msg)
|
||||
|
||||
def test_1d(self):
|
||||
x = np.array([1, 2.5, 3, 4.5, 5, 6])
|
||||
y = np.array([1, 2, 0, 3.9, 2, 1])
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
assert_allclose(griddata(x, y, x, method=method), y,
|
||||
err_msg=method, atol=1e-14)
|
||||
assert_allclose(griddata(x.reshape(6, 1), y, x, method=method), y,
|
||||
err_msg=method, atol=1e-14)
|
||||
assert_allclose(griddata((x,), y, (x,), method=method), y,
|
||||
err_msg=method, atol=1e-14)
|
||||
|
||||
def test_1d_borders(self):
|
||||
# Test for nearest neighbor case with xi outside
|
||||
# the range of the values.
|
||||
x = np.array([1, 2.5, 3, 4.5, 5, 6])
|
||||
y = np.array([1, 2, 0, 3.9, 2, 1])
|
||||
xi = np.array([0.9, 6.5])
|
||||
yi_should = np.array([1.0, 1.0])
|
||||
|
||||
method = 'nearest'
|
||||
assert_allclose(griddata(x, y, xi,
|
||||
method=method), yi_should,
|
||||
err_msg=method,
|
||||
atol=1e-14)
|
||||
assert_allclose(griddata(x.reshape(6, 1), y, xi,
|
||||
method=method), yi_should,
|
||||
err_msg=method,
|
||||
atol=1e-14)
|
||||
assert_allclose(griddata((x, ), y, (xi, ),
|
||||
method=method), yi_should,
|
||||
err_msg=method,
|
||||
atol=1e-14)
|
||||
|
||||
def test_1d_unsorted(self):
|
||||
x = np.array([2.5, 1, 4.5, 5, 6, 3])
|
||||
y = np.array([1, 2, 0, 3.9, 2, 1])
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
assert_allclose(griddata(x, y, x, method=method), y,
|
||||
err_msg=method, atol=1e-10)
|
||||
assert_allclose(griddata(x.reshape(6, 1), y, x, method=method), y,
|
||||
err_msg=method, atol=1e-10)
|
||||
assert_allclose(griddata((x,), y, (x,), method=method), y,
|
||||
err_msg=method, atol=1e-10)
|
||||
|
||||
def test_square_rescale_manual(self):
|
||||
points = np.array([(0,0), (0,100), (10,100), (10,0), (1, 5)], dtype=np.double)
|
||||
points_rescaled = np.array([(0,0), (0,1), (1,1), (1,0), (0.1, 0.05)], dtype=np.double)
|
||||
values = np.array([1., 2., -3., 5., 9.], dtype=np.double)
|
||||
|
||||
xx, yy = np.broadcast_arrays(np.linspace(0, 10, 14)[:,None],
|
||||
np.linspace(0, 100, 14)[None,:])
|
||||
xx = xx.ravel()
|
||||
yy = yy.ravel()
|
||||
xi = np.array([xx, yy]).T.copy()
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
msg = method
|
||||
zi = griddata(points_rescaled, values, xi/np.array([10, 100.]),
|
||||
method=method)
|
||||
zi_rescaled = griddata(points, values, xi, method=method,
|
||||
rescale=True)
|
||||
assert_allclose(zi, zi_rescaled, err_msg=msg,
|
||||
atol=1e-12)
|
||||
|
||||
def test_xi_1d(self):
|
||||
# Check that 1-D xi is interpreted as a coordinate
|
||||
x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
|
||||
dtype=np.double)
|
||||
y = np.arange(x.shape[0], dtype=np.double)
|
||||
y = y - 2j*y[::-1]
|
||||
|
||||
xi = np.array([0.5, 0.5])
|
||||
|
||||
for method in ('nearest', 'linear', 'cubic'):
|
||||
p1 = griddata(x, y, xi, method=method)
|
||||
p2 = griddata(x, y, xi[None,:], method=method)
|
||||
assert_allclose(p1, p2, err_msg=method)
|
||||
|
||||
xi1 = np.array([0.5])
|
||||
xi3 = np.array([0.5, 0.5, 0.5])
|
||||
assert_raises(ValueError, griddata, x, y, xi1,
|
||||
method=method)
|
||||
assert_raises(ValueError, griddata, x, y, xi3,
|
||||
method=method)
|
||||
|
||||
|
||||
def test_nearest_options():
|
||||
# smoke test that NearestNDInterpolator accept cKDTree options
|
||||
npts, nd = 4, 3
|
||||
x = np.arange(npts*nd).reshape((npts, nd))
|
||||
y = np.arange(npts)
|
||||
nndi = NearestNDInterpolator(x, y)
|
||||
|
||||
opts = {'balanced_tree': False, 'compact_nodes': False}
|
||||
nndi_o = NearestNDInterpolator(x, y, tree_options=opts)
|
||||
assert_allclose(nndi(x), nndi_o(x), atol=1e-14)
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
from numpy.testing import (assert_array_equal, assert_array_almost_equal)
|
||||
from scipy.interpolate import pade
|
||||
|
||||
def test_pade_trivial():
|
||||
nump, denomp = pade([1.0], 0)
|
||||
assert_array_equal(nump.c, [1.0])
|
||||
assert_array_equal(denomp.c, [1.0])
|
||||
|
||||
nump, denomp = pade([1.0], 0, 0)
|
||||
assert_array_equal(nump.c, [1.0])
|
||||
assert_array_equal(denomp.c, [1.0])
|
||||
|
||||
|
||||
def test_pade_4term_exp():
|
||||
# First four Taylor coefficients of exp(x).
|
||||
# Unlike poly1d, the first array element is the zero-order term.
|
||||
an = [1.0, 1.0, 0.5, 1.0/6]
|
||||
|
||||
nump, denomp = pade(an, 0)
|
||||
assert_array_almost_equal(nump.c, [1.0/6, 0.5, 1.0, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0])
|
||||
|
||||
nump, denomp = pade(an, 1)
|
||||
assert_array_almost_equal(nump.c, [1.0/6, 2.0/3, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [-1.0/3, 1.0])
|
||||
|
||||
nump, denomp = pade(an, 2)
|
||||
assert_array_almost_equal(nump.c, [1.0/3, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0/6, -2.0/3, 1.0])
|
||||
|
||||
nump, denomp = pade(an, 3)
|
||||
assert_array_almost_equal(nump.c, [1.0])
|
||||
assert_array_almost_equal(denomp.c, [-1.0/6, 0.5, -1.0, 1.0])
|
||||
|
||||
# Testing inclusion of optional parameter
|
||||
nump, denomp = pade(an, 0, 3)
|
||||
assert_array_almost_equal(nump.c, [1.0/6, 0.5, 1.0, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0])
|
||||
|
||||
nump, denomp = pade(an, 1, 2)
|
||||
assert_array_almost_equal(nump.c, [1.0/6, 2.0/3, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [-1.0/3, 1.0])
|
||||
|
||||
nump, denomp = pade(an, 2, 1)
|
||||
assert_array_almost_equal(nump.c, [1.0/3, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0/6, -2.0/3, 1.0])
|
||||
|
||||
nump, denomp = pade(an, 3, 0)
|
||||
assert_array_almost_equal(nump.c, [1.0])
|
||||
assert_array_almost_equal(denomp.c, [-1.0/6, 0.5, -1.0, 1.0])
|
||||
|
||||
# Testing reducing array
|
||||
nump, denomp = pade(an, 0, 2)
|
||||
assert_array_almost_equal(nump.c, [0.5, 1.0, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0])
|
||||
|
||||
nump, denomp = pade(an, 1, 1)
|
||||
assert_array_almost_equal(nump.c, [1.0/2, 1.0])
|
||||
assert_array_almost_equal(denomp.c, [-1.0/2, 1.0])
|
||||
|
||||
nump, denomp = pade(an, 2, 0)
|
||||
assert_array_almost_equal(nump.c, [1.0])
|
||||
assert_array_almost_equal(denomp.c, [1.0/2, -1.0, 1.0])
|
||||
|
||||
@@ -0,0 +1,664 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
|
||||
from numpy.testing import (
|
||||
assert_almost_equal, assert_array_equal, assert_array_almost_equal,
|
||||
assert_allclose, assert_equal, assert_)
|
||||
from pytest import raises as assert_raises
|
||||
|
||||
from scipy.interpolate import (
|
||||
KroghInterpolator, krogh_interpolate,
|
||||
BarycentricInterpolator, barycentric_interpolate,
|
||||
approximate_taylor_polynomial, pchip, PchipInterpolator,
|
||||
pchip_interpolate, Akima1DInterpolator, CubicSpline, make_interp_spline)
|
||||
|
||||
from scipy._lib.six import xrange
|
||||
|
||||
|
||||
def check_shape(interpolator_cls, x_shape, y_shape, deriv_shape=None, axis=0,
|
||||
extra_args={}):
|
||||
np.random.seed(1234)
|
||||
|
||||
x = [-1, 0, 1, 2, 3, 4]
|
||||
s = list(range(1, len(y_shape)+1))
|
||||
s.insert(axis % (len(y_shape)+1), 0)
|
||||
y = np.random.rand(*((6,) + y_shape)).transpose(s)
|
||||
|
||||
# Cython code chokes on y.shape = (0, 3) etc, skip them
|
||||
if y.size == 0:
|
||||
return
|
||||
|
||||
xi = np.zeros(x_shape)
|
||||
yi = interpolator_cls(x, y, axis=axis, **extra_args)(xi)
|
||||
|
||||
target_shape = ((deriv_shape or ()) + y.shape[:axis]
|
||||
+ x_shape + y.shape[axis:][1:])
|
||||
assert_equal(yi.shape, target_shape)
|
||||
|
||||
# check it works also with lists
|
||||
if x_shape and y.size > 0:
|
||||
interpolator_cls(list(x), list(y), axis=axis, **extra_args)(list(xi))
|
||||
|
||||
# check also values
|
||||
if xi.size > 0 and deriv_shape is None:
|
||||
bs_shape = y.shape[:axis] + (1,)*len(x_shape) + y.shape[axis:][1:]
|
||||
yv = y[((slice(None,),)*(axis % y.ndim)) + (1,)]
|
||||
yv = yv.reshape(bs_shape)
|
||||
|
||||
yi, y = np.broadcast_arrays(yi, yv)
|
||||
assert_allclose(yi, y)
|
||||
|
||||
|
||||
SHAPES = [(), (0,), (1,), (6, 2, 5)]
|
||||
|
||||
|
||||
def test_shapes():
|
||||
|
||||
def spl_interp(x, y, axis):
|
||||
return make_interp_spline(x, y, axis=axis)
|
||||
|
||||
for ip in [KroghInterpolator, BarycentricInterpolator, pchip,
|
||||
Akima1DInterpolator, CubicSpline, spl_interp]:
|
||||
for s1 in SHAPES:
|
||||
for s2 in SHAPES:
|
||||
for axis in range(-len(s2), len(s2)):
|
||||
if ip != CubicSpline:
|
||||
check_shape(ip, s1, s2, None, axis)
|
||||
else:
|
||||
for bc in ['natural', 'clamped']:
|
||||
extra = {'bc_type': bc}
|
||||
check_shape(ip, s1, s2, None, axis, extra)
|
||||
|
||||
def test_derivs_shapes():
|
||||
def krogh_derivs(x, y, axis=0):
|
||||
return KroghInterpolator(x, y, axis).derivatives
|
||||
|
||||
for s1 in SHAPES:
|
||||
for s2 in SHAPES:
|
||||
for axis in range(-len(s2), len(s2)):
|
||||
check_shape(krogh_derivs, s1, s2, (6,), axis)
|
||||
|
||||
|
||||
def test_deriv_shapes():
|
||||
def krogh_deriv(x, y, axis=0):
|
||||
return KroghInterpolator(x, y, axis).derivative
|
||||
|
||||
def pchip_deriv(x, y, axis=0):
|
||||
return pchip(x, y, axis).derivative()
|
||||
|
||||
def pchip_deriv2(x, y, axis=0):
|
||||
return pchip(x, y, axis).derivative(2)
|
||||
|
||||
def pchip_antideriv(x, y, axis=0):
|
||||
return pchip(x, y, axis).derivative()
|
||||
|
||||
def pchip_antideriv2(x, y, axis=0):
|
||||
return pchip(x, y, axis).derivative(2)
|
||||
|
||||
def pchip_deriv_inplace(x, y, axis=0):
|
||||
class P(PchipInterpolator):
|
||||
def __call__(self, x):
|
||||
return PchipInterpolator.__call__(self, x, 1)
|
||||
pass
|
||||
return P(x, y, axis)
|
||||
|
||||
def akima_deriv(x, y, axis=0):
|
||||
return Akima1DInterpolator(x, y, axis).derivative()
|
||||
|
||||
def akima_antideriv(x, y, axis=0):
|
||||
return Akima1DInterpolator(x, y, axis).antiderivative()
|
||||
|
||||
def cspline_deriv(x, y, axis=0):
|
||||
return CubicSpline(x, y, axis).derivative()
|
||||
|
||||
def cspline_antideriv(x, y, axis=0):
|
||||
return CubicSpline(x, y, axis).antiderivative()
|
||||
|
||||
def bspl_deriv(x, y, axis=0):
|
||||
return make_interp_spline(x, y, axis=axis).derivative()
|
||||
|
||||
def bspl_antideriv(x, y, axis=0):
|
||||
return make_interp_spline(x, y, axis=axis).antiderivative()
|
||||
|
||||
for ip in [krogh_deriv, pchip_deriv, pchip_deriv2, pchip_deriv_inplace,
|
||||
pchip_antideriv, pchip_antideriv2, akima_deriv, akima_antideriv,
|
||||
cspline_deriv, cspline_antideriv, bspl_deriv, bspl_antideriv]:
|
||||
for s1 in SHAPES:
|
||||
for s2 in SHAPES:
|
||||
for axis in range(-len(s2), len(s2)):
|
||||
check_shape(ip, s1, s2, (), axis)
|
||||
|
||||
|
||||
def _check_complex(ip):
|
||||
x = [1, 2, 3, 4]
|
||||
y = [1, 2, 1j, 3]
|
||||
p = ip(x, y)
|
||||
assert_allclose(y, p(x))
|
||||
|
||||
|
||||
def test_complex():
|
||||
for ip in [KroghInterpolator, BarycentricInterpolator, pchip, CubicSpline]:
|
||||
_check_complex(ip)
|
||||
|
||||
|
||||
class TestKrogh(object):
|
||||
def setup_method(self):
|
||||
self.true_poly = np.poly1d([-2,3,1,5,-4])
|
||||
self.test_xs = np.linspace(-1,1,100)
|
||||
self.xs = np.linspace(-1,1,5)
|
||||
self.ys = self.true_poly(self.xs)
|
||||
|
||||
def test_lagrange(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
assert_almost_equal(self.true_poly(self.test_xs),P(self.test_xs))
|
||||
|
||||
def test_scalar(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
assert_almost_equal(self.true_poly(7),P(7))
|
||||
assert_almost_equal(self.true_poly(np.array(7)), P(np.array(7)))
|
||||
|
||||
def test_derivatives(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
D = P.derivatives(self.test_xs)
|
||||
for i in xrange(D.shape[0]):
|
||||
assert_almost_equal(self.true_poly.deriv(i)(self.test_xs),
|
||||
D[i])
|
||||
|
||||
def test_low_derivatives(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
D = P.derivatives(self.test_xs,len(self.xs)+2)
|
||||
for i in xrange(D.shape[0]):
|
||||
assert_almost_equal(self.true_poly.deriv(i)(self.test_xs),
|
||||
D[i])
|
||||
|
||||
def test_derivative(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
m = 10
|
||||
r = P.derivatives(self.test_xs,m)
|
||||
for i in xrange(m):
|
||||
assert_almost_equal(P.derivative(self.test_xs,i),r[i])
|
||||
|
||||
def test_high_derivative(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
for i in xrange(len(self.xs),2*len(self.xs)):
|
||||
assert_almost_equal(P.derivative(self.test_xs,i),
|
||||
np.zeros(len(self.test_xs)))
|
||||
|
||||
def test_hermite(self):
|
||||
xs = [0,0,0,1,1,1,2]
|
||||
ys = [self.true_poly(0),
|
||||
self.true_poly.deriv(1)(0),
|
||||
self.true_poly.deriv(2)(0),
|
||||
self.true_poly(1),
|
||||
self.true_poly.deriv(1)(1),
|
||||
self.true_poly.deriv(2)(1),
|
||||
self.true_poly(2)]
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
assert_almost_equal(self.true_poly(self.test_xs),P(self.test_xs))
|
||||
|
||||
def test_vector(self):
|
||||
xs = [0, 1, 2]
|
||||
ys = np.array([[0,1],[1,0],[2,1]])
|
||||
P = KroghInterpolator(xs,ys)
|
||||
Pi = [KroghInterpolator(xs,ys[:,i]) for i in xrange(ys.shape[1])]
|
||||
test_xs = np.linspace(-1,3,100)
|
||||
assert_almost_equal(P(test_xs),
|
||||
np.rollaxis(np.asarray([p(test_xs) for p in Pi]),-1))
|
||||
assert_almost_equal(P.derivatives(test_xs),
|
||||
np.transpose(np.asarray([p.derivatives(test_xs) for p in Pi]),
|
||||
(1,2,0)))
|
||||
|
||||
def test_empty(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
assert_array_equal(P([]), [])
|
||||
|
||||
def test_shapes_scalarvalue(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
assert_array_equal(np.shape(P(0)), ())
|
||||
assert_array_equal(np.shape(P(np.array(0))), ())
|
||||
assert_array_equal(np.shape(P([0])), (1,))
|
||||
assert_array_equal(np.shape(P([0,1])), (2,))
|
||||
|
||||
def test_shapes_scalarvalue_derivative(self):
|
||||
P = KroghInterpolator(self.xs,self.ys)
|
||||
n = P.n
|
||||
assert_array_equal(np.shape(P.derivatives(0)), (n,))
|
||||
assert_array_equal(np.shape(P.derivatives(np.array(0))), (n,))
|
||||
assert_array_equal(np.shape(P.derivatives([0])), (n,1))
|
||||
assert_array_equal(np.shape(P.derivatives([0,1])), (n,2))
|
||||
|
||||
def test_shapes_vectorvalue(self):
|
||||
P = KroghInterpolator(self.xs,np.outer(self.ys,np.arange(3)))
|
||||
assert_array_equal(np.shape(P(0)), (3,))
|
||||
assert_array_equal(np.shape(P([0])), (1,3))
|
||||
assert_array_equal(np.shape(P([0,1])), (2,3))
|
||||
|
||||
def test_shapes_1d_vectorvalue(self):
|
||||
P = KroghInterpolator(self.xs,np.outer(self.ys,[1]))
|
||||
assert_array_equal(np.shape(P(0)), (1,))
|
||||
assert_array_equal(np.shape(P([0])), (1,1))
|
||||
assert_array_equal(np.shape(P([0,1])), (2,1))
|
||||
|
||||
def test_shapes_vectorvalue_derivative(self):
|
||||
P = KroghInterpolator(self.xs,np.outer(self.ys,np.arange(3)))
|
||||
n = P.n
|
||||
assert_array_equal(np.shape(P.derivatives(0)), (n,3))
|
||||
assert_array_equal(np.shape(P.derivatives([0])), (n,1,3))
|
||||
assert_array_equal(np.shape(P.derivatives([0,1])), (n,2,3))
|
||||
|
||||
def test_wrapper(self):
|
||||
P = KroghInterpolator(self.xs, self.ys)
|
||||
ki = krogh_interpolate
|
||||
assert_almost_equal(P(self.test_xs), ki(self.xs, self.ys, self.test_xs))
|
||||
assert_almost_equal(P.derivative(self.test_xs, 2),
|
||||
ki(self.xs, self.ys, self.test_xs, der=2))
|
||||
assert_almost_equal(P.derivatives(self.test_xs, 2),
|
||||
ki(self.xs, self.ys, self.test_xs, der=[0, 1]))
|
||||
|
||||
def test_int_inputs(self):
|
||||
# Check input args are cast correctly to floats, gh-3669
|
||||
x = [0, 234, 468, 702, 936, 1170, 1404, 2340, 3744, 6084, 8424,
|
||||
13104, 60000]
|
||||
offset_cdf = np.array([-0.95, -0.86114777, -0.8147762, -0.64072425,
|
||||
-0.48002351, -0.34925329, -0.26503107,
|
||||
-0.13148093, -0.12988833, -0.12979296,
|
||||
-0.12973574, -0.08582937, 0.05])
|
||||
f = KroghInterpolator(x, offset_cdf)
|
||||
|
||||
assert_allclose(abs((f(x) - offset_cdf) / f.derivative(x, 1)),
|
||||
0, atol=1e-10)
|
||||
|
||||
def test_derivatives_complex(self):
|
||||
# regression test for gh-7381: krogh.derivatives(0) fails complex y
|
||||
x, y = np.array([-1, -1, 0, 1, 1]), np.array([1, 1.0j, 0, -1, 1.0j])
|
||||
func = KroghInterpolator(x, y)
|
||||
cmplx = func.derivatives(0)
|
||||
|
||||
cmplx2 = (KroghInterpolator(x, y.real).derivatives(0) +
|
||||
1j*KroghInterpolator(x, y.imag).derivatives(0))
|
||||
assert_allclose(cmplx, cmplx2, atol=1e-15)
|
||||
|
||||
|
||||
class TestTaylor(object):
|
||||
def test_exponential(self):
|
||||
degree = 5
|
||||
p = approximate_taylor_polynomial(np.exp, 0, degree, 1, 15)
|
||||
for i in xrange(degree+1):
|
||||
assert_almost_equal(p(0),1)
|
||||
p = p.deriv()
|
||||
assert_almost_equal(p(0),0)
|
||||
|
||||
|
||||
class TestBarycentric(object):
|
||||
def setup_method(self):
|
||||
self.true_poly = np.poly1d([-2, 3, 1, 5, -4])
|
||||
self.test_xs = np.linspace(-1, 1, 100)
|
||||
self.xs = np.linspace(-1, 1, 5)
|
||||
self.ys = self.true_poly(self.xs)
|
||||
|
||||
def test_lagrange(self):
|
||||
P = BarycentricInterpolator(self.xs, self.ys)
|
||||
assert_almost_equal(self.true_poly(self.test_xs), P(self.test_xs))
|
||||
|
||||
def test_scalar(self):
|
||||
P = BarycentricInterpolator(self.xs, self.ys)
|
||||
assert_almost_equal(self.true_poly(7), P(7))
|
||||
assert_almost_equal(self.true_poly(np.array(7)), P(np.array(7)))
|
||||
|
||||
def test_delayed(self):
|
||||
P = BarycentricInterpolator(self.xs)
|
||||
P.set_yi(self.ys)
|
||||
assert_almost_equal(self.true_poly(self.test_xs), P(self.test_xs))
|
||||
|
||||
def test_append(self):
|
||||
P = BarycentricInterpolator(self.xs[:3], self.ys[:3])
|
||||
P.add_xi(self.xs[3:], self.ys[3:])
|
||||
assert_almost_equal(self.true_poly(self.test_xs), P(self.test_xs))
|
||||
|
||||
def test_vector(self):
|
||||
xs = [0, 1, 2]
|
||||
ys = np.array([[0, 1], [1, 0], [2, 1]])
|
||||
BI = BarycentricInterpolator
|
||||
P = BI(xs, ys)
|
||||
Pi = [BI(xs, ys[:, i]) for i in xrange(ys.shape[1])]
|
||||
test_xs = np.linspace(-1, 3, 100)
|
||||
assert_almost_equal(P(test_xs),
|
||||
np.rollaxis(np.asarray([p(test_xs) for p in Pi]), -1))
|
||||
|
||||
def test_shapes_scalarvalue(self):
|
||||
P = BarycentricInterpolator(self.xs, self.ys)
|
||||
assert_array_equal(np.shape(P(0)), ())
|
||||
assert_array_equal(np.shape(P(np.array(0))), ())
|
||||
assert_array_equal(np.shape(P([0])), (1,))
|
||||
assert_array_equal(np.shape(P([0, 1])), (2,))
|
||||
|
||||
def test_shapes_vectorvalue(self):
|
||||
P = BarycentricInterpolator(self.xs, np.outer(self.ys, np.arange(3)))
|
||||
assert_array_equal(np.shape(P(0)), (3,))
|
||||
assert_array_equal(np.shape(P([0])), (1, 3))
|
||||
assert_array_equal(np.shape(P([0, 1])), (2, 3))
|
||||
|
||||
def test_shapes_1d_vectorvalue(self):
|
||||
P = BarycentricInterpolator(self.xs, np.outer(self.ys, [1]))
|
||||
assert_array_equal(np.shape(P(0)), (1,))
|
||||
assert_array_equal(np.shape(P([0])), (1, 1))
|
||||
assert_array_equal(np.shape(P([0,1])), (2, 1))
|
||||
|
||||
def test_wrapper(self):
|
||||
P = BarycentricInterpolator(self.xs, self.ys)
|
||||
values = barycentric_interpolate(self.xs, self.ys, self.test_xs)
|
||||
assert_almost_equal(P(self.test_xs), values)
|
||||
|
||||
|
||||
class TestPCHIP(object):
|
||||
def _make_random(self, npts=20):
|
||||
np.random.seed(1234)
|
||||
xi = np.sort(np.random.random(npts))
|
||||
yi = np.random.random(npts)
|
||||
return pchip(xi, yi), xi, yi
|
||||
|
||||
def test_overshoot(self):
|
||||
# PCHIP should not overshoot
|
||||
p, xi, yi = self._make_random()
|
||||
for i in range(len(xi)-1):
|
||||
x1, x2 = xi[i], xi[i+1]
|
||||
y1, y2 = yi[i], yi[i+1]
|
||||
if y1 > y2:
|
||||
y1, y2 = y2, y1
|
||||
xp = np.linspace(x1, x2, 10)
|
||||
yp = p(xp)
|
||||
assert_(((y1 <= yp) & (yp <= y2)).all())
|
||||
|
||||
def test_monotone(self):
|
||||
# PCHIP should preserve monotonicty
|
||||
p, xi, yi = self._make_random()
|
||||
for i in range(len(xi)-1):
|
||||
x1, x2 = xi[i], xi[i+1]
|
||||
y1, y2 = yi[i], yi[i+1]
|
||||
xp = np.linspace(x1, x2, 10)
|
||||
yp = p(xp)
|
||||
assert_(((y2-y1) * (yp[1:] - yp[:1]) > 0).all())
|
||||
|
||||
def test_cast(self):
|
||||
# regression test for integer input data, see gh-3453
|
||||
data = np.array([[0, 4, 12, 27, 47, 60, 79, 87, 99, 100],
|
||||
[-33, -33, -19, -2, 12, 26, 38, 45, 53, 55]])
|
||||
xx = np.arange(100)
|
||||
curve = pchip(data[0], data[1])(xx)
|
||||
|
||||
data1 = data * 1.0
|
||||
curve1 = pchip(data1[0], data1[1])(xx)
|
||||
|
||||
assert_allclose(curve, curve1, atol=1e-14, rtol=1e-14)
|
||||
|
||||
def test_nag(self):
|
||||
# Example from NAG C implementation,
|
||||
# http://nag.com/numeric/cl/nagdoc_cl25/html/e01/e01bec.html
|
||||
# suggested in gh-5326 as a smoke test for the way the derivatives
|
||||
# are computed (see also gh-3453)
|
||||
from scipy._lib.six import StringIO
|
||||
dataStr = '''
|
||||
7.99 0.00000E+0
|
||||
8.09 0.27643E-4
|
||||
8.19 0.43750E-1
|
||||
8.70 0.16918E+0
|
||||
9.20 0.46943E+0
|
||||
10.00 0.94374E+0
|
||||
12.00 0.99864E+0
|
||||
15.00 0.99992E+0
|
||||
20.00 0.99999E+0
|
||||
'''
|
||||
data = np.loadtxt(StringIO(dataStr))
|
||||
pch = pchip(data[:,0], data[:,1])
|
||||
|
||||
resultStr = '''
|
||||
7.9900 0.0000
|
||||
9.1910 0.4640
|
||||
10.3920 0.9645
|
||||
11.5930 0.9965
|
||||
12.7940 0.9992
|
||||
13.9950 0.9998
|
||||
15.1960 0.9999
|
||||
16.3970 1.0000
|
||||
17.5980 1.0000
|
||||
18.7990 1.0000
|
||||
20.0000 1.0000
|
||||
'''
|
||||
result = np.loadtxt(StringIO(resultStr))
|
||||
assert_allclose(result[:,1], pch(result[:,0]), rtol=0., atol=5e-5)
|
||||
|
||||
def test_endslopes(self):
|
||||
# this is a smoke test for gh-3453: PCHIP interpolator should not
|
||||
# set edge slopes to zero if the data do not suggest zero edge derivatives
|
||||
x = np.array([0.0, 0.1, 0.25, 0.35])
|
||||
y1 = np.array([279.35, 0.5e3, 1.0e3, 2.5e3])
|
||||
y2 = np.array([279.35, 2.5e3, 1.50e3, 1.0e3])
|
||||
for pp in (pchip(x, y1), pchip(x, y2)):
|
||||
for t in (x[0], x[-1]):
|
||||
assert_(pp(t, 1) != 0)
|
||||
|
||||
def test_all_zeros(self):
|
||||
x = np.arange(10)
|
||||
y = np.zeros_like(x)
|
||||
|
||||
# this should work and not generate any warnings
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('error')
|
||||
pch = pchip(x, y)
|
||||
|
||||
xx = np.linspace(0, 9, 101)
|
||||
assert_equal(pch(xx), 0.)
|
||||
|
||||
def test_two_points(self):
|
||||
# regression test for gh-6222: pchip([0, 1], [0, 1]) fails because
|
||||
# it tries to use a three-point scheme to estimate edge derivatives,
|
||||
# while there are only two points available.
|
||||
# Instead, it should construct a linear interpolator.
|
||||
x = np.linspace(0, 1, 11)
|
||||
p = pchip([0, 1], [0, 2])
|
||||
assert_allclose(p(x), 2*x, atol=1e-15)
|
||||
|
||||
def test_pchip_interpolate(self):
|
||||
assert_array_almost_equal(
|
||||
pchip_interpolate([1,2,3], [4,5,6], [0.5], der=1),
|
||||
[1.])
|
||||
|
||||
assert_array_almost_equal(
|
||||
pchip_interpolate([1,2,3], [4,5,6], [0.5], der=0),
|
||||
[3.5])
|
||||
|
||||
assert_array_almost_equal(
|
||||
pchip_interpolate([1,2,3], [4,5,6], [0.5], der=[0, 1]),
|
||||
[[3.5], [1]])
|
||||
|
||||
def test_roots(self):
|
||||
# regression test for gh-6357: .roots method should work
|
||||
p = pchip([0, 1], [-1, 1])
|
||||
r = p.roots()
|
||||
assert_allclose(r, 0.5)
|
||||
|
||||
class TestCubicSpline(object):
|
||||
@staticmethod
|
||||
def check_correctness(S, bc_start='not-a-knot', bc_end='not-a-knot',
|
||||
tol=1e-14):
|
||||
"""Check that spline coefficients satisfy the continuity and boundary
|
||||
conditions."""
|
||||
x = S.x
|
||||
c = S.c
|
||||
dx = np.diff(x)
|
||||
dx = dx.reshape([dx.shape[0]] + [1] * (c.ndim - 2))
|
||||
dxi = dx[:-1]
|
||||
|
||||
# Check C2 continuity.
|
||||
assert_allclose(c[3, 1:], c[0, :-1] * dxi**3 + c[1, :-1] * dxi**2 +
|
||||
c[2, :-1] * dxi + c[3, :-1], rtol=tol, atol=tol)
|
||||
assert_allclose(c[2, 1:], 3 * c[0, :-1] * dxi**2 +
|
||||
2 * c[1, :-1] * dxi + c[2, :-1], rtol=tol, atol=tol)
|
||||
assert_allclose(c[1, 1:], 3 * c[0, :-1] * dxi + c[1, :-1],
|
||||
rtol=tol, atol=tol)
|
||||
|
||||
# Check that we found a parabola, the third derivative is 0.
|
||||
if x.size == 3 and bc_start == 'not-a-knot' and bc_end == 'not-a-knot':
|
||||
assert_allclose(c[0], 0, rtol=tol, atol=tol)
|
||||
return
|
||||
|
||||
# Check periodic boundary conditions.
|
||||
if bc_start == 'periodic':
|
||||
assert_allclose(S(x[0], 0), S(x[-1], 0), rtol=tol, atol=tol)
|
||||
assert_allclose(S(x[0], 1), S(x[-1], 1), rtol=tol, atol=tol)
|
||||
assert_allclose(S(x[0], 2), S(x[-1], 2), rtol=tol, atol=tol)
|
||||
return
|
||||
|
||||
# Check other boundary conditions.
|
||||
if bc_start == 'not-a-knot':
|
||||
if x.size == 2:
|
||||
slope = (S(x[1]) - S(x[0])) / dx[0]
|
||||
assert_allclose(S(x[0], 1), slope, rtol=tol, atol=tol)
|
||||
else:
|
||||
assert_allclose(c[0, 0], c[0, 1], rtol=tol, atol=tol)
|
||||
elif bc_start == 'clamped':
|
||||
assert_allclose(S(x[0], 1), 0, rtol=tol, atol=tol)
|
||||
elif bc_start == 'natural':
|
||||
assert_allclose(S(x[0], 2), 0, rtol=tol, atol=tol)
|
||||
else:
|
||||
order, value = bc_start
|
||||
assert_allclose(S(x[0], order), value, rtol=tol, atol=tol)
|
||||
|
||||
if bc_end == 'not-a-knot':
|
||||
if x.size == 2:
|
||||
slope = (S(x[1]) - S(x[0])) / dx[0]
|
||||
assert_allclose(S(x[1], 1), slope, rtol=tol, atol=tol)
|
||||
else:
|
||||
assert_allclose(c[0, -1], c[0, -2], rtol=tol, atol=tol)
|
||||
elif bc_end == 'clamped':
|
||||
assert_allclose(S(x[-1], 1), 0, rtol=tol, atol=tol)
|
||||
elif bc_end == 'natural':
|
||||
assert_allclose(S(x[-1], 2), 0, rtol=2*tol, atol=2*tol)
|
||||
else:
|
||||
order, value = bc_end
|
||||
assert_allclose(S(x[-1], order), value, rtol=tol, atol=tol)
|
||||
|
||||
def check_all_bc(self, x, y, axis):
|
||||
deriv_shape = list(y.shape)
|
||||
del deriv_shape[axis]
|
||||
first_deriv = np.empty(deriv_shape)
|
||||
first_deriv.fill(2)
|
||||
second_deriv = np.empty(deriv_shape)
|
||||
second_deriv.fill(-1)
|
||||
bc_all = [
|
||||
'not-a-knot',
|
||||
'natural',
|
||||
'clamped',
|
||||
(1, first_deriv),
|
||||
(2, second_deriv)
|
||||
]
|
||||
for bc in bc_all[:3]:
|
||||
S = CubicSpline(x, y, axis=axis, bc_type=bc)
|
||||
self.check_correctness(S, bc, bc)
|
||||
|
||||
for bc_start in bc_all:
|
||||
for bc_end in bc_all:
|
||||
S = CubicSpline(x, y, axis=axis, bc_type=(bc_start, bc_end))
|
||||
self.check_correctness(S, bc_start, bc_end, tol=2e-14)
|
||||
|
||||
def test_general(self):
|
||||
x = np.array([-1, 0, 0.5, 2, 4, 4.5, 5.5, 9])
|
||||
y = np.array([0, -0.5, 2, 3, 2.5, 1, 1, 0.5])
|
||||
for n in [2, 3, x.size]:
|
||||
self.check_all_bc(x[:n], y[:n], 0)
|
||||
|
||||
Y = np.empty((2, n, 2))
|
||||
Y[0, :, 0] = y[:n]
|
||||
Y[0, :, 1] = y[:n] - 1
|
||||
Y[1, :, 0] = y[:n] + 2
|
||||
Y[1, :, 1] = y[:n] + 3
|
||||
self.check_all_bc(x[:n], Y, 1)
|
||||
|
||||
def test_periodic(self):
|
||||
for n in [2, 3, 5]:
|
||||
x = np.linspace(0, 2 * np.pi, n)
|
||||
y = np.cos(x)
|
||||
S = CubicSpline(x, y, bc_type='periodic')
|
||||
self.check_correctness(S, 'periodic', 'periodic')
|
||||
|
||||
Y = np.empty((2, n, 2))
|
||||
Y[0, :, 0] = y
|
||||
Y[0, :, 1] = y + 2
|
||||
Y[1, :, 0] = y - 1
|
||||
Y[1, :, 1] = y + 5
|
||||
S = CubicSpline(x, Y, axis=1, bc_type='periodic')
|
||||
self.check_correctness(S, 'periodic', 'periodic')
|
||||
|
||||
def test_periodic_eval(self):
|
||||
x = np.linspace(0, 2 * np.pi, 10)
|
||||
y = np.cos(x)
|
||||
S = CubicSpline(x, y, bc_type='periodic')
|
||||
assert_almost_equal(S(1), S(1 + 2 * np.pi), decimal=15)
|
||||
|
||||
def test_dtypes(self):
|
||||
x = np.array([0, 1, 2, 3], dtype=int)
|
||||
y = np.array([-5, 2, 3, 1], dtype=int)
|
||||
S = CubicSpline(x, y)
|
||||
self.check_correctness(S)
|
||||
|
||||
y = np.array([-1+1j, 0.0, 1-1j, 0.5-1.5j])
|
||||
S = CubicSpline(x, y)
|
||||
self.check_correctness(S)
|
||||
|
||||
S = CubicSpline(x, x ** 3, bc_type=("natural", (1, 2j)))
|
||||
self.check_correctness(S, "natural", (1, 2j))
|
||||
|
||||
y = np.array([-5, 2, 3, 1])
|
||||
S = CubicSpline(x, y, bc_type=[(1, 2 + 0.5j), (2, 0.5 - 1j)])
|
||||
self.check_correctness(S, (1, 2 + 0.5j), (2, 0.5 - 1j))
|
||||
|
||||
def test_small_dx(self):
|
||||
rng = np.random.RandomState(0)
|
||||
x = np.sort(rng.uniform(size=100))
|
||||
y = 1e4 + rng.uniform(size=100)
|
||||
S = CubicSpline(x, y)
|
||||
self.check_correctness(S, tol=1e-13)
|
||||
|
||||
def test_incorrect_inputs(self):
|
||||
x = np.array([1, 2, 3, 4])
|
||||
y = np.array([1, 2, 3, 4])
|
||||
xc = np.array([1 + 1j, 2, 3, 4])
|
||||
xn = np.array([np.nan, 2, 3, 4])
|
||||
xo = np.array([2, 1, 3, 4])
|
||||
yn = np.array([np.nan, 2, 3, 4])
|
||||
y3 = [1, 2, 3]
|
||||
x1 = [1]
|
||||
y1 = [1]
|
||||
|
||||
assert_raises(ValueError, CubicSpline, xc, y)
|
||||
assert_raises(ValueError, CubicSpline, xn, y)
|
||||
assert_raises(ValueError, CubicSpline, x, yn)
|
||||
assert_raises(ValueError, CubicSpline, xo, y)
|
||||
assert_raises(ValueError, CubicSpline, x, y3)
|
||||
assert_raises(ValueError, CubicSpline, x[:, np.newaxis], y)
|
||||
assert_raises(ValueError, CubicSpline, x1, y1)
|
||||
|
||||
wrong_bc = [('periodic', 'clamped'),
|
||||
((2, 0), (3, 10)),
|
||||
((1, 0), ),
|
||||
(0., 0.),
|
||||
'not-a-typo']
|
||||
|
||||
for bc_type in wrong_bc:
|
||||
assert_raises(ValueError, CubicSpline, x, y, 0, bc_type, True)
|
||||
|
||||
# Shapes mismatch when giving arbitrary derivative values:
|
||||
Y = np.c_[y, y]
|
||||
bc1 = ('clamped', (1, 0))
|
||||
bc2 = ('clamped', (1, [0, 0, 0]))
|
||||
bc3 = ('clamped', (1, [[0, 0]]))
|
||||
assert_raises(ValueError, CubicSpline, x, Y, 0, bc1, True)
|
||||
assert_raises(ValueError, CubicSpline, x, Y, 0, bc2, True)
|
||||
assert_raises(ValueError, CubicSpline, x, Y, 0, bc3, True)
|
||||
|
||||
# periodic condition, y[-1] must be equal to y[0]:
|
||||
assert_raises(ValueError, CubicSpline, x, y, 0, 'periodic', True)
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
# Created by John Travers, Robert Hetland, 2007
|
||||
""" Test functions for rbf module """
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import (assert_, assert_array_almost_equal,
|
||||
assert_almost_equal)
|
||||
from numpy import linspace, sin, random, exp, allclose
|
||||
from scipy.interpolate.rbf import Rbf
|
||||
|
||||
FUNCTIONS = ('multiquadric', 'inverse multiquadric', 'gaussian',
|
||||
'cubic', 'quintic', 'thin-plate', 'linear')
|
||||
|
||||
|
||||
def check_rbf1d_interpolation(function):
|
||||
# Check that the Rbf function interpolates through the nodes (1D)
|
||||
x = linspace(0,10,9)
|
||||
y = sin(x)
|
||||
rbf = Rbf(x, y, function=function)
|
||||
yi = rbf(x)
|
||||
assert_array_almost_equal(y, yi)
|
||||
assert_almost_equal(rbf(float(x[0])), y[0])
|
||||
|
||||
|
||||
def check_rbf2d_interpolation(function):
|
||||
# Check that the Rbf function interpolates through the nodes (2D).
|
||||
x = random.rand(50,1)*4-2
|
||||
y = random.rand(50,1)*4-2
|
||||
z = x*exp(-x**2-1j*y**2)
|
||||
rbf = Rbf(x, y, z, epsilon=2, function=function)
|
||||
zi = rbf(x, y)
|
||||
zi.shape = x.shape
|
||||
assert_array_almost_equal(z, zi)
|
||||
|
||||
|
||||
def check_rbf3d_interpolation(function):
|
||||
# Check that the Rbf function interpolates through the nodes (3D).
|
||||
x = random.rand(50, 1)*4 - 2
|
||||
y = random.rand(50, 1)*4 - 2
|
||||
z = random.rand(50, 1)*4 - 2
|
||||
d = x*exp(-x**2 - y**2)
|
||||
rbf = Rbf(x, y, z, d, epsilon=2, function=function)
|
||||
di = rbf(x, y, z)
|
||||
di.shape = x.shape
|
||||
assert_array_almost_equal(di, d)
|
||||
|
||||
|
||||
def test_rbf_interpolation():
|
||||
for function in FUNCTIONS:
|
||||
check_rbf1d_interpolation(function)
|
||||
check_rbf2d_interpolation(function)
|
||||
check_rbf3d_interpolation(function)
|
||||
|
||||
|
||||
def check_rbf1d_regularity(function, atol):
|
||||
# Check that the Rbf function approximates a smooth function well away
|
||||
# from the nodes.
|
||||
x = linspace(0, 10, 9)
|
||||
y = sin(x)
|
||||
rbf = Rbf(x, y, function=function)
|
||||
xi = linspace(0, 10, 100)
|
||||
yi = rbf(xi)
|
||||
# import matplotlib.pyplot as plt
|
||||
# plt.figure()
|
||||
# plt.plot(x, y, 'o', xi, sin(xi), ':', xi, yi, '-')
|
||||
# plt.plot(x, y, 'o', xi, yi-sin(xi), ':')
|
||||
# plt.title(function)
|
||||
# plt.show()
|
||||
msg = "abs-diff: %f" % abs(yi - sin(xi)).max()
|
||||
assert_(allclose(yi, sin(xi), atol=atol), msg)
|
||||
|
||||
|
||||
def test_rbf_regularity():
|
||||
tolerances = {
|
||||
'multiquadric': 0.1,
|
||||
'inverse multiquadric': 0.15,
|
||||
'gaussian': 0.15,
|
||||
'cubic': 0.15,
|
||||
'quintic': 0.1,
|
||||
'thin-plate': 0.1,
|
||||
'linear': 0.2
|
||||
}
|
||||
for function in FUNCTIONS:
|
||||
check_rbf1d_regularity(function, tolerances.get(function, 1e-2))
|
||||
|
||||
|
||||
def check_rbf1d_stability(function):
|
||||
# Check that the Rbf function with default epsilon is not subject
|
||||
# to overshoot. Regression for issue #4523.
|
||||
#
|
||||
# Generate some data (fixed random seed hence deterministic)
|
||||
np.random.seed(1234)
|
||||
x = np.linspace(0, 10, 50)
|
||||
z = x + 4.0 * np.random.randn(len(x))
|
||||
|
||||
rbf = Rbf(x, z, function=function)
|
||||
xi = np.linspace(0, 10, 1000)
|
||||
yi = rbf(xi)
|
||||
|
||||
# subtract the linear trend and make sure there no spikes
|
||||
assert_(np.abs(yi-xi).max() / np.abs(z-x).max() < 1.1)
|
||||
|
||||
def test_rbf_stability():
|
||||
for function in FUNCTIONS:
|
||||
check_rbf1d_stability(function)
|
||||
|
||||
|
||||
def test_default_construction():
|
||||
# Check that the Rbf class can be constructed with the default
|
||||
# multiquadric basis function. Regression test for ticket #1228.
|
||||
x = linspace(0,10,9)
|
||||
y = sin(x)
|
||||
rbf = Rbf(x, y)
|
||||
yi = rbf(x)
|
||||
assert_array_almost_equal(y, yi)
|
||||
|
||||
|
||||
def test_function_is_callable():
|
||||
# Check that the Rbf class can be constructed with function=callable.
|
||||
x = linspace(0,10,9)
|
||||
y = sin(x)
|
||||
linfunc = lambda x:x
|
||||
rbf = Rbf(x, y, function=linfunc)
|
||||
yi = rbf(x)
|
||||
assert_array_almost_equal(y, yi)
|
||||
|
||||
|
||||
def test_two_arg_function_is_callable():
|
||||
# Check that the Rbf class can be constructed with a two argument
|
||||
# function=callable.
|
||||
def _func(self, r):
|
||||
return self.epsilon + r
|
||||
|
||||
x = linspace(0,10,9)
|
||||
y = sin(x)
|
||||
rbf = Rbf(x, y, function=_func)
|
||||
yi = rbf(x)
|
||||
assert_array_almost_equal(y, yi)
|
||||
|
||||
|
||||
def test_rbf_epsilon_none():
|
||||
x = linspace(0, 10, 9)
|
||||
y = sin(x)
|
||||
rbf = Rbf(x, y, epsilon=None)
|
||||
|
||||
|
||||
def test_rbf_epsilon_none_collinear():
|
||||
# Check that collinear points in one dimension doesn't cause an error
|
||||
# due to epsilon = 0
|
||||
x = [1, 2, 3]
|
||||
y = [4, 4, 4]
|
||||
z = [5, 6, 7]
|
||||
rbf = Rbf(x, y, z, epsilon=None)
|
||||
assert_(rbf.epsilon > 0)
|
||||
@@ -0,0 +1,16 @@
|
||||
from __future__ import division, print_function, absolute_import
|
||||
|
||||
import numpy as np
|
||||
import scipy.interpolate as interp
|
||||
from numpy.testing import assert_almost_equal
|
||||
|
||||
|
||||
class TestRegression(object):
|
||||
def test_spalde_scalar_input(self):
|
||||
"""Ticket #629"""
|
||||
x = np.linspace(0,10)
|
||||
y = x**3
|
||||
tck = interp.splrep(x, y, k=3, t=[5])
|
||||
res = interp.spalde(np.float64(1), tck)
|
||||
des = np.array([1., 3., 6., 6.])
|
||||
assert_almost_equal(res, des)
|
||||
Reference in New Issue
Block a user