/Python27/Lib/site-packages/scipy/interpolate/tests/test_interpnd.py

https://github.com/mantidproject/3rdpartylibs-win64
Python | 216 lines | 152 code | 47 blank | 17 comment | 12 complexity | 979c4264ba108696cf02498b3957780c MD5 | raw file
  1. import numpy as np
  2. from numpy.testing import assert_equal, assert_allclose, assert_almost_equal, \
  3. run_module_suite, assert_raises
  4. import scipy.interpolate.interpnd as interpnd
  5. import scipy.spatial.qhull as qhull
  6. import pickle
  7. class TestLinearNDInterpolation(object):
  8. def test_smoketest(self):
  9. # Test at single points
  10. x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
  11. dtype=np.double)
  12. y = np.arange(x.shape[0], dtype=np.double)
  13. yi = interpnd.LinearNDInterpolator(x, y)(x)
  14. assert_almost_equal(y, yi)
  15. def test_smoketest_alternate(self):
  16. # Test at single points, alternate calling convention
  17. x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
  18. dtype=np.double)
  19. y = np.arange(x.shape[0], dtype=np.double)
  20. yi = interpnd.LinearNDInterpolator((x[:,0], x[:,1]), y)(x[:,0], x[:,1])
  21. assert_almost_equal(y, yi)
  22. def test_complex_smoketest(self):
  23. # Test at single points
  24. x = np.array([(0,0), (-0.5,-0.5), (-0.5,0.5), (0.5, 0.5), (0.25, 0.3)],
  25. dtype=np.double)
  26. y = np.arange(x.shape[0], dtype=np.double)
  27. y = y - 3j*y
  28. yi = interpnd.LinearNDInterpolator(x, y)(x)
  29. assert_almost_equal(y, yi)
  30. def test_square(self):
  31. # Test barycentric interpolation on a square against a manual
  32. # implementation
  33. points = np.array([(0,0), (0,1), (1,1), (1,0)], dtype=np.double)
  34. values = np.array([1., 2., -3., 5.], dtype=np.double)
  35. # NB: assume triangles (0, 1, 3) and (1, 2, 3)
  36. #
  37. # 1----2
  38. # | \ |
  39. # | \ |
  40. # 0----3
  41. def ip(x, y):
  42. t1 = (x + y <= 1)
  43. t2 = ~t1
  44. x1 = x[t1]
  45. y1 = y[t1]
  46. x2 = x[t2]
  47. y2 = y[t2]
  48. z = 0*x
  49. z[t1] = (values[0]*(1 - x1 - y1)
  50. + values[1]*y1
  51. + values[3]*x1)
  52. z[t2] = (values[2]*(x2 + y2 - 1)
  53. + values[1]*(1 - x2)
  54. + values[3]*(1 - y2))
  55. return z
  56. xx, yy = np.broadcast_arrays(np.linspace(0, 1, 14)[:,None],
  57. np.linspace(0, 1, 14)[None,:])
  58. xx = xx.ravel()
  59. yy = yy.ravel()
  60. xi = np.array([xx, yy]).T.copy()
  61. zi = interpnd.LinearNDInterpolator(points, values)(xi)
  62. assert_almost_equal(zi, ip(xx, yy))
  63. def test_pickle(self):
  64. # Test at single points
  65. np.random.seed(1234)
  66. x = np.random.rand(30, 2)
  67. y = np.random.rand(30) + 1j*np.random.rand(30)
  68. ip = interpnd.LinearNDInterpolator(x, y)
  69. ip2 = pickle.loads(pickle.dumps(ip))
  70. assert_almost_equal(ip(0.5, 0.5), ip2(0.5, 0.5))
  71. class TestEstimateGradients2DGlobal(object):
  72. def test_smoketest(self):
  73. x = np.array([(0, 0), (0, 2),
  74. (1, 0), (1, 2), (0.25, 0.75), (0.6, 0.8)], dtype=float)
  75. tri = qhull.Delaunay(x)
  76. # Should be exact for linear functions, independent of triangulation
  77. funcs = [
  78. (lambda x, y: 0*x + 1, (0, 0)),
  79. (lambda x, y: 0 + x, (1, 0)),
  80. (lambda x, y: -2 + y, (0, 1)),
  81. (lambda x, y: 3 + 3*x + 14.15*y, (3, 14.15))
  82. ]
  83. for j, (func, grad) in enumerate(funcs):
  84. z = func(x[:,0], x[:,1])
  85. dz = interpnd.estimate_gradients_2d_global(tri, z, tol=1e-6)
  86. assert_equal(dz.shape, (6, 2))
  87. assert_allclose(dz, np.array(grad)[None,:] + 0*dz,
  88. rtol=1e-5, atol=1e-5, err_msg="item %d" % j)
  89. class TestCloughTocher2DInterpolator(object):
  90. def _check_accuracy(self, func, x=None, tol=1e-6, alternate=False, **kw):
  91. np.random.seed(1234)
  92. if x is None:
  93. x = np.array([(0, 0), (0, 1),
  94. (1, 0), (1, 1), (0.25, 0.75), (0.6, 0.8),
  95. (0.5, 0.2)],
  96. dtype=float)
  97. if not alternate:
  98. ip = interpnd.CloughTocher2DInterpolator(x, func(x[:,0], x[:,1]),
  99. tol=1e-6)
  100. else:
  101. ip = interpnd.CloughTocher2DInterpolator((x[:,0], x[:,1]),
  102. func(x[:,0], x[:,1]),
  103. tol=1e-6)
  104. p = np.random.rand(50, 2)
  105. if not alternate:
  106. a = ip(p)
  107. else:
  108. a = ip(p[:,0], p[:,1])
  109. b = func(p[:,0], p[:,1])
  110. try:
  111. assert_allclose(a, b, **kw)
  112. except AssertionError:
  113. print abs(a - b)
  114. print ip.grad
  115. raise
  116. def test_linear_smoketest(self):
  117. # Should be exact for linear functions, independent of triangulation
  118. funcs = [
  119. lambda x, y: 0*x + 1,
  120. lambda x, y: 0 + x,
  121. lambda x, y: -2 + y,
  122. lambda x, y: 3 + 3*x + 14.15*y,
  123. ]
  124. for j, func in enumerate(funcs):
  125. self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
  126. err_msg="Function %d" % j)
  127. self._check_accuracy(func, tol=1e-13, atol=1e-7, rtol=1e-7,
  128. alternate=True,
  129. err_msg="Function (alternate) %d" % j)
  130. def test_quadratic_smoketest(self):
  131. # Should be reasonably accurate for quadratic functions
  132. funcs = [
  133. lambda x, y: x**2,
  134. lambda x, y: y**2,
  135. lambda x, y: x**2 - y**2,
  136. lambda x, y: x*y,
  137. ]
  138. for j, func in enumerate(funcs):
  139. self._check_accuracy(func, tol=1e-9, atol=0.22, rtol=0,
  140. err_msg="Function %d" % j)
  141. def test_dense(self):
  142. # Should be more accurate for dense meshes
  143. funcs = [
  144. lambda x, y: x**2,
  145. lambda x, y: y**2,
  146. lambda x, y: x**2 - y**2,
  147. lambda x, y: x*y,
  148. lambda x, y: np.cos(2*np.pi*x)*np.sin(2*np.pi*y)
  149. ]
  150. np.random.seed(4321) # use a different seed than the check!
  151. grid = np.r_[np.array([(0,0), (0,1), (1,0), (1,1)], dtype=float),
  152. np.random.rand(30*30, 2)]
  153. for j, func in enumerate(funcs):
  154. self._check_accuracy(func, x=grid, tol=1e-9, atol=5e-3, rtol=1e-2,
  155. err_msg="Function %d" % j)
  156. def test_wrong_ndim(self):
  157. x = np.random.randn(30, 3)
  158. y = np.random.randn(30)
  159. assert_raises(ValueError, interpnd.CloughTocher2DInterpolator, x, y)
  160. def test_pickle(self):
  161. # Test at single points
  162. np.random.seed(1234)
  163. x = np.random.rand(30, 2)
  164. y = np.random.rand(30) + 1j*np.random.rand(30)
  165. ip = interpnd.CloughTocher2DInterpolator(x, y)
  166. ip2 = pickle.loads(pickle.dumps(ip))
  167. assert_almost_equal(ip(0.5, 0.5), ip2(0.5, 0.5))
  168. if __name__ == "__main__":
  169. run_module_suite()