2017-10-12 4 views
1

J'essaie de trouver les valeurs propres et les vecteurs propres d'une matrice complexe avec scipy.sparse.linalg.eigsh en utilisant son mode shift-invert. Avec juste des nombres réels dans la matrice, j'obtiens le même résultat pour le solveur de spicy.linalg.eigh, mais en ajoutant les parties imaginaires, les valeurs propres divergent. Un petit exemple:Scipy eigsh retournant des mauvais résultats pour une matrice d'entrée complexe

import numpy as np 
from scipy.linalg import eigh 
from scipy.sparse.linalg import eigsh 

n = 10 
X = np.random.random((n, n)) - 0.5 + (np.random.random((n, n)) - 0.5) * 1j 
X = np.dot(X, X.T) # create a symmetric matrix 

evals_all, evecs_all = eigh(X) 
evals_small, evecs_small = eigsh(X, 3, sigma=0, which='LM') 

print(sorted(evals_all, key=abs)) 
print(sorted(evals_small, key=abs)) 

Les impressions dans ce cas sont par exemple

[0.041577858515751132, -0.084104744918533481, -0.58668240775486691, 0.63845672501004724, -1.2311727737115068, 1.5193345703630159, -1.8652302423152105, 1.9970059660853923, -2.6414593461321654, 2.8624290667460293] 
[-0.017278543470343462, -0.32684893256215408, 0.34551438015659475] 

alors que dans le cas réel, les trois premières valeurs propres sont identiques. Je suis conscient que je passe une matrice dense au solveur clairsemé, mais ceci est juste destiné à titre d'exemple. Je manque probablement quelque chose d'évident quelque part, mais je serais heureux de trouver quelques indices. Je vous remercie!

+2

Vous avez besoin de 'conj(). T' pour rendre les choses hermitiennes. – percusse

Répondre

0

scipy est not checking votre entrée si elle est hermitienne.

Faire comme proposé dans le lien:

if not np.allclose(X, np.asmatrix(X).H): 
    raise ValueError('expected symmetric or Hermitian matrix') 

sorties:

ValueError: expected symmetric or Hermitian matrix 

Je pense que cela est également indiqué par les valeurs propres négatives que vous voyez (mais les mathématiques à base complexe est vraiment pas mon spécialité...).