(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 nOnC1n3C2n2.xn
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 AA−1bAx=bnumpy.linalg.solve
xAA−1A