From b6e88e8bd690c7dedc4982384c992e9883cb529b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20R=C3=B6fer?= Date: Tue, 12 Aug 2025 09:38:59 +0200 Subject: [PATCH 1/4] Fixed MVN norm factor. --- gmr/mvn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmr/mvn.py b/gmr/mvn.py index 427ffa9d69..e3145f6748 100644 --- a/gmr/mvn.py +++ b/gmr/mvn.py @@ -185,7 +185,7 @@ def to_norm_factor_and_exponents(self, X): if self.norm is None: # Suppress a determinant of 0 to avoid numerical problems L_det = max(sp.linalg.det(L), np.finfo(L.dtype).eps) - self.norm = 0.5 / np.pi ** (0.5 * n_features) / L_det + self.norm = (2 * np.pi) ** (-0.5 * n_features) / L_det # Solve L x = (X - mean)^T for x with triangular L # (LL^T = Sigma), that is, x = L^T^-1 (X - mean)^T. From badc1cae284fc46726f89242420816ad7fe56696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20R=C3=B6fer?= Date: Wed, 13 Aug 2025 10:55:31 +0200 Subject: [PATCH 2/4] Added new MVN density test with 3D data. --- gmr/tests/test_mvn.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/gmr/tests/test_mvn.py b/gmr/tests/test_mvn.py index 319966cd12..7621588054 100644 --- a/gmr/tests/test_mvn.py +++ b/gmr/tests/test_mvn.py @@ -8,7 +8,6 @@ mean = np.array([0.0, 1.0]) covariance = np.array([[0.5, -1.0], [-1.0, 5.0]]) - class AxisStub: def __init__(self): self.count = 0 @@ -75,13 +74,18 @@ def test_sample_confidence_region(): def test_probability_density(): """Test PDF of MVN.""" + mean = np.array([0.0, 1.0, 2.0]) + covariance = np.array([[ 0.5, -1.0, 0.0], + [-1.0, 5.0, -0.5], + [ 0.0, -0.5, 1.0]]) + random_state = check_random_state(0) mvn = MVN(mean, covariance, random_state=random_state) x = np.linspace(-100, 100, 201) - X = np.vstack(list(map(np.ravel, np.meshgrid(x, x)))).T + X = np.vstack(list(map(np.ravel, np.meshgrid(x, x, x)))).T p = mvn.to_probability_density(X) - approx_int = np.sum(p) * ((x[-1] - x[0]) / 201) ** 2 + approx_int = np.sum(p) assert np.abs(1.0 - approx_int) < 0.01 From c18c5e52b4c952556ef6c95846e5de8b634c7146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20R=C3=B6fer?= Date: Wed, 13 Aug 2025 10:56:16 +0200 Subject: [PATCH 3/4] Fixed norm calculation. Test revealed it to be faulty. --- gmr/mvn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmr/mvn.py b/gmr/mvn.py index 427ffa9d69..d9778d24d5 100644 --- a/gmr/mvn.py +++ b/gmr/mvn.py @@ -185,7 +185,7 @@ def to_norm_factor_and_exponents(self, X): if self.norm is None: # Suppress a determinant of 0 to avoid numerical problems L_det = max(sp.linalg.det(L), np.finfo(L.dtype).eps) - self.norm = 0.5 / np.pi ** (0.5 * n_features) / L_det + self.norm = (2 * np.pi) ** (-n_features/2) * (1 / L_det) # Solve L x = (X - mean)^T for x with triangular L # (LL^T = Sigma), that is, x = L^T^-1 (X - mean)^T. From a83f39ee46ee1f9dc974903c04073b103df7f2f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20R=C3=B6fer?= Date: Wed, 13 Aug 2025 11:28:37 +0200 Subject: [PATCH 4/4] Removed unnecessary "1 /" in MVN norm --- gmr/mvn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gmr/mvn.py b/gmr/mvn.py index d9778d24d5..023d25b25a 100644 --- a/gmr/mvn.py +++ b/gmr/mvn.py @@ -185,7 +185,7 @@ def to_norm_factor_and_exponents(self, X): if self.norm is None: # Suppress a determinant of 0 to avoid numerical problems L_det = max(sp.linalg.det(L), np.finfo(L.dtype).eps) - self.norm = (2 * np.pi) ** (-n_features/2) * (1 / L_det) + self.norm = (2 * np.pi) ** (-n_features/2) / L_det # Solve L x = (X - mean)^T for x with triangular L # (LL^T = Sigma), that is, x = L^T^-1 (X - mean)^T.