-
Notifications
You must be signed in to change notification settings - Fork 19
Squeeze morph warning handling #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| **Added:** | ||
|
|
||
| * Warnings added to `squeeze` morph if the squeeze causes the grid to become non-monotonic. | ||
|
|
||
| **Changed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Deprecated:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Removed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Fixed:** | ||
|
|
||
| * <news item> | ||
|
|
||
| **Security:** | ||
|
|
||
| * <news item> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -170,3 +170,110 @@ def test_morphsqueeze_extrapolate(user_filesystem, squeeze_coeffs, wmsg_gen): | |
| ) | ||
| with pytest.warns(UserWarning, match=expected_wmsg): | ||
| single_morph(parser, opts, pargs, stdout_flag=False) | ||
|
|
||
|
|
||
| def test_non_unique_grid(): | ||
| squeeze_coeffs = {"a0": 0.01, "a1": 0.01, "a2": -0.1} | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| x_grid = np.linspace(0, 10, 101) | ||
|
|
||
| coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))] | ||
| squeeze_polynomial = Polynomial(coeffs) | ||
| x_morph = x_grid + squeeze_polynomial(x_grid) | ||
| x_gradient = np.diff(x_morph) | ||
| x_gradient_sign = np.sign(x_gradient) | ||
| # non-strictly increasing means the gradient becomes 0 or negative | ||
| assert not np.all(x_gradient_sign > 0) | ||
|
|
||
| x_target = np.linspace(min(x_morph), max(x_morph), len(x_morph)) | ||
| y_target = np.sin(x_target) | ||
|
|
||
| y_morph = np.sin(x_morph) | ||
| # apply no squeeze, but the morph should sort the function | ||
| _, table = morphpy.morph_arrays( | ||
| np.array([x_morph, y_morph]).T, | ||
| np.array([x_target, y_target]).T, | ||
| squeeze=[0, 0, 0], | ||
| apply=True, | ||
| ) | ||
| x_refined, _ = table[:, 0], table[:, 1] | ||
|
|
||
| # grid should be properly sorted | ||
| assert np.allclose(x_refined, x_target) | ||
| # note that the function itself may be distorted | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "squeeze_coeffs, x_morph", | ||
| [ | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # The following squeezes make the function non-monotonic | ||
|
||
| ({"a0": -1, "a1": -1, "a2": 2}, np.linspace(-1, 1, 101)), | ||
| ( | ||
| {"a0": -1, "a1": -1, "a2": 0, "a3": 0, "a4": 2}, | ||
| np.linspace(-1, 1, 101), | ||
| ), | ||
| ], | ||
| ) | ||
| def test_squeeze_warnings(user_filesystem, squeeze_coeffs, x_morph): | ||
| # call in .py | ||
| x_target = x_morph | ||
| y_target = np.sin(x_target) | ||
| coeffs = [squeeze_coeffs[f"a{i}"] for i in range(len(squeeze_coeffs))] | ||
|
||
| squeeze_polynomial = Polynomial(coeffs) | ||
| x_squeezed = x_morph + squeeze_polynomial(x_morph) | ||
| y_morph = np.sin(x_squeezed) | ||
| morph = MorphSqueeze() | ||
| morph.squeeze = squeeze_coeffs | ||
| with pytest.warns() as w: | ||
|
||
| morphpy.morph_arrays( | ||
| np.array([x_morph, y_morph]).T, | ||
| np.array([x_target, y_target]).T, | ||
| squeeze=coeffs, | ||
| apply=True, | ||
| ) | ||
| assert len(w) == 1 | ||
| assert w[0].category is UserWarning | ||
| actual_wmsg = str(w[0].message) | ||
| expected_wmsg = ( | ||
| "Warning: The squeeze morph has interpolated your morphed " | ||
| "function from a non-monotonically increasing grid. " | ||
| "This can result in strange behavior in certain " | ||
| "grid regions." | ||
| ) | ||
| assert expected_wmsg in actual_wmsg | ||
|
|
||
| # call in CLI | ||
| morph_file, target_file = create_morph_data_file( | ||
| user_filesystem / "cwd_dir", x_morph, y_morph, x_target, y_target | ||
| ) | ||
| parser = create_option_parser() | ||
| (opts, pargs) = parser.parse_args( | ||
| [ | ||
| "--squeeze", | ||
| ",".join(map(str, coeffs)), | ||
| f"{morph_file.as_posix()}", | ||
| f"{target_file.as_posix()}", | ||
| "--apply", | ||
| "-n", | ||
| ] | ||
| ) | ||
| with pytest.warns(UserWarning) as w: | ||
sbillinge marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| single_morph(parser, opts, pargs, stdout_flag=False) | ||
| assert len(w) == 1 | ||
| actual_wmsg = str(w[0].message) | ||
| assert expected_wmsg in actual_wmsg | ||
|
|
||
|
|
||
| def test_handle_duplicates(): | ||
| x_choices = np.linspace(0, 10, 11) | ||
| iter = 10 | ||
| morph = MorphSqueeze() | ||
sbillinge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| for i in range(iter): | ||
| x_sampled = np.random.choice(x_choices, size=20) | ||
| y_sampled = np.sin(x_sampled) | ||
| x_handled, y_handled = morph._handle_duplicates(x_sampled, y_sampled) | ||
| x_target = np.unique(x_sampled) | ||
| y_target = np.array( | ||
| [y_sampled[x_sampled == x].mean() for x in x_target] | ||
| ) | ||
| assert np.allclose(x_handled, x_target) | ||
| assert np.allclose(y_handled, y_target) | ||
Uh oh!
There was an error while loading. Please reload this page.