1010
1111
1212class TestColumnInterpolation (unittest .TestCase ):
13- def interpolate (self , x_target , x_src ):
13+ def interpolate (self , x_target , x_src , rising = None ):
1414 x_target = np .array (x_target )
1515 x_src = np .array (x_src )
1616 fx_src = np .empty (x_src .shape )
@@ -19,13 +19,15 @@ def interpolate(self, x_target, x_src):
1919 extrap_direct = vinterp ._TestableDirectionExtrapKernel ()
2020
2121 r1 = stratify .interpolate (x_target , x_src , fx_src ,
22- interpolation = index_interp ,
23- extrapolation = extrap_direct )
22+ rising = rising ,
23+ interpolation = index_interp ,
24+ extrapolation = extrap_direct )
2425
25- r2 = stratify .interpolate (- 1 * x_target , - 1 * x_src , fx_src ,
26- rising = False , interpolation = index_interp ,
27- extrapolation = extrap_direct )
28- assert_array_equal (r1 , r2 )
26+ if rising is not None :
27+ r2 = stratify .interpolate (- 1 * x_target , - 1 * x_src , fx_src ,
28+ rising = not rising , interpolation = index_interp ,
29+ extrapolation = extrap_direct )
30+ assert_array_equal (r1 , r2 )
2931
3032 return r1
3133
@@ -46,7 +48,7 @@ def test_lower_extrap_only(self):
4648 assert_array_equal (r , [- np .inf , - np .inf , - np .inf ])
4749
4850 def test_upper_extrap_only (self ):
49- r = self .interpolate ([1 , 2 , 3 ], [- 4 , - 5 ])
51+ r = self .interpolate ([1 , 2 , 3 ], [- 4 , - 5 ], rising = True )
5052 assert_array_equal (r , [np .inf , np .inf , np .inf ])
5153
5254 def test_extrap_on_both_sides_only (self ):
@@ -65,7 +67,7 @@ def test_nan_in_target(self):
6567 def test_nan_in_src (self ):
6668 msg = 'The source coordinate .* NaN'
6769 with self .assertRaisesRegexp (ValueError , msg ):
68- self .interpolate ([1 ], [0 , np .nan ])
70+ self .interpolate ([1 ], [0 , np .nan ], rising = True )
6971
7072 def test_all_nan_in_src (self ):
7173 r = self .interpolate ([1 , 2 , 3 , 4 ], [np .nan , np .nan , np .nan ])
@@ -86,13 +88,13 @@ def test_wrong_rising_target(self):
8688 assert_array_equal (r , [1 , np .inf ])
8789
8890 def test_wrong_rising_source (self ):
89- r = self .interpolate ([1 , 2 ], [2 , 1 ])
91+ r = self .interpolate ([1 , 2 ], [2 , 1 ], rising = True )
9092 assert_array_equal (r , [- np .inf , 0 ])
9193
9294 def test_wrong_rising_source_and_target (self ):
9395 # If we overshoot the first level, there is no hope,
9496 # so we end up extrapolating.
95- r = self .interpolate ([3 , 2 , 1 , 0 ], [2 , 1 ])
97+ r = self .interpolate ([3 , 2 , 1 , 0 ], [2 , 1 ], rising = True )
9698 assert_array_equal (r , [np .inf , np .inf , np .inf , np .inf ])
9799
98100 def test_non_monotonic_coordinate_interp (self ):
@@ -103,6 +105,20 @@ def test_non_monotonic_coordinate_extrap(self):
103105 result = self .interpolate ([0 , 15 , 16 , 17 , 5 , 15. , 25 ], [10. , 40 , 0 , 20 ])
104106 assert_array_equal (result , [- np .inf , 1 , 1 , 1 , 2 , 3 , np .inf ])
105107
108+ def test_length_one_interp (self ):
109+ r = self .interpolate ([1 ], [2 ], rising = True )
110+ assert_array_equal (r , [- np .inf ])
111+
112+ def test_auto_rising_not_enough_values (self ):
113+ with self .assertRaises (ValueError ):
114+ r = self .interpolate ([1 ], [2 ])
115+
116+ def test_auto_rising_equal_values (self ):
117+ # The code checks whether the first value is <= or equal to
118+ # the second. If it didn't, we'd end up with +inf, not -inf.
119+ r = self .interpolate ([1 ], [2 , 2 ])
120+ assert_array_equal (r , [- np .inf ])
121+
106122
107123class Test_INTERPOLATE_LINEAR (unittest .TestCase ):
108124 def interpolate (self , x_target ):
@@ -129,6 +145,19 @@ def test_high_precision(self):
129145 assert_array_almost_equal (self .interpolate ([1.123456789 ]),
130146 [11.23456789 ], decimal = 6 )
131147
148+ def test_single_point (self ):
149+ # Test that a single input point that falls exactly on the target
150+ # level triggers a shortcut that avoids the expectation of >=2 source
151+ # points.
152+ interpolation = stratify .INTERPOLATE_LINEAR
153+ extrapolation = vinterp ._TestableDirectionExtrapKernel ()
154+
155+ r = stratify .interpolate ([2 ], [2 ], [20 ],
156+ interpolation = interpolation ,
157+ extrapolation = extrapolation ,
158+ rising = True )
159+ self .assertEqual (r , 20 )
160+
132161
133162class Test_INTERPOLATE_NEAREST (unittest .TestCase ):
134163 def interpolate (self , x_target ):
@@ -140,8 +169,8 @@ def interpolate(self, x_target):
140169
141170 # Use -2 to test negative number support.
142171 return stratify .interpolate (np .array (x_target ) - 2 , x_src - 2 , fx_src ,
143- interpolation = interpolation ,
144- extrapolation = extrapolation )
172+ interpolation = interpolation ,
173+ extrapolation = extrapolation )
145174
146175 def test_on_the_mark (self ):
147176 assert_array_equal (self .interpolate ([0 , 1 , 2 , 3 , 4 ]),
@@ -167,8 +196,8 @@ def interpolate(self, x_target):
167196
168197 # Use -2 to test negative number support.
169198 return stratify .interpolate (np .array (x_target ) - 2 , x_src - 2 , fx_src ,
170- interpolation = interpolation ,
171- extrapolation = extrapolation )
199+ interpolation = interpolation ,
200+ extrapolation = extrapolation )
172201
173202 def test_below (self ):
174203 assert_array_equal (self .interpolate ([- 1 ]), [np .nan ])
@@ -187,8 +216,8 @@ def interpolate(self, x_target):
187216
188217 # Use -2 to test negative number support.
189218 return stratify .interpolate (np .array (x_target ) - 2 , x_src - 2 , fx_src ,
190- interpolation = interpolation ,
191- extrapolation = extrapolation )
219+ interpolation = interpolation ,
220+ extrapolation = extrapolation )
192221
193222 def test_below (self ):
194223 assert_array_equal (self .interpolate ([- 1 ]), [0. ])
@@ -197,6 +226,40 @@ def test_above(self):
197226 assert_array_equal (self .interpolate ([5 ]), [40 ])
198227
199228
229+ class Test_EXTRAPOLATE_LINEAR (unittest .TestCase ):
230+ def interpolate (self , x_target ):
231+ interpolation = vinterp ._TestableIndexInterpKernel ()
232+ extrapolation = stratify .EXTRAPOLATE_LINEAR
233+
234+ x_src = np .arange (5 )
235+ # To spice things up a bit, let's make x_src non-equal distance.
236+ x_src [4 ] = 9
237+ fx_src = 10 * x_src
238+
239+ # Use -2 to test negative number support.
240+ return stratify .interpolate (np .array (x_target ) - 2 , x_src - 2 , fx_src ,
241+ interpolation = interpolation ,
242+ extrapolation = extrapolation )
243+
244+ def test_below (self ):
245+ assert_array_equal (self .interpolate ([- 1 ]), [- 10. ])
246+
247+ def test_above (self ):
248+ assert_array_almost_equal (self .interpolate ([15.123 ]), [151.23 ])
249+
250+ def test_npts (self ):
251+ interpolation = vinterp ._TestableIndexInterpKernel ()
252+ extrapolation = stratify .EXTRAPOLATE_LINEAR
253+
254+ msg = (r'Linear extrapolation requires at least 2 '
255+ r'source points. Got 1.' )
256+
257+ with self .assertRaisesRegexp (ValueError , msg ):
258+ stratify .interpolate ([1 , 3. ], [2 ], [20 ],
259+ interpolation = interpolation ,
260+ extrapolation = extrapolation , rising = True )
261+
262+
200263class Test__Interpolator (unittest .TestCase ):
201264 def test_axis_m1 (self ):
202265 data = np .empty ([5 , 4 , 23 , 7 , 3 ])
0 commit comments