From 61b41666b23f757d503312e9ca975a9fa766ccaa Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Thu, 30 Jul 2026 11:04:55 +0200 Subject: [PATCH 1/2] Reject masked manifold EMA weights --- src/pyrecest/filters/manifold_exponential_moving_average.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pyrecest/filters/manifold_exponential_moving_average.py b/src/pyrecest/filters/manifold_exponential_moving_average.py index 1576d412f4..a78172dbf6 100644 --- a/src/pyrecest/filters/manifold_exponential_moving_average.py +++ b/src/pyrecest/filters/manifold_exponential_moving_average.py @@ -53,6 +53,8 @@ def __init__( @staticmethod def _validate_alpha(alpha: float) -> float: message = "alpha must be a real scalar between 0 and 1" + if np.ma.is_masked(alpha): + raise TypeError(message) try: alpha_array = np.asarray(alpha) except (TypeError, ValueError) as exc: From 96c3a8fcb8f40e2f96d4363f45a1cbe270e90e38 Mon Sep 17 00:00:00 2001 From: Florian Pfaff <6773539+FlorianPfaff@users.noreply.github.com> Date: Thu, 30 Jul 2026 11:05:32 +0200 Subject: [PATCH 2/2] Test masked manifold EMA weight validation --- ...est_manifold_exponential_moving_average.py | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/filters/test_manifold_exponential_moving_average.py b/tests/filters/test_manifold_exponential_moving_average.py index b221ce8cd1..f9e5bceedb 100644 --- a/tests/filters/test_manifold_exponential_moving_average.py +++ b/tests/filters/test_manifold_exponential_moving_average.py @@ -103,6 +103,35 @@ def test_alpha_rejects_boolean_values(self): with self.assertRaisesRegex(TypeError, "real scalar"): ema.alpha = True + def test_alpha_rejects_masked_values_without_changing_current_weight(self): + masked_values = ( + np.ma.masked, + np.ma.array(0.25, mask=True), + ) + for alpha in masked_values: + with self.subTest(alpha=alpha): + with self.assertRaisesRegex(TypeError, "real scalar"): + ManifoldExponentialMovingAverage( + initial_state=0.0, + alpha=alpha, + phi=_phi_so2, + phi_inv=_phi_inv_so2, + ) + + ema = ManifoldExponentialMovingAverage( + initial_state=0.0, + alpha=np.ma.array(0.5, mask=False), + phi=_phi_so2, + phi_inv=_phi_inv_so2, + ) + self.assertEqual(ema.alpha, 0.5) + + for alpha in masked_values: + with self.subTest(alpha=alpha): + with self.assertRaisesRegex(TypeError, "real scalar"): + ema.alpha = alpha + self.assertEqual(ema.alpha, 0.5) + def test_alpha_rejects_text_values(self): for alpha in ("0.5", b"0.5", np.array("0.5")): with self.subTest(alpha=alpha):