@@ -170,3 +170,141 @@ def test_morphsqueeze_extrapolate(user_filesystem, squeeze_coeffs, wmsg_gen):
170170 )
171171 with pytest .warns (UserWarning , match = expected_wmsg ):
172172 single_morph (parser , opts , pargs , stdout_flag = False )
173+
174+
175+ @pytest .mark .parametrize (
176+ "squeeze_coeffs, x_morph" ,
177+ [
178+ ({"a0" : 0.01 , "a1" : 0.01 , "a2" : - 0.1 }, np .linspace (0 , 10 , 101 )),
179+ ],
180+ )
181+ def test_non_strictly_increasing_squeeze (squeeze_coeffs , x_morph ):
182+ x_target = x_morph
183+ y_target = np .sin (x_target )
184+ coeffs = [squeeze_coeffs [f"a{ i } " ] for i in range (len (squeeze_coeffs ))]
185+ squeeze_polynomial = Polynomial (coeffs )
186+ x_squeezed = x_morph + squeeze_polynomial (x_morph )
187+ # non-strictly-increasing
188+ assert not np .all (np .sign (np .diff (x_squeezed )) > 0 )
189+ y_morph = np .sin (x_squeezed )
190+ # all zero initial guess
191+ morph_results = morphpy .morph_arrays (
192+ np .array ([x_morph , y_morph ]).T ,
193+ np .array ([x_target , y_target ]).T ,
194+ squeeze = [0 , 0 , 0 ],
195+ apply = True ,
196+ )
197+ _ , y_morph_actual = morph_results [1 ].T # noqa: F841
198+ y_morph_expected = np .sin (x_morph ) # noqa: F841
199+ # squeeze morph extrapolates.
200+ # Need to extract extrap_index from morph_results to examine
201+ # the convergence.
202+ # assert np.allclose(y_morph_actual, y_morph_expected, atol=1e-3)
203+ # Raise warning when called without --check-increase
204+ with pytest .warns () as w :
205+ morph_results = morphpy .morph_arrays (
206+ np .array ([x_morph , y_morph ]).T ,
207+ np .array ([x_target , y_target ]).T ,
208+ squeeze = [0.01 , 0.01 , - 0.1 ],
209+ apply = True ,
210+ )
211+ assert w [0 ].category is UserWarning
212+ actual_wmsg = " " .join ([str (w [i ].message ) for i in range (len (w ))])
213+ expected_wmsg = (
214+ "Warning: The squeeze morph has interpolated your morphed "
215+ "function from a non-monotonically increasing grid. "
216+ )
217+ assert expected_wmsg in actual_wmsg
218+ _ , y_morph_actual = morph_results [1 ].T # noqa: F841
219+ y_morph_expected = np .sin (x_morph ) # noqa: F841
220+ # squeeze morph extrapolates.
221+ # Need to extract extrap_index from morph_results to examine
222+ # the convergence.
223+ # assert np.allclose(y_morph_actual, y_morph_expected, atol=1e-3)
224+ # System exits when called with --check-increase
225+ with pytest .raises (SystemExit ) as excinfo :
226+ morphpy .morph_arrays (
227+ np .array ([x_morph , y_morph ]).T ,
228+ np .array ([x_target , y_target ]).T ,
229+ squeeze = [0.01 , 0.009 , - 0.1 ],
230+ check_increase = True ,
231+ )
232+ actual_emsg = str (excinfo .value )
233+ expected_emsg = "2"
234+ assert expected_emsg == actual_emsg
235+
236+
237+ @pytest .mark .parametrize (
238+ "squeeze_coeffs, x_morph" ,
239+ [
240+ ({"a0" : - 1 , "a1" : - 1 , "a2" : 2 }, np .linspace (- 1 , 1 , 101 )),
241+ (
242+ {"a0" : - 1 , "a1" : - 1 , "a2" : 0 , "a3" : 0 , "a4" : 2 },
243+ np .linspace (- 1 , 1 , 101 ),
244+ ),
245+ ],
246+ )
247+ def test_sort_squeeze_bad (user_filesystem , squeeze_coeffs , x_morph ):
248+ # call in .py without --check-increase
249+ x_target = x_morph
250+ y_target = np .sin (x_target )
251+ coeffs = [squeeze_coeffs [f"a{ i } " ] for i in range (len (squeeze_coeffs ))]
252+ squeeze_polynomial = Polynomial (coeffs )
253+ x_squeezed = x_morph + squeeze_polynomial (x_morph )
254+ y_morph = np .sin (x_squeezed )
255+ morph = MorphSqueeze ()
256+ morph .squeeze = squeeze_coeffs
257+ with pytest .warns () as w :
258+ morphpy .morph_arrays (
259+ np .array ([x_morph , y_morph ]).T ,
260+ np .array ([x_target , y_target ]).T ,
261+ squeeze = coeffs ,
262+ apply = True ,
263+ )
264+ assert len (w ) == 1
265+ assert w [0 ].category is UserWarning
266+ actual_wmsg = str (w [0 ].message )
267+ expected_wmsg = (
268+ "Warning: The squeeze morph has interpolated your morphed "
269+ "function from a non-monotonically increasing grid. "
270+ )
271+ assert expected_wmsg in actual_wmsg
272+
273+ # call in CLI without --check-increase
274+ morph_file , target_file = create_morph_data_file (
275+ user_filesystem / "cwd_dir" , x_morph , y_morph , x_target , y_target
276+ )
277+ parser = create_option_parser ()
278+ (opts , pargs ) = parser .parse_args (
279+ [
280+ "--squeeze" ,
281+ "," .join (map (str , coeffs )),
282+ f"{ morph_file .as_posix ()} " ,
283+ f"{ target_file .as_posix ()} " ,
284+ "--apply" ,
285+ "-n" ,
286+ ]
287+ )
288+ with pytest .warns (UserWarning ) as w :
289+ single_morph (parser , opts , pargs , stdout_flag = False )
290+ assert len (w ) == 1
291+ actual_wmsg = str (w [0 ].message )
292+ assert expected_wmsg in actual_wmsg
293+
294+
295+ def test_handle_duplicates ():
296+ unq_x = np .linspace (0 , 11 , 10 )
297+ iter = 10
298+ morph = MorphSqueeze ()
299+ for i in range (iter ):
300+ actual_x = np .random .choice (unq_x , size = 20 )
301+ actual_y = np .sin (actual_x )
302+ actual_handled_x , actual_handled_y = morph ._handle_duplicates (
303+ actual_x , actual_y
304+ )
305+ expected_handled_x = np .unique (actual_x )
306+ expected_handled_y = np .array (
307+ [actual_y [actual_x == x ].mean () for x in expected_handled_x ]
308+ )
309+ assert np .allclose (actual_handled_x , expected_handled_x )
310+ assert np .allclose (actual_handled_y , expected_handled_y )
0 commit comments