J'essaie de diagonaliser des matrices denses et mal conditionnées. En précision machine, les résultats sont inexacts (renvoyant des valeurs propres négatives, les vecteurs propres n'ont pas les symétries attendues). Je suis passé à la fonction Eigensystem [] de Mathematica pour profiter d'une précision arbitraire, mais les calculs sont extrêmement lents. Je suis ouvert à toutes sortes de solutions. Existe-t-il des packages / algorithmes bien adaptés aux problèmes mal conditionnés? Je ne suis pas un expert en préconditionnement, donc je ne sais pas combien cela pourrait aider. Sinon, je ne pense qu'à des solveurs de valeurs propres de précision arbitraire parallélisés, mais je ne connais rien au-delà de Mathematica, MATLAB et C ++.
Pour donner un aperçu du problème, les matrices sont grandes, mais pas énormes (4096x4096 à 32768x32768 tout au plus). Ils sont réels, symétriques et les valeurs propres sont limitées entre 0 et 1 (exclusif), de nombreuses valeurs propres étant très proches de 0 et aucune proche de 1. La matrice est essentiellement un opérateur de convolution. Je n'ai pas besoin de diagonaliser toutes mes matrices, mais plus je peux agrandir, mieux c'est. J'ai accès à des clusters informatiques avec de nombreux processeurs et des capacités informatiques distribuées.
Je vous remercie
Réponses:
Calculez la SVD à la place de la décomposition spectrale. Les résultats sont les mêmes en arithmétique exacte, car votre matrice est définie positivement symétrique, mais en arithmétique de précision finie, vous obtiendrez les petites valeurs propres avec beaucoup plus de précision.
Edit: Voir Demmel & Kahan, Accurate Singular Values of Bidiagonal Matrices, SIAM J. Sci. Stat. Comput. 11 (1990), 873-912.
ftp://netlib2.cs.utk.edu/lapack/lawnspdf/lawn03.pdf
Edit2; Notez qu'aucune méthode ne sera en mesure de résoudre des valeurs propres plus petites que les temps normaux de la précision de la machine utilisée, car la modification d'une seule entrée par un ulp peut déjà changer une petite valeur propre de cette façon. Ainsi, obtenir des valeurs propres nulles à la place de très petites valeurs est approprié, et aucune méthode (sauf travailler avec une plus grande précision) ne démêlera les vecteurs propres correspondants, mais renverra simplement une base pour l'espace nul numérique commun.
la source
Merci pour cette suggestion. J'ai essayé la commande SVD de Mathematica, mais je n'obtiens aucune amélioration notable (il manque toujours les symétries appropriées, les `` valeurs propres '' sont incorrectement nulles alors qu'elles sortaient incorrectement négativement auparavant). Peut-être aurais-je besoin d'implémenter l'un des algorithmes que vous décrivez ci-dessus au lieu d'une fonction intégrée? Je voudrais probablement éviter de me donner la peine d'utiliser une méthode spécifique comme celle-ci, sauf si j'étais sûr à l'avance qu'elle offrirait une amélioration significative.
@JackPoulson, j'ai parcouru le document sur la méthode de Jacobi que vous avez mentionnée, et cela semble prometteur. Pouvez-vous ou quelqu'un d'autre recommander un bon moyen de mettre en œuvre la méthode de Jacobi pour trouver des systèmes électroniques? Je suppose que si je le codais moi-même (dans MATLAB), ce serait extrêmement lent.
la source