Estoy tratando de diagonalizar algunas matrices densas y mal acondicionadas. En la precisión de la máquina, los resultados son inexactos (devuelve valores propios negativos, los vectores propios no tienen las simetrías esperadas). Cambié a la función Eigensystem [] de Mathematica para aprovechar la precisión arbitraria, pero los cálculos son extremadamente lentos. Estoy abierto a cualquier cantidad de soluciones. ¿Existen paquetes / algoritmos que se adapten bien a problemas mal condicionados? No soy un experto en preacondicionamiento, así que no estoy seguro de cuánto podría ayudar esto. De lo contrario, todo lo que puedo pensar son solucionadores de valores propios de precisión arbitraria paralelos, pero no estoy familiarizado con nada más allá de Mathematica, MATLAB y C ++.
Para dar algunos antecedentes sobre el problema, las matrices son grandes, pero no enormes (4096x4096 a 32768x32768 como máximo). Son reales, simétricos, y los valores propios están delimitados entre 0 y 1 (exclusivo), con muchos valores propios muy cerca de 0 y ninguno cerca de 1. La matriz es esencialmente un operador de convolución. No necesito diagonalizar todas mis matrices, pero cuanto más grande sea, mejor. Tengo acceso a clústeres informáticos con muchos procesadores y capacidades informáticas distribuidas.
Gracias
Respuestas:
Calcule la SVD en lugar de la descomposición espectral. Los resultados son los mismos en aritmética exacta, ya que su matriz es positiva simétrica positiva, pero en aritmética de precisión finita, obtendrá los valores propios pequeños con mucha más precisión.
Editar: Ver Demmel y Kahan, Valores singulares precisos de matrices bidiagonales, SIAM J. Sci. Stat. Comput 11 (1990), 873-912.
ftp://netlib2.cs.utk.edu/lapack/lawnspdf/lawn03.pdf
Edit2; Tenga en cuenta que ningún método podrá resolver valores propios más pequeños que aproximadamente la norma multiplicada por la precisión de la máquina, ya que el cambio de una sola entrada por un ulp ya puede cambiar un valor propio pequeño. Por lo tanto, obtener valores propios cero en lugar de valores muy pequeños es apropiado, y ningún método (excepto trabajar con mayor precisión) desenredará los vectores propios correspondientes, pero solo devolverá una base para el espacio nulo numérico común.
fuente
Gracias por esta sugerencia. Intenté el comando SVD de Mathematica, pero no obtengo una mejora notable (todavía me faltan las simetrías apropiadas, los 'valores propios' son incorrectamente cero donde antes salían incorrectamente). ¿Quizás deba implementar uno de los algoritmos que describió anteriormente en lugar de una función incorporada? Probablemente quiera evitar tener que usar un método específico como este a menos que esté seguro de antemano de que ofrecerá una mejora significativa.
@JackPoulson, leí el documento sobre el método de Jacobi al que hizo referencia, y parece prometedor. ¿Puede usted o alguien recomendar una buena manera de implementar el método de Jacobi para encontrar sistemas propios? Supongo que si lo codificara yo mismo (en MATLAB), sería extremadamente lento.
fuente