123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- # 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)
|