Estou tentando diagonalizar algumas matrizes densas e mal condicionadas. Na precisão da máquina, os resultados são imprecisos (retornando valores próprios negativos, os vetores próprios não possuem as simetrias esperadas). Eu mudei para a função Eigensystem [] do Mathematica para tirar proveito da precisão arbitrária, mas os cálculos são extremamente lentos. Estou aberto a qualquer número de soluções. Existem pacotes / algoritmos adequados para problemas mal condicionados? Como não sou especialista em pré-condicionamento, não tenho certeza de quanto isso poderia ajudar. Caso contrário, só consigo pensar em solucionadores de autovalores de precisão arbitrários paralelizados, mas não estou familiarizado com nada além do Mathematica, MATLAB e C ++.
Para dar uma idéia do problema, as matrizes são grandes, mas não enormes (no máximo de 4096 x 4096 a 32768 x 32768). Eles são reais, simétricos e os autovalores são limitados entre 0 e 1 (exclusivo), com muitos autovalores sendo muito próximos de 0 e nenhum próximo de 1. A matriz é essencialmente um operador de convolução. Não preciso diagonalizar todas as minhas matrizes, mas quanto maior eu puder, melhor. Eu tenho acesso a clusters de computação com muitos processadores e recursos de computação distribuída.
Obrigado
Respostas:
Calcular o SVD no lugar da decomposição espectral. Os resultados são os mesmos na aritmética exata, pois sua matriz é definida positivamente simétrica, mas na aritmética de precisão finita, você obterá os pequenos autovalores com muito mais precisão.
Edit: Veja Demmel & Kahan, Valores Singulares Exatos de Matrizes Bidiagonais, SIAM J. Sci. Estado. Comput. 11 (1990), 873-912.
ftp://netlib2.cs.utk.edu/lapack/lawnspdf/lawn03.pdf
Edit2; Observe que nenhum método poderá resolver valores próprios menores que os tempos normais que a precisão da máquina usou, pois alterar uma única entrada por uma ulp já pode alterar um valor próprio pequeno por esse valor. Portanto, obter zero autovalores no lugar de valores muito pequenos é apropriado, e nenhum método (exceto trabalhar com maior precisão) irá separar os autovetores correspondentes, mas apenas retornar uma base para o espaço nulo numérico comum.
fonte
Obrigado por esta sugestão. Eu tentei o comando SVD do Mathematica, mas não obtive nenhuma melhoria perceptível (ainda faltando simetrias apropriadas, 'autovalores' são incorretamente zero, onde estavam incorretamente negativos antes). Talvez eu precise implementar um dos algoritmos que você descreve acima, em vez de uma função interna? Provavelmente, eu gostaria de evitar o trabalho de usar um método específico como este, a menos que tivesse certeza antecipada de que isso ofereceria uma melhoria significativa.
@JackPoulson, passei os olhos pelo artigo sobre o método de Jacobi que você mencionou e parece promissor. Você ou alguém pode recomendar uma boa maneira de implementar o método de Jacobi para encontrar sistemas eigensistemas? Eu estou supondo que se eu mesmo codificasse (no MATLAB), seria extremamente lento.
fonte