test_fitpack2.py 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347
  1. # Created by Pearu Peterson, June 2003
  2. import itertools
  3. import numpy as np
  4. from numpy.testing import (assert_equal, assert_almost_equal, assert_array_equal,
  5. assert_array_almost_equal, assert_allclose, suppress_warnings)
  6. from pytest import raises as assert_raises
  7. from numpy import array, diff, linspace, meshgrid, ones, pi, shape
  8. from scipy.interpolate._fitpack_py import bisplrep, bisplev, splrep, spalde
  9. from scipy.interpolate._fitpack2 import (UnivariateSpline,
  10. LSQUnivariateSpline, InterpolatedUnivariateSpline,
  11. LSQBivariateSpline, SmoothBivariateSpline, RectBivariateSpline,
  12. LSQSphereBivariateSpline, SmoothSphereBivariateSpline,
  13. RectSphereBivariateSpline)
  14. class TestUnivariateSpline:
  15. def test_linear_constant(self):
  16. x = [1,2,3]
  17. y = [3,3,3]
  18. lut = UnivariateSpline(x,y,k=1)
  19. assert_array_almost_equal(lut.get_knots(),[1,3])
  20. assert_array_almost_equal(lut.get_coeffs(),[3,3])
  21. assert_almost_equal(lut.get_residual(),0.0)
  22. assert_array_almost_equal(lut([1,1.5,2]),[3,3,3])
  23. def test_preserve_shape(self):
  24. x = [1, 2, 3]
  25. y = [0, 2, 4]
  26. lut = UnivariateSpline(x, y, k=1)
  27. arg = 2
  28. assert_equal(shape(arg), shape(lut(arg)))
  29. assert_equal(shape(arg), shape(lut(arg, nu=1)))
  30. arg = [1.5, 2, 2.5]
  31. assert_equal(shape(arg), shape(lut(arg)))
  32. assert_equal(shape(arg), shape(lut(arg, nu=1)))
  33. def test_linear_1d(self):
  34. x = [1,2,3]
  35. y = [0,2,4]
  36. lut = UnivariateSpline(x,y,k=1)
  37. assert_array_almost_equal(lut.get_knots(),[1,3])
  38. assert_array_almost_equal(lut.get_coeffs(),[0,4])
  39. assert_almost_equal(lut.get_residual(),0.0)
  40. assert_array_almost_equal(lut([1,1.5,2]),[0,1,2])
  41. def test_subclassing(self):
  42. # See #731
  43. class ZeroSpline(UnivariateSpline):
  44. def __call__(self, x):
  45. return 0*array(x)
  46. sp = ZeroSpline([1,2,3,4,5], [3,2,3,2,3], k=2)
  47. assert_array_equal(sp([1.5, 2.5]), [0., 0.])
  48. def test_empty_input(self):
  49. # Test whether empty input returns an empty output. Ticket 1014
  50. x = [1,3,5,7,9]
  51. y = [0,4,9,12,21]
  52. spl = UnivariateSpline(x, y, k=3)
  53. assert_array_equal(spl([]), array([]))
  54. def test_roots(self):
  55. x = [1, 3, 5, 7, 9]
  56. y = [0, 4, 9, 12, 21]
  57. spl = UnivariateSpline(x, y, k=3)
  58. assert_almost_equal(spl.roots()[0], 1.050290639101332)
  59. def test_derivatives(self):
  60. x = [1, 3, 5, 7, 9]
  61. y = [0, 4, 9, 12, 21]
  62. spl = UnivariateSpline(x, y, k=3)
  63. assert_almost_equal(spl.derivatives(3.5),
  64. [5.5152902, 1.7146577, -0.1830357, 0.3125])
  65. def test_derivatives_2(self):
  66. x = np.arange(8)
  67. y = x**3 + 2.*x**2
  68. tck = splrep(x, y, s=0)
  69. ders = spalde(3, tck)
  70. assert_allclose(ders, [45., # 3**3 + 2*(3)**2
  71. 39., # 3*(3)**2 + 4*(3)
  72. 22., # 6*(3) + 4
  73. 6.], # 6*3**0
  74. atol=1e-15)
  75. spl = UnivariateSpline(x, y, s=0, k=3)
  76. assert_allclose(spl.derivatives(3),
  77. ders,
  78. atol=1e-15)
  79. def test_resize_regression(self):
  80. """Regression test for #1375."""
  81. x = [-1., -0.65016502, -0.58856235, -0.26903553, -0.17370892,
  82. -0.10011001, 0., 0.10011001, 0.17370892, 0.26903553, 0.58856235,
  83. 0.65016502, 1.]
  84. y = [1.,0.62928599, 0.5797223, 0.39965815, 0.36322694, 0.3508061,
  85. 0.35214793, 0.3508061, 0.36322694, 0.39965815, 0.5797223,
  86. 0.62928599, 1.]
  87. w = [1.00000000e+12, 6.88875973e+02, 4.89314737e+02, 4.26864807e+02,
  88. 6.07746770e+02, 4.51341444e+02, 3.17480210e+02, 4.51341444e+02,
  89. 6.07746770e+02, 4.26864807e+02, 4.89314737e+02, 6.88875973e+02,
  90. 1.00000000e+12]
  91. spl = UnivariateSpline(x=x, y=y, w=w, s=None)
  92. desired = array([0.35100374, 0.51715855, 0.87789547, 0.98719344])
  93. assert_allclose(spl([0.1, 0.5, 0.9, 0.99]), desired, atol=5e-4)
  94. def test_out_of_range_regression(self):
  95. # Test different extrapolation modes. See ticket 3557
  96. x = np.arange(5, dtype=float)
  97. y = x**3
  98. xp = linspace(-8, 13, 100)
  99. xp_zeros = xp.copy()
  100. xp_zeros[np.logical_or(xp_zeros < 0., xp_zeros > 4.)] = 0
  101. xp_clip = xp.copy()
  102. xp_clip[xp_clip < x[0]] = x[0]
  103. xp_clip[xp_clip > x[-1]] = x[-1]
  104. for cls in [UnivariateSpline, InterpolatedUnivariateSpline]:
  105. spl = cls(x=x, y=y)
  106. for ext in [0, 'extrapolate']:
  107. assert_allclose(spl(xp, ext=ext), xp**3, atol=1e-16)
  108. assert_allclose(cls(x, y, ext=ext)(xp), xp**3, atol=1e-16)
  109. for ext in [1, 'zeros']:
  110. assert_allclose(spl(xp, ext=ext), xp_zeros**3, atol=1e-16)
  111. assert_allclose(cls(x, y, ext=ext)(xp), xp_zeros**3, atol=1e-16)
  112. for ext in [2, 'raise']:
  113. assert_raises(ValueError, spl, xp, **dict(ext=ext))
  114. for ext in [3, 'const']:
  115. assert_allclose(spl(xp, ext=ext), xp_clip**3, atol=1e-16)
  116. assert_allclose(cls(x, y, ext=ext)(xp), xp_clip**3, atol=1e-16)
  117. # also test LSQUnivariateSpline [which needs explicit knots]
  118. t = spl.get_knots()[3:4] # interior knots w/ default k=3
  119. spl = LSQUnivariateSpline(x, y, t)
  120. assert_allclose(spl(xp, ext=0), xp**3, atol=1e-16)
  121. assert_allclose(spl(xp, ext=1), xp_zeros**3, atol=1e-16)
  122. assert_raises(ValueError, spl, xp, **dict(ext=2))
  123. assert_allclose(spl(xp, ext=3), xp_clip**3, atol=1e-16)
  124. # also make sure that unknown values for `ext` are caught early
  125. for ext in [-1, 'unknown']:
  126. spl = UnivariateSpline(x, y)
  127. assert_raises(ValueError, spl, xp, **dict(ext=ext))
  128. assert_raises(ValueError, UnivariateSpline,
  129. **dict(x=x, y=y, ext=ext))
  130. def test_lsq_fpchec(self):
  131. xs = np.arange(100) * 1.
  132. ys = np.arange(100) * 1.
  133. knots = np.linspace(0, 99, 10)
  134. bbox = (-1, 101)
  135. assert_raises(ValueError, LSQUnivariateSpline, xs, ys, knots,
  136. bbox=bbox)
  137. def test_derivative_and_antiderivative(self):
  138. # Thin wrappers to splder/splantider, so light smoke test only.
  139. x = np.linspace(0, 1, 70)**3
  140. y = np.cos(x)
  141. spl = UnivariateSpline(x, y, s=0)
  142. spl2 = spl.antiderivative(2).derivative(2)
  143. assert_allclose(spl(0.3), spl2(0.3))
  144. spl2 = spl.antiderivative(1)
  145. assert_allclose(spl2(0.6) - spl2(0.2),
  146. spl.integral(0.2, 0.6))
  147. def test_derivative_extrapolation(self):
  148. # Regression test for gh-10195: for a const-extrapolation spline
  149. # its derivative evaluates to zero for extrapolation
  150. x_values = [1, 2, 4, 6, 8.5]
  151. y_values = [0.5, 0.8, 1.3, 2.5, 5]
  152. f = UnivariateSpline(x_values, y_values, ext='const', k=3)
  153. x = [-1, 0, -0.5, 9, 9.5, 10]
  154. assert_allclose(f.derivative()(x), 0, atol=1e-15)
  155. def test_integral_out_of_bounds(self):
  156. # Regression test for gh-7906: .integral(a, b) is wrong if both
  157. # a and b are out-of-bounds
  158. x = np.linspace(0., 1., 7)
  159. for ext in range(4):
  160. f = UnivariateSpline(x, x, s=0, ext=ext)
  161. for (a, b) in [(1, 1), (1, 5), (2, 5),
  162. (0, 0), (-2, 0), (-2, -1)]:
  163. assert_allclose(f.integral(a, b), 0, atol=1e-15)
  164. def test_nan(self):
  165. # bail out early if the input data contains nans
  166. x = np.arange(10, dtype=float)
  167. y = x**3
  168. w = np.ones_like(x)
  169. # also test LSQUnivariateSpline [which needs explicit knots]
  170. spl = UnivariateSpline(x, y, check_finite=True)
  171. t = spl.get_knots()[3:4] # interior knots w/ default k=3
  172. y_end = y[-1]
  173. for z in [np.nan, np.inf, -np.inf]:
  174. y[-1] = z
  175. assert_raises(ValueError, UnivariateSpline,
  176. **dict(x=x, y=y, check_finite=True))
  177. assert_raises(ValueError, InterpolatedUnivariateSpline,
  178. **dict(x=x, y=y, check_finite=True))
  179. assert_raises(ValueError, LSQUnivariateSpline,
  180. **dict(x=x, y=y, t=t, check_finite=True))
  181. y[-1] = y_end # check valid y but invalid w
  182. w[-1] = z
  183. assert_raises(ValueError, UnivariateSpline,
  184. **dict(x=x, y=y, w=w, check_finite=True))
  185. assert_raises(ValueError, InterpolatedUnivariateSpline,
  186. **dict(x=x, y=y, w=w, check_finite=True))
  187. assert_raises(ValueError, LSQUnivariateSpline,
  188. **dict(x=x, y=y, t=t, w=w, check_finite=True))
  189. def test_strictly_increasing_x(self):
  190. # Test the x is required to be strictly increasing for
  191. # UnivariateSpline if s=0 and for InterpolatedUnivariateSpline,
  192. # but merely increasing for UnivariateSpline if s>0
  193. # and for LSQUnivariateSpline; see gh-8535
  194. xx = np.arange(10, dtype=float)
  195. yy = xx**3
  196. x = np.arange(10, dtype=float)
  197. x[1] = x[0]
  198. y = x**3
  199. w = np.ones_like(x)
  200. # also test LSQUnivariateSpline [which needs explicit knots]
  201. spl = UnivariateSpline(xx, yy, check_finite=True)
  202. t = spl.get_knots()[3:4] # interior knots w/ default k=3
  203. UnivariateSpline(x=x, y=y, w=w, s=1, check_finite=True)
  204. LSQUnivariateSpline(x=x, y=y, t=t, w=w, check_finite=True)
  205. assert_raises(ValueError, UnivariateSpline,
  206. **dict(x=x, y=y, s=0, check_finite=True))
  207. assert_raises(ValueError, InterpolatedUnivariateSpline,
  208. **dict(x=x, y=y, check_finite=True))
  209. def test_increasing_x(self):
  210. # Test that x is required to be increasing, see gh-8535
  211. xx = np.arange(10, dtype=float)
  212. yy = xx**3
  213. x = np.arange(10, dtype=float)
  214. x[1] = x[0] - 1.0
  215. y = x**3
  216. w = np.ones_like(x)
  217. # also test LSQUnivariateSpline [which needs explicit knots]
  218. spl = UnivariateSpline(xx, yy, check_finite=True)
  219. t = spl.get_knots()[3:4] # interior knots w/ default k=3
  220. assert_raises(ValueError, UnivariateSpline,
  221. **dict(x=x, y=y, check_finite=True))
  222. assert_raises(ValueError, InterpolatedUnivariateSpline,
  223. **dict(x=x, y=y, check_finite=True))
  224. assert_raises(ValueError, LSQUnivariateSpline,
  225. **dict(x=x, y=y, t=t, w=w, check_finite=True))
  226. def test_invalid_input_for_univariate_spline(self):
  227. with assert_raises(ValueError) as info:
  228. x_values = [1, 2, 4, 6, 8.5]
  229. y_values = [0.5, 0.8, 1.3, 2.5]
  230. UnivariateSpline(x_values, y_values)
  231. assert "x and y should have a same length" in str(info.value)
  232. with assert_raises(ValueError) as info:
  233. x_values = [1, 2, 4, 6, 8.5]
  234. y_values = [0.5, 0.8, 1.3, 2.5, 2.8]
  235. w_values = [-1.0, 1.0, 1.0, 1.0]
  236. UnivariateSpline(x_values, y_values, w=w_values)
  237. assert "x, y, and w should have a same length" in str(info.value)
  238. with assert_raises(ValueError) as info:
  239. bbox = (-1)
  240. UnivariateSpline(x_values, y_values, bbox=bbox)
  241. assert "bbox shape should be (2,)" in str(info.value)
  242. with assert_raises(ValueError) as info:
  243. UnivariateSpline(x_values, y_values, k=6)
  244. assert "k should be 1 <= k <= 5" in str(info.value)
  245. with assert_raises(ValueError) as info:
  246. UnivariateSpline(x_values, y_values, s=-1.0)
  247. assert "s should be s >= 0.0" in str(info.value)
  248. def test_invalid_input_for_interpolated_univariate_spline(self):
  249. with assert_raises(ValueError) as info:
  250. x_values = [1, 2, 4, 6, 8.5]
  251. y_values = [0.5, 0.8, 1.3, 2.5]
  252. InterpolatedUnivariateSpline(x_values, y_values)
  253. assert "x and y should have a same length" in str(info.value)
  254. with assert_raises(ValueError) as info:
  255. x_values = [1, 2, 4, 6, 8.5]
  256. y_values = [0.5, 0.8, 1.3, 2.5, 2.8]
  257. w_values = [-1.0, 1.0, 1.0, 1.0]
  258. InterpolatedUnivariateSpline(x_values, y_values, w=w_values)
  259. assert "x, y, and w should have a same length" in str(info.value)
  260. with assert_raises(ValueError) as info:
  261. bbox = (-1)
  262. InterpolatedUnivariateSpline(x_values, y_values, bbox=bbox)
  263. assert "bbox shape should be (2,)" in str(info.value)
  264. with assert_raises(ValueError) as info:
  265. InterpolatedUnivariateSpline(x_values, y_values, k=6)
  266. assert "k should be 1 <= k <= 5" in str(info.value)
  267. def test_invalid_input_for_lsq_univariate_spline(self):
  268. x_values = [1, 2, 4, 6, 8.5]
  269. y_values = [0.5, 0.8, 1.3, 2.5, 2.8]
  270. spl = UnivariateSpline(x_values, y_values, check_finite=True)
  271. t_values = spl.get_knots()[3:4] # interior knots w/ default k=3
  272. with assert_raises(ValueError) as info:
  273. x_values = [1, 2, 4, 6, 8.5]
  274. y_values = [0.5, 0.8, 1.3, 2.5]
  275. LSQUnivariateSpline(x_values, y_values, t_values)
  276. assert "x and y should have a same length" in str(info.value)
  277. with assert_raises(ValueError) as info:
  278. x_values = [1, 2, 4, 6, 8.5]
  279. y_values = [0.5, 0.8, 1.3, 2.5, 2.8]
  280. w_values = [1.0, 1.0, 1.0, 1.0]
  281. LSQUnivariateSpline(x_values, y_values, t_values, w=w_values)
  282. assert "x, y, and w should have a same length" in str(info.value)
  283. with assert_raises(ValueError) as info:
  284. bbox = (100, -100)
  285. LSQUnivariateSpline(x_values, y_values, t_values, bbox=bbox)
  286. assert "Interior knots t must satisfy Schoenberg-Whitney conditions" in str(info.value)
  287. with assert_raises(ValueError) as info:
  288. bbox = (-1)
  289. LSQUnivariateSpline(x_values, y_values, t_values, bbox=bbox)
  290. assert "bbox shape should be (2,)" in str(info.value)
  291. with assert_raises(ValueError) as info:
  292. LSQUnivariateSpline(x_values, y_values, t_values, k=6)
  293. assert "k should be 1 <= k <= 5" in str(info.value)
  294. def test_array_like_input(self):
  295. x_values = np.array([1, 2, 4, 6, 8.5])
  296. y_values = np.array([0.5, 0.8, 1.3, 2.5, 2.8])
  297. w_values = np.array([1.0, 1.0, 1.0, 1.0, 1.0])
  298. bbox = np.array([-100, 100])
  299. # np.array input
  300. spl1 = UnivariateSpline(x=x_values, y=y_values, w=w_values,
  301. bbox=bbox)
  302. # list input
  303. spl2 = UnivariateSpline(x=x_values.tolist(), y=y_values.tolist(),
  304. w=w_values.tolist(), bbox=bbox.tolist())
  305. assert_allclose(spl1([0.1, 0.5, 0.9, 0.99]),
  306. spl2([0.1, 0.5, 0.9, 0.99]))
  307. def test_fpknot_oob_crash(self):
  308. # https://github.com/scipy/scipy/issues/3691
  309. x = range(109)
  310. y = [0., 0., 0., 0., 0., 10.9, 0., 11., 0.,
  311. 0., 0., 10.9, 0., 0., 0., 0., 0., 0.,
  312. 10.9, 0., 0., 0., 11., 0., 0., 0., 10.9,
  313. 0., 0., 0., 10.5, 0., 0., 0., 10.7, 0.,
  314. 0., 0., 11., 0., 0., 0., 0., 0., 0.,
  315. 10.9, 0., 0., 10.7, 0., 0., 0., 10.6, 0.,
  316. 0., 0., 10.5, 0., 0., 10.7, 0., 0., 10.5,
  317. 0., 0., 11.5, 0., 0., 0., 10.7, 0., 0.,
  318. 10.7, 0., 0., 10.9, 0., 0., 10.8, 0., 0.,
  319. 0., 10.7, 0., 0., 10.6, 0., 0., 0., 10.4,
  320. 0., 0., 10.6, 0., 0., 10.5, 0., 0., 0.,
  321. 10.7, 0., 0., 0., 10.4, 0., 0., 0., 10.8, 0.]
  322. with suppress_warnings() as sup:
  323. r = sup.record(
  324. UserWarning,
  325. r"""
  326. The maximal number of iterations maxit \(set to 20 by the program\)
  327. allowed for finding a smoothing spline with fp=s has been reached: s
  328. too small.
  329. There is an approximation returned but the corresponding weighted sum
  330. of squared residuals does not satisfy the condition abs\(fp-s\)/s < tol.""")
  331. UnivariateSpline(x, y, k=1)
  332. assert_equal(len(r), 1)
  333. class TestLSQBivariateSpline:
  334. # NOTE: The systems in this test class are rank-deficient
  335. def test_linear_constant(self):
  336. x = [1,1,1,2,2,2,3,3,3]
  337. y = [1,2,3,1,2,3,1,2,3]
  338. z = [3,3,3,3,3,3,3,3,3]
  339. s = 0.1
  340. tx = [1+s,3-s]
  341. ty = [1+s,3-s]
  342. with suppress_warnings() as sup:
  343. r = sup.record(UserWarning, "\nThe coefficients of the spline")
  344. lut = LSQBivariateSpline(x,y,z,tx,ty,kx=1,ky=1)
  345. assert_equal(len(r), 1)
  346. assert_almost_equal(lut(2,2), 3.)
  347. def test_bilinearity(self):
  348. x = [1,1,1,2,2,2,3,3,3]
  349. y = [1,2,3,1,2,3,1,2,3]
  350. z = [0,7,8,3,4,7,1,3,4]
  351. s = 0.1
  352. tx = [1+s,3-s]
  353. ty = [1+s,3-s]
  354. with suppress_warnings() as sup:
  355. # This seems to fail (ier=1, see ticket 1642).
  356. sup.filter(UserWarning, "\nThe coefficients of the spline")
  357. lut = LSQBivariateSpline(x,y,z,tx,ty,kx=1,ky=1)
  358. tx, ty = lut.get_knots()
  359. for xa, xb in zip(tx[:-1], tx[1:]):
  360. for ya, yb in zip(ty[:-1], ty[1:]):
  361. for t in [0.1, 0.5, 0.9]:
  362. for s in [0.3, 0.4, 0.7]:
  363. xp = xa*(1-t) + xb*t
  364. yp = ya*(1-s) + yb*s
  365. zp = (+ lut(xa, ya)*(1-t)*(1-s)
  366. + lut(xb, ya)*t*(1-s)
  367. + lut(xa, yb)*(1-t)*s
  368. + lut(xb, yb)*t*s)
  369. assert_almost_equal(lut(xp,yp), zp)
  370. def test_integral(self):
  371. x = [1,1,1,2,2,2,8,8,8]
  372. y = [1,2,3,1,2,3,1,2,3]
  373. z = array([0,7,8,3,4,7,1,3,4])
  374. s = 0.1
  375. tx = [1+s,3-s]
  376. ty = [1+s,3-s]
  377. with suppress_warnings() as sup:
  378. r = sup.record(UserWarning, "\nThe coefficients of the spline")
  379. lut = LSQBivariateSpline(x, y, z, tx, ty, kx=1, ky=1)
  380. assert_equal(len(r), 1)
  381. tx, ty = lut.get_knots()
  382. tz = lut(tx, ty)
  383. trpz = .25*(diff(tx)[:,None]*diff(ty)[None,:]
  384. * (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
  385. assert_almost_equal(lut.integral(tx[0], tx[-1], ty[0], ty[-1]),
  386. trpz)
  387. def test_empty_input(self):
  388. # Test whether empty inputs returns an empty output. Ticket 1014
  389. x = [1,1,1,2,2,2,3,3,3]
  390. y = [1,2,3,1,2,3,1,2,3]
  391. z = [3,3,3,3,3,3,3,3,3]
  392. s = 0.1
  393. tx = [1+s,3-s]
  394. ty = [1+s,3-s]
  395. with suppress_warnings() as sup:
  396. r = sup.record(UserWarning, "\nThe coefficients of the spline")
  397. lut = LSQBivariateSpline(x, y, z, tx, ty, kx=1, ky=1)
  398. assert_equal(len(r), 1)
  399. assert_array_equal(lut([], []), np.zeros((0,0)))
  400. assert_array_equal(lut([], [], grid=False), np.zeros((0,)))
  401. def test_invalid_input(self):
  402. s = 0.1
  403. tx = [1 + s, 3 - s]
  404. ty = [1 + s, 3 - s]
  405. with assert_raises(ValueError) as info:
  406. x = np.linspace(1.0, 10.0)
  407. y = np.linspace(1.0, 10.0)
  408. z = np.linspace(1.0, 10.0, num=10)
  409. LSQBivariateSpline(x, y, z, tx, ty)
  410. assert "x, y, and z should have a same length" in str(info.value)
  411. with assert_raises(ValueError) as info:
  412. x = np.linspace(1.0, 10.0)
  413. y = np.linspace(1.0, 10.0)
  414. z = np.linspace(1.0, 10.0)
  415. w = np.linspace(1.0, 10.0, num=20)
  416. LSQBivariateSpline(x, y, z, tx, ty, w=w)
  417. assert "x, y, z, and w should have a same length" in str(info.value)
  418. with assert_raises(ValueError) as info:
  419. w = np.linspace(-1.0, 10.0)
  420. LSQBivariateSpline(x, y, z, tx, ty, w=w)
  421. assert "w should be positive" in str(info.value)
  422. with assert_raises(ValueError) as info:
  423. bbox = (-100, 100, -100)
  424. LSQBivariateSpline(x, y, z, tx, ty, bbox=bbox)
  425. assert "bbox shape should be (4,)" in str(info.value)
  426. with assert_raises(ValueError) as info:
  427. LSQBivariateSpline(x, y, z, tx, ty, kx=10, ky=10)
  428. assert "The length of x, y and z should be at least (kx+1) * (ky+1)" in \
  429. str(info.value)
  430. with assert_raises(ValueError) as exc_info:
  431. LSQBivariateSpline(x, y, z, tx, ty, eps=0.0)
  432. assert "eps should be between (0, 1)" in str(exc_info.value)
  433. with assert_raises(ValueError) as exc_info:
  434. LSQBivariateSpline(x, y, z, tx, ty, eps=1.0)
  435. assert "eps should be between (0, 1)" in str(exc_info.value)
  436. def test_array_like_input(self):
  437. s = 0.1
  438. tx = np.array([1 + s, 3 - s])
  439. ty = np.array([1 + s, 3 - s])
  440. x = np.linspace(1.0, 10.0)
  441. y = np.linspace(1.0, 10.0)
  442. z = np.linspace(1.0, 10.0)
  443. w = np.linspace(1.0, 10.0)
  444. bbox = np.array([1.0, 10.0, 1.0, 10.0])
  445. with suppress_warnings() as sup:
  446. r = sup.record(UserWarning, "\nThe coefficients of the spline")
  447. # np.array input
  448. spl1 = LSQBivariateSpline(x, y, z, tx, ty, w=w, bbox=bbox)
  449. # list input
  450. spl2 = LSQBivariateSpline(x.tolist(), y.tolist(), z.tolist(),
  451. tx.tolist(), ty.tolist(), w=w.tolist(),
  452. bbox=bbox)
  453. assert_allclose(spl1(2.0, 2.0), spl2(2.0, 2.0))
  454. assert_equal(len(r), 2)
  455. def test_unequal_length_of_knots(self):
  456. """Test for the case when the input knot-location arrays in x and y are
  457. of different lengths.
  458. """
  459. x, y = np.mgrid[0:100, 0:100]
  460. x = x.ravel()
  461. y = y.ravel()
  462. z = 3.0 * np.ones_like(x)
  463. tx = np.linspace(0.1, 98.0, 29)
  464. ty = np.linspace(0.1, 98.0, 33)
  465. with suppress_warnings() as sup:
  466. r = sup.record(UserWarning, "\nThe coefficients of the spline")
  467. lut = LSQBivariateSpline(x,y,z,tx,ty)
  468. assert_equal(len(r), 1)
  469. assert_almost_equal(lut(x, y, grid=False), z)
  470. class TestSmoothBivariateSpline:
  471. def test_linear_constant(self):
  472. x = [1,1,1,2,2,2,3,3,3]
  473. y = [1,2,3,1,2,3,1,2,3]
  474. z = [3,3,3,3,3,3,3,3,3]
  475. lut = SmoothBivariateSpline(x,y,z,kx=1,ky=1)
  476. assert_array_almost_equal(lut.get_knots(),([1,1,3,3],[1,1,3,3]))
  477. assert_array_almost_equal(lut.get_coeffs(),[3,3,3,3])
  478. assert_almost_equal(lut.get_residual(),0.0)
  479. assert_array_almost_equal(lut([1,1.5,2],[1,1.5]),[[3,3],[3,3],[3,3]])
  480. def test_linear_1d(self):
  481. x = [1,1,1,2,2,2,3,3,3]
  482. y = [1,2,3,1,2,3,1,2,3]
  483. z = [0,0,0,2,2,2,4,4,4]
  484. lut = SmoothBivariateSpline(x,y,z,kx=1,ky=1)
  485. assert_array_almost_equal(lut.get_knots(),([1,1,3,3],[1,1,3,3]))
  486. assert_array_almost_equal(lut.get_coeffs(),[0,0,4,4])
  487. assert_almost_equal(lut.get_residual(),0.0)
  488. assert_array_almost_equal(lut([1,1.5,2],[1,1.5]),[[0,0],[1,1],[2,2]])
  489. def test_integral(self):
  490. x = [1,1,1,2,2,2,4,4,4]
  491. y = [1,2,3,1,2,3,1,2,3]
  492. z = array([0,7,8,3,4,7,1,3,4])
  493. with suppress_warnings() as sup:
  494. # This seems to fail (ier=1, see ticket 1642).
  495. sup.filter(UserWarning, "\nThe required storage space")
  496. lut = SmoothBivariateSpline(x, y, z, kx=1, ky=1, s=0)
  497. tx = [1,2,4]
  498. ty = [1,2,3]
  499. tz = lut(tx, ty)
  500. trpz = .25*(diff(tx)[:,None]*diff(ty)[None,:]
  501. * (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
  502. assert_almost_equal(lut.integral(tx[0], tx[-1], ty[0], ty[-1]), trpz)
  503. lut2 = SmoothBivariateSpline(x, y, z, kx=2, ky=2, s=0)
  504. assert_almost_equal(lut2.integral(tx[0], tx[-1], ty[0], ty[-1]), trpz,
  505. decimal=0) # the quadratures give 23.75 and 23.85
  506. tz = lut(tx[:-1], ty[:-1])
  507. trpz = .25*(diff(tx[:-1])[:,None]*diff(ty[:-1])[None,:]
  508. * (tz[:-1,:-1]+tz[1:,:-1]+tz[:-1,1:]+tz[1:,1:])).sum()
  509. assert_almost_equal(lut.integral(tx[0], tx[-2], ty[0], ty[-2]), trpz)
  510. def test_rerun_lwrk2_too_small(self):
  511. # in this setting, lwrk2 is too small in the default run. Here we
  512. # check for equality with the bisplrep/bisplev output because there,
  513. # an automatic re-run of the spline representation is done if ier>10.
  514. x = np.linspace(-2, 2, 80)
  515. y = np.linspace(-2, 2, 80)
  516. z = x + y
  517. xi = np.linspace(-1, 1, 100)
  518. yi = np.linspace(-2, 2, 100)
  519. tck = bisplrep(x, y, z)
  520. res1 = bisplev(xi, yi, tck)
  521. interp_ = SmoothBivariateSpline(x, y, z)
  522. res2 = interp_(xi, yi)
  523. assert_almost_equal(res1, res2)
  524. def test_invalid_input(self):
  525. with assert_raises(ValueError) as info:
  526. x = np.linspace(1.0, 10.0)
  527. y = np.linspace(1.0, 10.0)
  528. z = np.linspace(1.0, 10.0, num=10)
  529. SmoothBivariateSpline(x, y, z)
  530. assert "x, y, and z should have a same length" in str(info.value)
  531. with assert_raises(ValueError) as info:
  532. x = np.linspace(1.0, 10.0)
  533. y = np.linspace(1.0, 10.0)
  534. z = np.linspace(1.0, 10.0)
  535. w = np.linspace(1.0, 10.0, num=20)
  536. SmoothBivariateSpline(x, y, z, w=w)
  537. assert "x, y, z, and w should have a same length" in str(info.value)
  538. with assert_raises(ValueError) as info:
  539. w = np.linspace(-1.0, 10.0)
  540. SmoothBivariateSpline(x, y, z, w=w)
  541. assert "w should be positive" in str(info.value)
  542. with assert_raises(ValueError) as info:
  543. bbox = (-100, 100, -100)
  544. SmoothBivariateSpline(x, y, z, bbox=bbox)
  545. assert "bbox shape should be (4,)" in str(info.value)
  546. with assert_raises(ValueError) as info:
  547. SmoothBivariateSpline(x, y, z, kx=10, ky=10)
  548. assert "The length of x, y and z should be at least (kx+1) * (ky+1)" in\
  549. str(info.value)
  550. with assert_raises(ValueError) as info:
  551. SmoothBivariateSpline(x, y, z, s=-1.0)
  552. assert "s should be s >= 0.0" in str(info.value)
  553. with assert_raises(ValueError) as exc_info:
  554. SmoothBivariateSpline(x, y, z, eps=0.0)
  555. assert "eps should be between (0, 1)" in str(exc_info.value)
  556. with assert_raises(ValueError) as exc_info:
  557. SmoothBivariateSpline(x, y, z, eps=1.0)
  558. assert "eps should be between (0, 1)" in str(exc_info.value)
  559. def test_array_like_input(self):
  560. x = np.array([1, 1, 1, 2, 2, 2, 3, 3, 3])
  561. y = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3])
  562. z = np.array([3, 3, 3, 3, 3, 3, 3, 3, 3])
  563. w = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1])
  564. bbox = np.array([1.0, 3.0, 1.0, 3.0])
  565. # np.array input
  566. spl1 = SmoothBivariateSpline(x, y, z, w=w, bbox=bbox, kx=1, ky=1)
  567. # list input
  568. spl2 = SmoothBivariateSpline(x.tolist(), y.tolist(), z.tolist(),
  569. bbox=bbox.tolist(), w=w.tolist(),
  570. kx=1, ky=1)
  571. assert_allclose(spl1(0.1, 0.5), spl2(0.1, 0.5))
  572. class TestLSQSphereBivariateSpline:
  573. def setup_method(self):
  574. # define the input data and coordinates
  575. ntheta, nphi = 70, 90
  576. theta = linspace(0.5/(ntheta - 1), 1 - 0.5/(ntheta - 1), ntheta) * pi
  577. phi = linspace(0.5/(nphi - 1), 1 - 0.5/(nphi - 1), nphi) * 2. * pi
  578. data = ones((theta.shape[0], phi.shape[0]))
  579. # define knots and extract data values at the knots
  580. knotst = theta[::5]
  581. knotsp = phi[::5]
  582. knotdata = data[::5, ::5]
  583. # calculate spline coefficients
  584. lats, lons = meshgrid(theta, phi)
  585. lut_lsq = LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  586. data.T.ravel(), knotst, knotsp)
  587. self.lut_lsq = lut_lsq
  588. self.data = knotdata
  589. self.new_lons, self.new_lats = knotsp, knotst
  590. def test_linear_constant(self):
  591. assert_almost_equal(self.lut_lsq.get_residual(), 0.0)
  592. assert_array_almost_equal(self.lut_lsq(self.new_lats, self.new_lons),
  593. self.data)
  594. def test_empty_input(self):
  595. assert_array_almost_equal(self.lut_lsq([], []), np.zeros((0,0)))
  596. assert_array_almost_equal(self.lut_lsq([], [], grid=False), np.zeros((0,)))
  597. def test_invalid_input(self):
  598. ntheta, nphi = 70, 90
  599. theta = linspace(0.5 / (ntheta - 1), 1 - 0.5 / (ntheta - 1),
  600. ntheta) * pi
  601. phi = linspace(0.5 / (nphi - 1), 1 - 0.5 / (nphi - 1), nphi) * 2. * pi
  602. data = ones((theta.shape[0], phi.shape[0]))
  603. # define knots and extract data values at the knots
  604. knotst = theta[::5]
  605. knotsp = phi[::5]
  606. with assert_raises(ValueError) as exc_info:
  607. invalid_theta = linspace(-0.1, 1.0, num=ntheta) * pi
  608. invalid_lats, lons = meshgrid(invalid_theta, phi)
  609. LSQSphereBivariateSpline(invalid_lats.ravel(), lons.ravel(),
  610. data.T.ravel(), knotst, knotsp)
  611. assert "theta should be between [0, pi]" in str(exc_info.value)
  612. with assert_raises(ValueError) as exc_info:
  613. invalid_theta = linspace(0.1, 1.1, num=ntheta) * pi
  614. invalid_lats, lons = meshgrid(invalid_theta, phi)
  615. LSQSphereBivariateSpline(invalid_lats.ravel(), lons.ravel(),
  616. data.T.ravel(), knotst, knotsp)
  617. assert "theta should be between [0, pi]" in str(exc_info.value)
  618. with assert_raises(ValueError) as exc_info:
  619. invalid_phi = linspace(-0.1, 1.0, num=ntheta) * 2.0 * pi
  620. lats, invalid_lons = meshgrid(theta, invalid_phi)
  621. LSQSphereBivariateSpline(lats.ravel(), invalid_lons.ravel(),
  622. data.T.ravel(), knotst, knotsp)
  623. assert "phi should be between [0, 2pi]" in str(exc_info.value)
  624. with assert_raises(ValueError) as exc_info:
  625. invalid_phi = linspace(0.0, 1.1, num=ntheta) * 2.0 * pi
  626. lats, invalid_lons = meshgrid(theta, invalid_phi)
  627. LSQSphereBivariateSpline(lats.ravel(), invalid_lons.ravel(),
  628. data.T.ravel(), knotst, knotsp)
  629. assert "phi should be between [0, 2pi]" in str(exc_info.value)
  630. lats, lons = meshgrid(theta, phi)
  631. with assert_raises(ValueError) as exc_info:
  632. invalid_knotst = np.copy(knotst)
  633. invalid_knotst[0] = -0.1
  634. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  635. data.T.ravel(), invalid_knotst, knotsp)
  636. assert "tt should be between (0, pi)" in str(exc_info.value)
  637. with assert_raises(ValueError) as exc_info:
  638. invalid_knotst = np.copy(knotst)
  639. invalid_knotst[0] = pi
  640. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  641. data.T.ravel(), invalid_knotst, knotsp)
  642. assert "tt should be between (0, pi)" in str(exc_info.value)
  643. with assert_raises(ValueError) as exc_info:
  644. invalid_knotsp = np.copy(knotsp)
  645. invalid_knotsp[0] = -0.1
  646. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  647. data.T.ravel(), knotst, invalid_knotsp)
  648. assert "tp should be between (0, 2pi)" in str(exc_info.value)
  649. with assert_raises(ValueError) as exc_info:
  650. invalid_knotsp = np.copy(knotsp)
  651. invalid_knotsp[0] = 2 * pi
  652. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  653. data.T.ravel(), knotst, invalid_knotsp)
  654. assert "tp should be between (0, 2pi)" in str(exc_info.value)
  655. with assert_raises(ValueError) as exc_info:
  656. invalid_w = array([-1.0, 1.0, 1.5, 0.5, 1.0, 1.5, 0.5, 1.0, 1.0])
  657. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(), data.T.ravel(),
  658. knotst, knotsp, w=invalid_w)
  659. assert "w should be positive" in str(exc_info.value)
  660. with assert_raises(ValueError) as exc_info:
  661. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(), data.T.ravel(),
  662. knotst, knotsp, eps=0.0)
  663. assert "eps should be between (0, 1)" in str(exc_info.value)
  664. with assert_raises(ValueError) as exc_info:
  665. LSQSphereBivariateSpline(lats.ravel(), lons.ravel(), data.T.ravel(),
  666. knotst, knotsp, eps=1.0)
  667. assert "eps should be between (0, 1)" in str(exc_info.value)
  668. def test_array_like_input(self):
  669. ntheta, nphi = 70, 90
  670. theta = linspace(0.5 / (ntheta - 1), 1 - 0.5 / (ntheta - 1),
  671. ntheta) * pi
  672. phi = linspace(0.5 / (nphi - 1), 1 - 0.5 / (nphi - 1),
  673. nphi) * 2. * pi
  674. lats, lons = meshgrid(theta, phi)
  675. data = ones((theta.shape[0], phi.shape[0]))
  676. # define knots and extract data values at the knots
  677. knotst = theta[::5]
  678. knotsp = phi[::5]
  679. w = ones((lats.ravel().shape[0]))
  680. # np.array input
  681. spl1 = LSQSphereBivariateSpline(lats.ravel(), lons.ravel(),
  682. data.T.ravel(), knotst, knotsp, w=w)
  683. # list input
  684. spl2 = LSQSphereBivariateSpline(lats.ravel().tolist(),
  685. lons.ravel().tolist(),
  686. data.T.ravel().tolist(),
  687. knotst.tolist(),
  688. knotsp.tolist(), w=w.tolist())
  689. assert_array_almost_equal(spl1(1.0, 1.0), spl2(1.0, 1.0))
  690. class TestSmoothSphereBivariateSpline:
  691. def setup_method(self):
  692. theta = array([.25*pi, .25*pi, .25*pi, .5*pi, .5*pi, .5*pi, .75*pi,
  693. .75*pi, .75*pi])
  694. phi = array([.5 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi, .5 * pi, pi,
  695. 1.5 * pi])
  696. r = array([3, 3, 3, 3, 3, 3, 3, 3, 3])
  697. self.lut = SmoothSphereBivariateSpline(theta, phi, r, s=1E10)
  698. def test_linear_constant(self):
  699. assert_almost_equal(self.lut.get_residual(), 0.)
  700. assert_array_almost_equal(self.lut([1, 1.5, 2],[1, 1.5]),
  701. [[3, 3], [3, 3], [3, 3]])
  702. def test_empty_input(self):
  703. assert_array_almost_equal(self.lut([], []), np.zeros((0,0)))
  704. assert_array_almost_equal(self.lut([], [], grid=False), np.zeros((0,)))
  705. def test_invalid_input(self):
  706. theta = array([.25 * pi, .25 * pi, .25 * pi, .5 * pi, .5 * pi, .5 * pi,
  707. .75 * pi, .75 * pi, .75 * pi])
  708. phi = array([.5 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi, .5 * pi, pi,
  709. 1.5 * pi])
  710. r = array([3, 3, 3, 3, 3, 3, 3, 3, 3])
  711. with assert_raises(ValueError) as exc_info:
  712. invalid_theta = array([-0.1 * pi, .25 * pi, .25 * pi, .5 * pi,
  713. .5 * pi, .5 * pi, .75 * pi, .75 * pi,
  714. .75 * pi])
  715. SmoothSphereBivariateSpline(invalid_theta, phi, r, s=1E10)
  716. assert "theta should be between [0, pi]" in str(exc_info.value)
  717. with assert_raises(ValueError) as exc_info:
  718. invalid_theta = array([.25 * pi, .25 * pi, .25 * pi, .5 * pi,
  719. .5 * pi, .5 * pi, .75 * pi, .75 * pi,
  720. 1.1 * pi])
  721. SmoothSphereBivariateSpline(invalid_theta, phi, r, s=1E10)
  722. assert "theta should be between [0, pi]" in str(exc_info.value)
  723. with assert_raises(ValueError) as exc_info:
  724. invalid_phi = array([-.1 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi,
  725. .5 * pi, pi, 1.5 * pi])
  726. SmoothSphereBivariateSpline(theta, invalid_phi, r, s=1E10)
  727. assert "phi should be between [0, 2pi]" in str(exc_info.value)
  728. with assert_raises(ValueError) as exc_info:
  729. invalid_phi = array([1.0 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi,
  730. .5 * pi, pi, 2.1 * pi])
  731. SmoothSphereBivariateSpline(theta, invalid_phi, r, s=1E10)
  732. assert "phi should be between [0, 2pi]" in str(exc_info.value)
  733. with assert_raises(ValueError) as exc_info:
  734. invalid_w = array([-1.0, 1.0, 1.5, 0.5, 1.0, 1.5, 0.5, 1.0, 1.0])
  735. SmoothSphereBivariateSpline(theta, phi, r, w=invalid_w, s=1E10)
  736. assert "w should be positive" in str(exc_info.value)
  737. with assert_raises(ValueError) as exc_info:
  738. SmoothSphereBivariateSpline(theta, phi, r, s=-1.0)
  739. assert "s should be positive" in str(exc_info.value)
  740. with assert_raises(ValueError) as exc_info:
  741. SmoothSphereBivariateSpline(theta, phi, r, eps=-1.0)
  742. assert "eps should be between (0, 1)" in str(exc_info.value)
  743. with assert_raises(ValueError) as exc_info:
  744. SmoothSphereBivariateSpline(theta, phi, r, eps=1.0)
  745. assert "eps should be between (0, 1)" in str(exc_info.value)
  746. def test_array_like_input(self):
  747. theta = np.array([.25 * pi, .25 * pi, .25 * pi, .5 * pi, .5 * pi,
  748. .5 * pi, .75 * pi, .75 * pi, .75 * pi])
  749. phi = np.array([.5 * pi, pi, 1.5 * pi, .5 * pi, pi, 1.5 * pi, .5 * pi,
  750. pi, 1.5 * pi])
  751. r = np.array([3, 3, 3, 3, 3, 3, 3, 3, 3])
  752. w = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
  753. # np.array input
  754. spl1 = SmoothSphereBivariateSpline(theta, phi, r, w=w, s=1E10)
  755. # list input
  756. spl2 = SmoothSphereBivariateSpline(theta.tolist(), phi.tolist(),
  757. r.tolist(), w=w.tolist(), s=1E10)
  758. assert_array_almost_equal(spl1(1.0, 1.0), spl2(1.0, 1.0))
  759. class TestRectBivariateSpline:
  760. def test_defaults(self):
  761. x = array([1,2,3,4,5])
  762. y = array([1,2,3,4,5])
  763. 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]])
  764. lut = RectBivariateSpline(x,y,z)
  765. assert_array_almost_equal(lut(x,y),z)
  766. def test_evaluate(self):
  767. x = array([1,2,3,4,5])
  768. y = array([1,2,3,4,5])
  769. 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]])
  770. lut = RectBivariateSpline(x,y,z)
  771. xi = [1, 2.3, 5.3, 0.5, 3.3, 1.2, 3]
  772. yi = [1, 3.3, 1.2, 4.0, 5.0, 1.0, 3]
  773. zi = lut.ev(xi, yi)
  774. zi2 = array([lut(xp, yp)[0,0] for xp, yp in zip(xi, yi)])
  775. assert_almost_equal(zi, zi2)
  776. def test_derivatives_grid(self):
  777. x = array([1,2,3,4,5])
  778. y = array([1,2,3,4,5])
  779. 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]])
  780. dx = array([[0,0,-20,0,0],[0,0,13,0,0],[0,0,4,0,0],
  781. [0,0,-11,0,0],[0,0,4,0,0]])/6.
  782. dy = array([[4,-1,0,1,-4],[4,-1,0,1,-4],[0,1.5,0,-1.5,0],
  783. [2,.25,0,-.25,-2],[4,-1,0,1,-4]])
  784. dxdy = array([[40,-25,0,25,-40],[-26,16.25,0,-16.25,26],
  785. [-8,5,0,-5,8],[22,-13.75,0,13.75,-22],[-8,5,0,-5,8]])/6.
  786. lut = RectBivariateSpline(x,y,z)
  787. assert_array_almost_equal(lut(x,y,dx=1),dx)
  788. assert_array_almost_equal(lut(x,y,dy=1),dy)
  789. assert_array_almost_equal(lut(x,y,dx=1,dy=1),dxdy)
  790. def test_derivatives(self):
  791. x = array([1,2,3,4,5])
  792. y = array([1,2,3,4,5])
  793. 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]])
  794. dx = array([0,0,2./3,0,0])
  795. dy = array([4,-1,0,-.25,-4])
  796. dxdy = array([160,65,0,55,32])/24.
  797. lut = RectBivariateSpline(x,y,z)
  798. assert_array_almost_equal(lut(x,y,dx=1,grid=False),dx)
  799. assert_array_almost_equal(lut(x,y,dy=1,grid=False),dy)
  800. assert_array_almost_equal(lut(x,y,dx=1,dy=1,grid=False),dxdy)
  801. def test_partial_derivative_method_grid(self):
  802. x = array([1, 2, 3, 4, 5])
  803. y = array([1, 2, 3, 4, 5])
  804. z = array([[1, 2, 1, 2, 1],
  805. [1, 2, 1, 2, 1],
  806. [1, 2, 3, 2, 1],
  807. [1, 2, 2, 2, 1],
  808. [1, 2, 1, 2, 1]])
  809. dx = array([[0, 0, -20, 0, 0],
  810. [0, 0, 13, 0, 0],
  811. [0, 0, 4, 0, 0],
  812. [0, 0, -11, 0, 0],
  813. [0, 0, 4, 0, 0]]) / 6.
  814. dy = array([[4, -1, 0, 1, -4],
  815. [4, -1, 0, 1, -4],
  816. [0, 1.5, 0, -1.5, 0],
  817. [2, .25, 0, -.25, -2],
  818. [4, -1, 0, 1, -4]])
  819. dxdy = array([[40, -25, 0, 25, -40],
  820. [-26, 16.25, 0, -16.25, 26],
  821. [-8, 5, 0, -5, 8],
  822. [22, -13.75, 0, 13.75, -22],
  823. [-8, 5, 0, -5, 8]]) / 6.
  824. lut = RectBivariateSpline(x, y, z)
  825. assert_array_almost_equal(lut.partial_derivative(1, 0)(x, y), dx)
  826. assert_array_almost_equal(lut.partial_derivative(0, 1)(x, y), dy)
  827. assert_array_almost_equal(lut.partial_derivative(1, 1)(x, y), dxdy)
  828. def test_partial_derivative_method(self):
  829. x = array([1, 2, 3, 4, 5])
  830. y = array([1, 2, 3, 4, 5])
  831. z = array([[1, 2, 1, 2, 1],
  832. [1, 2, 1, 2, 1],
  833. [1, 2, 3, 2, 1],
  834. [1, 2, 2, 2, 1],
  835. [1, 2, 1, 2, 1]])
  836. dx = array([0, 0, 2./3, 0, 0])
  837. dy = array([4, -1, 0, -.25, -4])
  838. dxdy = array([160, 65, 0, 55, 32]) / 24.
  839. lut = RectBivariateSpline(x, y, z)
  840. assert_array_almost_equal(lut.partial_derivative(1, 0)(x, y,
  841. grid=False),
  842. dx)
  843. assert_array_almost_equal(lut.partial_derivative(0, 1)(x, y,
  844. grid=False),
  845. dy)
  846. assert_array_almost_equal(lut.partial_derivative(1, 1)(x, y,
  847. grid=False),
  848. dxdy)
  849. def test_partial_derivative_order_too_large(self):
  850. x = array([0, 1, 2, 3, 4], dtype=float)
  851. y = x.copy()
  852. z = ones((x.size, y.size))
  853. lut = RectBivariateSpline(x, y, z)
  854. with assert_raises(ValueError):
  855. lut.partial_derivative(4, 1)
  856. def test_broadcast(self):
  857. x = array([1,2,3,4,5])
  858. y = array([1,2,3,4,5])
  859. 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]])
  860. lut = RectBivariateSpline(x,y,z)
  861. assert_allclose(lut(x, y), lut(x[:,None], y[None,:], grid=False))
  862. def test_invalid_input(self):
  863. with assert_raises(ValueError) as info:
  864. x = array([6, 2, 3, 4, 5])
  865. y = array([1, 2, 3, 4, 5])
  866. z = array([[1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 3, 2, 1],
  867. [1, 2, 2, 2, 1], [1, 2, 1, 2, 1]])
  868. RectBivariateSpline(x, y, z)
  869. assert "x must be strictly increasing" in str(info.value)
  870. with assert_raises(ValueError) as info:
  871. x = array([1, 2, 3, 4, 5])
  872. y = array([2, 2, 3, 4, 5])
  873. z = array([[1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 3, 2, 1],
  874. [1, 2, 2, 2, 1], [1, 2, 1, 2, 1]])
  875. RectBivariateSpline(x, y, z)
  876. assert "y must be strictly increasing" in str(info.value)
  877. with assert_raises(ValueError) as info:
  878. x = array([1, 2, 3, 4, 5])
  879. y = array([1, 2, 3, 4, 5])
  880. z = array([[1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 3, 2, 1],
  881. [1, 2, 2, 2, 1]])
  882. RectBivariateSpline(x, y, z)
  883. assert "x dimension of z must have same number of elements as x"\
  884. in str(info.value)
  885. with assert_raises(ValueError) as info:
  886. x = array([1, 2, 3, 4, 5])
  887. y = array([1, 2, 3, 4, 5])
  888. z = array([[1, 2, 1, 2], [1, 2, 1, 2], [1, 2, 3, 2],
  889. [1, 2, 2, 2], [1, 2, 1, 2]])
  890. RectBivariateSpline(x, y, z)
  891. assert "y dimension of z must have same number of elements as y"\
  892. in str(info.value)
  893. with assert_raises(ValueError) as info:
  894. x = array([1, 2, 3, 4, 5])
  895. y = array([1, 2, 3, 4, 5])
  896. z = array([[1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 3, 2, 1],
  897. [1, 2, 2, 2, 1], [1, 2, 1, 2, 1]])
  898. bbox = (-100, 100, -100)
  899. RectBivariateSpline(x, y, z, bbox=bbox)
  900. assert "bbox shape should be (4,)" in str(info.value)
  901. with assert_raises(ValueError) as info:
  902. RectBivariateSpline(x, y, z, s=-1.0)
  903. assert "s should be s >= 0.0" in str(info.value)
  904. def test_array_like_input(self):
  905. x = array([1, 2, 3, 4, 5])
  906. y = array([1, 2, 3, 4, 5])
  907. z = array([[1, 2, 1, 2, 1], [1, 2, 1, 2, 1], [1, 2, 3, 2, 1],
  908. [1, 2, 2, 2, 1], [1, 2, 1, 2, 1]])
  909. bbox = array([1, 5, 1, 5])
  910. spl1 = RectBivariateSpline(x, y, z, bbox=bbox)
  911. spl2 = RectBivariateSpline(x.tolist(), y.tolist(), z.tolist(),
  912. bbox=bbox.tolist())
  913. assert_array_almost_equal(spl1(1.0, 1.0), spl2(1.0, 1.0))
  914. def test_not_increasing_input(self):
  915. # gh-8565
  916. NSamp = 20
  917. Theta = np.random.uniform(0, np.pi, NSamp)
  918. Phi = np.random.uniform(0, 2 * np.pi, NSamp)
  919. Data = np.ones(NSamp)
  920. Interpolator = SmoothSphereBivariateSpline(Theta, Phi, Data, s=3.5)
  921. NLon = 6
  922. NLat = 3
  923. GridPosLats = np.arange(NLat) / NLat * np.pi
  924. GridPosLons = np.arange(NLon) / NLon * 2 * np.pi
  925. # No error
  926. Interpolator(GridPosLats, GridPosLons)
  927. nonGridPosLats = GridPosLats.copy()
  928. nonGridPosLats[2] = 0.001
  929. with assert_raises(ValueError) as exc_info:
  930. Interpolator(nonGridPosLats, GridPosLons)
  931. assert "x must be strictly increasing" in str(exc_info.value)
  932. nonGridPosLons = GridPosLons.copy()
  933. nonGridPosLons[2] = 0.001
  934. with assert_raises(ValueError) as exc_info:
  935. Interpolator(GridPosLats, nonGridPosLons)
  936. assert "y must be strictly increasing" in str(exc_info.value)
  937. class TestRectSphereBivariateSpline:
  938. def test_defaults(self):
  939. y = linspace(0.01, 2*pi-0.01, 7)
  940. x = linspace(0.01, pi-0.01, 7)
  941. z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
  942. [1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
  943. [1,2,1,2,1,2,1]])
  944. lut = RectSphereBivariateSpline(x,y,z)
  945. assert_array_almost_equal(lut(x,y),z)
  946. def test_evaluate(self):
  947. y = linspace(0.01, 2*pi-0.01, 7)
  948. x = linspace(0.01, pi-0.01, 7)
  949. z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
  950. [1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
  951. [1,2,1,2,1,2,1]])
  952. lut = RectSphereBivariateSpline(x,y,z)
  953. yi = [0.2, 1, 2.3, 2.35, 3.0, 3.99, 5.25]
  954. xi = [1.5, 0.4, 1.1, 0.45, 0.2345, 1., 0.0001]
  955. zi = lut.ev(xi, yi)
  956. zi2 = array([lut(xp, yp)[0,0] for xp, yp in zip(xi, yi)])
  957. assert_almost_equal(zi, zi2)
  958. def test_invalid_input(self):
  959. data = np.dot(np.atleast_2d(90. - np.linspace(-80., 80., 18)).T,
  960. np.atleast_2d(180. - np.abs(np.linspace(0., 350., 9)))).T
  961. with assert_raises(ValueError) as exc_info:
  962. lats = np.linspace(-1, 170, 9) * np.pi / 180.
  963. lons = np.linspace(0, 350, 18) * np.pi / 180.
  964. RectSphereBivariateSpline(lats, lons, data)
  965. assert "u should be between (0, pi)" in str(exc_info.value)
  966. with assert_raises(ValueError) as exc_info:
  967. lats = np.linspace(10, 181, 9) * np.pi / 180.
  968. lons = np.linspace(0, 350, 18) * np.pi / 180.
  969. RectSphereBivariateSpline(lats, lons, data)
  970. assert "u should be between (0, pi)" in str(exc_info.value)
  971. with assert_raises(ValueError) as exc_info:
  972. lats = np.linspace(10, 170, 9) * np.pi / 180.
  973. lons = np.linspace(-181, 10, 18) * np.pi / 180.
  974. RectSphereBivariateSpline(lats, lons, data)
  975. assert "v[0] should be between [-pi, pi)" in str(exc_info.value)
  976. with assert_raises(ValueError) as exc_info:
  977. lats = np.linspace(10, 170, 9) * np.pi / 180.
  978. lons = np.linspace(-10, 360, 18) * np.pi / 180.
  979. RectSphereBivariateSpline(lats, lons, data)
  980. assert "v[-1] should be v[0] + 2pi or less" in str(exc_info.value)
  981. with assert_raises(ValueError) as exc_info:
  982. lats = np.linspace(10, 170, 9) * np.pi / 180.
  983. lons = np.linspace(10, 350, 18) * np.pi / 180.
  984. RectSphereBivariateSpline(lats, lons, data, s=-1)
  985. assert "s should be positive" in str(exc_info.value)
  986. def test_derivatives_grid(self):
  987. y = linspace(0.01, 2*pi-0.01, 7)
  988. x = linspace(0.01, pi-0.01, 7)
  989. z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
  990. [1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
  991. [1,2,1,2,1,2,1]])
  992. lut = RectSphereBivariateSpline(x,y,z)
  993. y = linspace(0.02, 2*pi-0.02, 7)
  994. x = linspace(0.02, pi-0.02, 7)
  995. assert_allclose(lut(x, y, dtheta=1), _numdiff_2d(lut, x, y, dx=1),
  996. rtol=1e-4, atol=1e-4)
  997. assert_allclose(lut(x, y, dphi=1), _numdiff_2d(lut, x, y, dy=1),
  998. rtol=1e-4, atol=1e-4)
  999. assert_allclose(lut(x, y, dtheta=1, dphi=1), _numdiff_2d(lut, x, y, dx=1, dy=1, eps=1e-6),
  1000. rtol=1e-3, atol=1e-3)
  1001. assert_array_equal(lut(x, y, dtheta=1),
  1002. lut.partial_derivative(1, 0)(x, y))
  1003. assert_array_equal(lut(x, y, dphi=1),
  1004. lut.partial_derivative(0, 1)(x, y))
  1005. assert_array_equal(lut(x, y, dtheta=1, dphi=1),
  1006. lut.partial_derivative(1, 1)(x, y))
  1007. assert_array_equal(lut(x, y, dtheta=1, grid=False),
  1008. lut.partial_derivative(1, 0)(x, y, grid=False))
  1009. assert_array_equal(lut(x, y, dphi=1, grid=False),
  1010. lut.partial_derivative(0, 1)(x, y, grid=False))
  1011. assert_array_equal(lut(x, y, dtheta=1, dphi=1, grid=False),
  1012. lut.partial_derivative(1, 1)(x, y, grid=False))
  1013. def test_derivatives(self):
  1014. y = linspace(0.01, 2*pi-0.01, 7)
  1015. x = linspace(0.01, pi-0.01, 7)
  1016. z = array([[1,2,1,2,1,2,1],[1,2,1,2,1,2,1],[1,2,3,2,1,2,1],
  1017. [1,2,2,2,1,2,1],[1,2,1,2,1,2,1],[1,2,2,2,1,2,1],
  1018. [1,2,1,2,1,2,1]])
  1019. lut = RectSphereBivariateSpline(x,y,z)
  1020. y = linspace(0.02, 2*pi-0.02, 7)
  1021. x = linspace(0.02, pi-0.02, 7)
  1022. assert_equal(lut(x, y, dtheta=1, grid=False).shape, x.shape)
  1023. assert_allclose(lut(x, y, dtheta=1, grid=False),
  1024. _numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dx=1),
  1025. rtol=1e-4, atol=1e-4)
  1026. assert_allclose(lut(x, y, dphi=1, grid=False),
  1027. _numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dy=1),
  1028. rtol=1e-4, atol=1e-4)
  1029. assert_allclose(lut(x, y, dtheta=1, dphi=1, grid=False),
  1030. _numdiff_2d(lambda x,y: lut(x,y,grid=False), x, y, dx=1, dy=1, eps=1e-6),
  1031. rtol=1e-3, atol=1e-3)
  1032. def test_invalid_input_2(self):
  1033. data = np.dot(np.atleast_2d(90. - np.linspace(-80., 80., 18)).T,
  1034. np.atleast_2d(180. - np.abs(np.linspace(0., 350., 9)))).T
  1035. with assert_raises(ValueError) as exc_info:
  1036. lats = np.linspace(0, 170, 9) * np.pi / 180.
  1037. lons = np.linspace(0, 350, 18) * np.pi / 180.
  1038. RectSphereBivariateSpline(lats, lons, data)
  1039. assert "u should be between (0, pi)" in str(exc_info.value)
  1040. with assert_raises(ValueError) as exc_info:
  1041. lats = np.linspace(10, 180, 9) * np.pi / 180.
  1042. lons = np.linspace(0, 350, 18) * np.pi / 180.
  1043. RectSphereBivariateSpline(lats, lons, data)
  1044. assert "u should be between (0, pi)" in str(exc_info.value)
  1045. with assert_raises(ValueError) as exc_info:
  1046. lats = np.linspace(10, 170, 9) * np.pi / 180.
  1047. lons = np.linspace(-181, 10, 18) * np.pi / 180.
  1048. RectSphereBivariateSpline(lats, lons, data)
  1049. assert "v[0] should be between [-pi, pi)" in str(exc_info.value)
  1050. with assert_raises(ValueError) as exc_info:
  1051. lats = np.linspace(10, 170, 9) * np.pi / 180.
  1052. lons = np.linspace(-10, 360, 18) * np.pi / 180.
  1053. RectSphereBivariateSpline(lats, lons, data)
  1054. assert "v[-1] should be v[0] + 2pi or less" in str(exc_info.value)
  1055. with assert_raises(ValueError) as exc_info:
  1056. lats = np.linspace(10, 170, 9) * np.pi / 180.
  1057. lons = np.linspace(10, 350, 18) * np.pi / 180.
  1058. RectSphereBivariateSpline(lats, lons, data, s=-1)
  1059. assert "s should be positive" in str(exc_info.value)
  1060. def test_array_like_input(self):
  1061. y = linspace(0.01, 2 * pi - 0.01, 7)
  1062. x = linspace(0.01, pi - 0.01, 7)
  1063. z = array([[1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1],
  1064. [1, 2, 3, 2, 1, 2, 1],
  1065. [1, 2, 2, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1],
  1066. [1, 2, 2, 2, 1, 2, 1],
  1067. [1, 2, 1, 2, 1, 2, 1]])
  1068. # np.array input
  1069. spl1 = RectSphereBivariateSpline(x, y, z)
  1070. # list input
  1071. spl2 = RectSphereBivariateSpline(x.tolist(), y.tolist(), z.tolist())
  1072. assert_array_almost_equal(spl1(x, y), spl2(x, y))
  1073. def test_negative_evaluation(self):
  1074. lats = np.array([25, 30, 35, 40, 45])
  1075. lons = np.array([-90, -85, -80, -75, 70])
  1076. mesh = np.meshgrid(lats, lons)
  1077. data = mesh[0] + mesh[1] # lon + lat value
  1078. lat_r = np.radians(lats)
  1079. lon_r = np.radians(lons)
  1080. interpolator = RectSphereBivariateSpline(lat_r, lon_r, data)
  1081. query_lat = np.radians(np.array([35, 37.5]))
  1082. query_lon = np.radians(np.array([-80, -77.5]))
  1083. data_interp = interpolator(query_lat, query_lon)
  1084. ans = np.array([[-45.0, -42.480862],
  1085. [-49.0625, -46.54315]])
  1086. assert_array_almost_equal(data_interp, ans)
  1087. def test_pole_continuity_gh_14591(self):
  1088. # regression test for https://github.com/scipy/scipy/issues/14591
  1089. # with pole_continuty=(True, True), the internal work array size
  1090. # was too small, leading to a FITPACK data validation error.
  1091. # The reproducer in gh-14591 was using a NetCDF4 file with
  1092. # 361x507 arrays, so here we trivialize array sizes to a minimum
  1093. # which still demonstrates the issue.
  1094. u = np.arange(1, 10) * np.pi / 10
  1095. v = np.arange(1, 10) * np.pi / 10
  1096. r = np.zeros((9, 9))
  1097. for p in [(True, True), (True, False), (False, False)]:
  1098. RectSphereBivariateSpline(u, v, r, s=0, pole_continuity=p)
  1099. def _numdiff_2d(func, x, y, dx=0, dy=0, eps=1e-8):
  1100. if dx == 0 and dy == 0:
  1101. return func(x, y)
  1102. elif dx == 1 and dy == 0:
  1103. return (func(x + eps, y) - func(x - eps, y)) / (2*eps)
  1104. elif dx == 0 and dy == 1:
  1105. return (func(x, y + eps) - func(x, y - eps)) / (2*eps)
  1106. elif dx == 1 and dy == 1:
  1107. return (func(x + eps, y + eps) - func(x - eps, y + eps)
  1108. - func(x + eps, y - eps) + func(x - eps, y - eps)) / (2*eps)**2
  1109. else:
  1110. raise ValueError("invalid derivative order")
  1111. class Test_DerivedBivariateSpline(object):
  1112. """Test the creation, usage, and attribute access of the (private)
  1113. _DerivedBivariateSpline class.
  1114. """
  1115. def setup_method(self):
  1116. x = np.concatenate(list(zip(range(10), range(10))))
  1117. y = np.concatenate(list(zip(range(10), range(1, 11))))
  1118. z = np.concatenate((np.linspace(3, 1, 10), np.linspace(1, 3, 10)))
  1119. with suppress_warnings() as sup:
  1120. sup.record(UserWarning, "\nThe coefficients of the spline")
  1121. self.lut_lsq = LSQBivariateSpline(x, y, z,
  1122. linspace(0.5, 19.5, 4),
  1123. linspace(1.5, 20.5, 4),
  1124. eps=1e-2)
  1125. self.lut_smooth = SmoothBivariateSpline(x, y, z)
  1126. xx = linspace(0, 1, 20)
  1127. yy = xx + 1.0
  1128. zz = array([np.roll(z, i) for i in range(z.size)])
  1129. self.lut_rect = RectBivariateSpline(xx, yy, zz)
  1130. self.orders = list(itertools.product(range(3), range(3)))
  1131. def test_creation_from_LSQ(self):
  1132. for nux, nuy in self.orders:
  1133. lut_der = self.lut_lsq.partial_derivative(nux, nuy)
  1134. a = lut_der(3.5, 3.5, grid=False)
  1135. b = self.lut_lsq(3.5, 3.5, dx=nux, dy=nuy, grid=False)
  1136. assert_equal(a, b)
  1137. def test_creation_from_Smooth(self):
  1138. for nux, nuy in self.orders:
  1139. lut_der = self.lut_smooth.partial_derivative(nux, nuy)
  1140. a = lut_der(5.5, 5.5, grid=False)
  1141. b = self.lut_smooth(5.5, 5.5, dx=nux, dy=nuy, grid=False)
  1142. assert_equal(a, b)
  1143. def test_creation_from_Rect(self):
  1144. for nux, nuy in self.orders:
  1145. lut_der = self.lut_rect.partial_derivative(nux, nuy)
  1146. a = lut_der(0.5, 1.5, grid=False)
  1147. b = self.lut_rect(0.5, 1.5, dx=nux, dy=nuy, grid=False)
  1148. assert_equal(a, b)
  1149. def test_invalid_attribute_fp(self):
  1150. der = self.lut_rect.partial_derivative(1, 1)
  1151. with assert_raises(AttributeError):
  1152. der.fp
  1153. def test_invalid_attribute_get_residual(self):
  1154. der = self.lut_smooth.partial_derivative(1, 1)
  1155. with assert_raises(AttributeError):
  1156. der.get_residual()