Skip to content

Commit 08ceeb7

Browse files
committed
Fix riemann ASR eigpair mismatch in nonlinear_eigenspace
1 parent 02db7a1 commit 08ceeb7

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

meegkit/utils/covariances.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,5 +503,10 @@ def ehess(X, U):
503503
problem = Problem(manifold=manifold, cost=cost, euclidean_gradient=egrad,
504504
euclidean_hessian=ehess)
505505
Xsol = solver.run(problem, initial_point=U0)
506+
X = Xsol.point
506507

507-
return S0, Xsol.point
508+
# Keep eigpairs consistent: compute each optimized vector's Rayleigh
509+
# quotient against L instead of returning the random-init eigenvalues S0.
510+
S = np.real(np.diag(X.T @ L @ X))
511+
512+
return S, X

tests/test_cov.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import numpy as np
2+
import pytest
23
from numpy.testing import assert_almost_equal
34

45
from meegkit.utils import convmtx, tscov, tsxcov
@@ -88,6 +89,25 @@ def test_convmtx():
8889
])
8990
)
9091

92+
93+
def test_nonlinear_eigenspace_consistent_eigpairs():
94+
"""Returned eigenvalues must match returned eigenvectors."""
95+
pytest.importorskip("pymanopt")
96+
from meegkit.utils.covariances import nonlinear_eigenspace
97+
98+
A = rng.standard_normal((6, 6))
99+
L = A.T @ A + np.eye(6) * 1e-6
100+
101+
S, X = nonlinear_eigenspace(L, 6)
102+
rayleigh = np.real(np.diag(X.T @ L @ X))
103+
104+
np.testing.assert_allclose(
105+
np.sort(np.real(S)),
106+
np.sort(rayleigh),
107+
rtol=1e-3,
108+
atol=1e-6,
109+
)
110+
91111
if __name__ == "__main__":
92112
import pytest
93113
pytest.main([__file__])

0 commit comments

Comments
 (0)