Estou resolvendo equações diferenciais que exigem inverter matrizes quadradas densas. Essa inversão de matriz consome a maior parte do meu tempo de computação, então eu queria saber se estou usando o algoritmo mais rápido disponível.
Minha escolha atual é numpy.linalg.inv . Dos meus números, vejo que ele é escalado como que n é o número de linhas, de modo que o método parece ser a eliminação gaussiana.
Segundo a Wikipedia , existem algoritmos mais rápidos disponíveis. Alguém sabe se existe uma biblioteca que os implementa?
Eu me pergunto, por que não está entorpecido usando esses algoritmos mais rápidos?
numpy
dense-matrix
inverse
physicsGuy
fonte
fonte
scipy.sparse
ajudaria?scipy.sparse
é relevante aqui?Respostas:
(Isso está demorando muito para comentários ...)
Suponho que você realmente precise calcular uma inversa no seu algoritmo. 1 Primeiro, é importante observar que esses algoritmos alternativos não são realmente mais rápidos , apenas que eles têm melhor complexidade assintótica (o que significa que o número necessário de operações elementares cresce mais lentamente). De fato, na prática, eles são realmente (muito) mais lentos que a abordagem padrão (para o dado ), pelos seguintes motivos:n
A anotação oculta uma constante diante do poder de , que pode ser astronomicamente grande - tão grande que pode ser muito menor que para qualquer que pode ser manuseado por qualquer computador no futuro próximo. (Este é o caso do algoritmo Coppersmith – Winograd, por exemplo.) n C 1 n 3 C 2 n 2. x nO n C1n3 C2n2.x n
A complexidade pressupõe que toda operação (aritmética) leva o mesmo tempo - mas isso está longe de ser verdade na prática: multiplicar um monte de números com o mesmo número é muito mais rápido do que multiplicar a mesma quantidade de números diferentes . Isso se deve ao fato de que o maior gargalo na computação atual está colocando os dados no cache, não nas operações aritméticas reais desses dados. Portanto, um algoritmo que pode ser reorganizado para ter a primeira situação (chamada de reconhecimento de cache ) será muito mais rápido do que aquele em que isso não for possível. (Este é o caso do algoritmo Strassen, por exemplo.)
Além disso, a estabilidade numérica é pelo menos tão importante quanto o desempenho; e aqui, novamente, a abordagem padrão geralmente vence.
Por esse motivo, as bibliotecas padrão de alto desempenho (BLAS / LAPACK, que Numpy chama quando você pede uma computação inversa) geralmente implementam apenas essa abordagem. Obviamente, existem implementações Numpy de, por exemplo, o algoritmo de Strassen, mas um algoritmo ajustado manualmente no nível da montagem supera profundamente um algoritmo escrito em uma linguagem de alto nível para qualquer tamanho de matriz razoável.O ( n 2. x )O(n3) O(n2.x)
1 Mas eu ficaria errado se não afirmasse que isso raramente é realmente necessário: sempre que você precisar calcular um produto , você deve resolver o sistema linear (por exemplo, use ) e use - isso é muito mais estável e pode ser feito (dependendo da estrutura da matriz ) muito mais rapidamente. Se você precisar usar várias vezes, poderá precompor uma fatoração de (que geralmente é a parte mais cara da solução) e reutilizá-la posteriormente.A x = b x A A - 1 A
numpy.linalg.solve
fonte
Provavelmente, você deve observar que, enterrada profundamente no código-fonte numpy (consulte https://github.com/numpy/numpy/blob/master/numpy/linalg/umath_linalg.c.src ), a rotina inv tenta chamar a função dgetrf do pacote LAPACK do sistema, que executa uma decomposição da LU da sua matriz original. Isso é moralmente equivalente à eliminação gaussiana, mas pode ser ajustado para uma complexidade um pouco menor usando algoritmos de multiplicação de matriz mais rápidos em um BLAS de alto desempenho.
Se você seguir esta rota, deve ser avisado de que forçar toda a cadeia de bibliotecas a usar a nova biblioteca em vez do sistema que veio com sua distribuição é bastante complexo. Uma alternativa nos sistemas modernos de computadores é examinar métodos paralelizados usando pacotes como scaLAPACK ou (no mundo python) petsc4py. No entanto, estes são tipicamente mais felizes sendo usados como solucionadores iterativos para sistemas de álgebra linear do que aplicados a métodos diretos e o PETSc, em particular, tem como alvo sistemas esparsos mais que os densos.
fonte