Estoy resolviendo ecuaciones diferenciales que requieren invertir matrices cuadradas densas. Esta inversión matricial consume la mayor parte de mi tiempo de cálculo, por lo que me preguntaba si estoy usando el algoritmo más rápido disponible.
Mi elección actual es numpy.linalg.inv . De mis números veo que se escala como donde n es el número de filas, por lo que el método parece ser la eliminación gaussiana.
Según Wikipedia , hay algoritmos más rápidos disponibles. ¿Alguien sabe si hay una biblioteca que implemente estos?
Me pregunto, ¿por qué no es molesto usar estos algoritmos más rápidos?
numpy
dense-matrix
inverse
físicaGuy
fuente
fuente
scipy.sparse
ayudaría?scipy.sparse
es relevante aquí.Respuestas:
(Esto se está haciendo demasiado largo para comentarios ...)
Asumiré que realmente necesitas calcular un inverso en tu algoritmo. 1 Primero, es importante tener en cuenta que estos algoritmos alternativos en realidad no se afirman que sean más rápidos , solo que tienen una mejor complejidad asintótica (lo que significa que el número requerido de operaciones elementales crece más lentamente). De hecho, en la práctica, estos son en realidad (mucho) más lentos que el enfoque estándar (para un dado ), por las siguientes razones:n
La notación oculta una constante frente a la potencia de , que puede ser astronómicamente grande, tan grande que puede ser mucho más pequeña que para cualquier que puede ser manejado por cualquier computadora en el futuro previsible. (Este es el caso del algoritmo Coppersmith – Winograd, por ejemplo).O n C1n3 C2n2.x n
La complejidad supone que cada operación (aritmética) lleva el mismo tiempo, pero esto está lejos de ser cierto en la práctica real: multiplicar un grupo de números con el mismo número es mucho más rápido que multiplicar la misma cantidad de números diferentes . Esto se debe al hecho de que el cuello de botella principal en la informática actual es llevar los datos a la memoria caché, no las operaciones aritméticas reales sobre esos datos. Por lo tanto, un algoritmo que se puede reorganizar para tener la primera situación (llamado reconocimiento de caché ) será mucho más rápido que uno donde esto no sea posible. (Este es el caso del algoritmo de Strassen, por ejemplo).
Además, la estabilidad numérica es al menos tan importante como el rendimiento; y aquí, nuevamente, el enfoque estándar generalmente gana.
Por esta razón, las bibliotecas estándar de alto rendimiento (BLAS / LAPACK, que Numpy llama cuando le pide que calcule un inverso) generalmente solo implementan este enfoque. Por supuesto, hay implementaciones de Numpy de, por ejemplo, el algoritmo de Strassen, pero un algoritmo ajustado a mano en el nivel de ensamblaje superará a un algoritmo escrito en un lenguaje de alto nivel para cualquier tamaño de matriz razonable.O(n3) O(n2.x)
1 Pero me equivocaría si no señalara que esto rara vez es realmente necesario: cada vez que necesite calcular un producto , debería resolver el sistema lineal (p. Ej., usando ) y use lugar: esto es mucho más estable y se puede hacer (dependiendo de la estructura de la matriz ) mucho más rápido. Si necesita usar varias veces, puede calcular previamente una factorización de (que generalmente es la parte más costosa de la solución) y reutilizarla más tarde.
numpy.linalg.solve
fuente
Probablemente debería tener en cuenta que, enterrado en el interior del código fuente numpy (consulte https://github.com/numpy/numpy/blob/master/numpy/linalg/umath_linalg.c.src ) la rutina inv intenta llamar a la función dgetrf del paquete LAPACK de su sistema, que luego realiza una descomposición LU de su matriz original. Esto es moralmente equivalente a la eliminación gaussiana, pero puede ajustarse a una complejidad ligeramente inferior mediante el uso de algoritmos de multiplicación de matriz más rápidos en un BLAS de alto rendimiento.
Si sigue esta ruta, se le debe advertir que obligar a toda la cadena de bibliotecas a usar la nueva biblioteca en lugar del sistema que viene con su distribución es bastante complejo. Una alternativa en los sistemas informáticos modernos es buscar métodos paralelos utilizando paquetes como scaLAPACK o (en el mundo de Python) petsc4py. Sin embargo, estos suelen ser más felices de ser utilizados como solucionadores iterativos para sistemas de álgebra lineal que los aplicados a métodos directos y PETSc en objetivos particulares sistemas dispersos más que sistemas densos.
fuente