I am writing a python 3.7 program and I need to get symmetric positive-definite matrices.
I used this code to get the nearest SPD (all eigenvalues have to be > 0) :
Python: convert matrix to positive semi-definite
The fact is that I have to compute riemannian exponentials of symmetric matrices: Definition of the riemannian exponential.
But I get matrices with complex coefficients. How could I get rid of that ?
Note: Even with the aforementioned implementation, I get matrices with complex numbers.
I also tried to explore the geomstats
package, but I do not know how to use it :
https://geomstats.github.io/geometry.html#module-geomstats.geometry.spd_matrices
Thanks a lot
Edit 1: my code and what I expect:
This is my function:
def expNearestSPD(Y, Delta):
"""
Implementation of riemannian exponential using the nearestPD function
I try to always keep SPD matrices
But at the end it does not work
"""
Y2 = nearestPD(Y)
mul = np.matmul( np.matmul(inv(sqrtm(Y2)), Delta), inv(sqrtm(Y2)) )
mul = nearestPD(mul)
z1 = expm( mul )
z1 = nearestPD(z1)
z = np.matmul( np.matmul(sqrtm(Y2), z1), sqrtm(Y2) )
return nearestPD(z)
For example, here is P
, a SPD matrix:
P
array([[0.1, 0. , 0. , ..., 0. , 0. , 0. ],
[0. , 0.1, 0. , ..., 0. , 0. , 0. ],
[0. , 0. , 0.1, ..., 0. , 0. , 0. ],
...,
[0. , 0. , 0. , ..., 0.1, 0. , 0. ],
[0. , 0. , 0. , ..., 0. , 0.1, 0. ],
[0. , 0. , 0. , ..., 0. , 0. , 0.1]])
One can check:
np.isrealobj(P)
True
But when I compute expNearestSPD(P, P)
for example, I get:
expNearestSPD(P, P)
array([[0.27182818+0.j, 0. +0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[0. +0.j, 0.27182818+0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[0. +0.j, 0. +0.j, 0.27182818+0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
...,
[0. +0.j, 0. +0.j, 0. +0.j, ...,
0.27182818+0.j, 0. +0.j, 0. +0.j],
[0. +0.j, 0. +0.j, 0. +0.j, ...,
0. +0.j, 0.27182818+0.j, 0. +0.j],
[0. +0.j, 0. +0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0.27182818+0.j]])
I get complex, but very little, coefficients.