|
8 | 8 | from pyest.sensors import ConvexPolyhedralFieldOfView |
9 | 9 | from pyest.utils import fail |
10 | 10 | import pytest |
| 11 | +from pyest.metrics import max_covariance_ratio |
11 | 12 |
|
12 | 13 |
|
13 | 14 | def test_gm_equal_weights(): |
@@ -555,6 +556,57 @@ def test_init_mismatch_fail(): |
555 | 556 |
|
556 | 557 | fail(gm.GaussianMixture, ValueError, w, m, P) |
557 | 558 |
|
| 559 | +def test_cov(): |
| 560 | + # Initial covariance matrix P0 (6×6) |
| 561 | + P0 = np.array([ |
| 562 | + [2.25e-06, 0, 0, 0, 0, 0], |
| 563 | + [0, 2.25e-06, 0, 0, 0, 0], |
| 564 | + [0, 0, 2.25e-06, 0, 0, 0], |
| 565 | + [0, 0, 0, 1.77777778e-14, 0, 0], |
| 566 | + [0, 0, 0, 0, 1.77777778e-14, 0], |
| 567 | + [0, 0, 0, 0, 0, 1.77777778e-14] |
| 568 | + ]) |
| 569 | + |
| 570 | + # Initial large mean vector m0 |
| 571 | + m0 = np.array([ |
| 572 | + -3.95911227e+05, -1.80422801e+05, -8.03243134e+04, |
| 573 | + 5.48813474e-01, -1.02480997e+00, -5.93612009e-01 |
| 574 | + ]) |
| 575 | + |
| 576 | + # Single-component GMM (weight 1) |
| 577 | + weights = np.array([1]) |
| 578 | + p0 = gm.GaussianMixture(weights, m0, P0) |
| 579 | + |
| 580 | + # Options for Gaussian splitting |
| 581 | + split_opts = gm.GaussSplitOptions( |
| 582 | + L=3, # number of components created per split |
| 583 | + lam=1e-3, # scaling parameter |
| 584 | + recurse_depth=3, # maximum recursion depth |
| 585 | + min_weight=-np.inf |
| 586 | + ) |
| 587 | + |
| 588 | + # No weight threshold |
| 589 | + split_tol = -np.inf |
| 590 | + |
| 591 | + # Arguments passed to recursive_split: splitting method + tolerance |
| 592 | + recursive_split_args = (gm.split.id_variance, split_tol) |
| 593 | + |
| 594 | + # Apply recursive splitting to the initial GMM |
| 595 | + p0 = gm.split.recursive_split(p0, split_opts, *recursive_split_args) |
| 596 | + |
| 597 | + # Cholesky decomposition of the resulting GMM covariance |
| 598 | + Schol_gmm = np.atleast_2d(np.linalg.cholesky(p0.cov())) |
| 599 | + |
| 600 | + # Cholesky decomposition of the original covariance |
| 601 | + Schol_P0 = np.atleast_2d(np.linalg.cholesky(P0)) |
| 602 | + |
| 603 | + # Compute the maximum covariance ratio between the two matrices |
| 604 | + max_cov_ratio = abs(max_covariance_ratio(Schol_gmm, Schol_P0)) |
| 605 | + |
| 606 | + # Test: the covariance should not increase by more than 0.01% |
| 607 | + assert max_cov_ratio <= 1.0001, f"max_cov_ratio is too large: {max_cov_ratio}" |
558 | 608 |
|
559 | 609 | if __name__ == '__main__': |
560 | 610 | pytest.main([__file__]) |
| 611 | + |
| 612 | + |
0 commit comments