Comprender cómo Numpy hace SVD

13

He estado usando diferentes métodos para calcular tanto el rango de una matriz como la solución de un sistema matricial de ecuaciones. Encontré la función linalg.svd. Comparando esto con mi propio esfuerzo para resolver el sistema con Gaussian Elimination, parece ser más rápido y más preciso. Estoy tratando de entender cómo es esto posible.

Hasta donde sé, la función linalg.svd usa un algoritmo QR para calcular los valores propios de mi matriz. Sé cómo funciona matemáticamente, pero no sé cómo Numpy logra hacerlo tan rápido y sin perder mucha precisión.

Entonces, mi pregunta: ¿cómo funciona la función numpy.svd y, más específicamente, cómo logra hacerlo de manera rápida y precisa (en comparación con la eliminación gaussiana)?

RobVerheyen
fuente
2
numpy usa la rutina Lapack dgesddpara SVDs con valor real. Entonces, su verdadera pregunta es probablemente "¿cómo funciona Lapack dgesdd?"
Talonmies
Si es REALMENTE curioso, sugeriría examinar la fuente LAPACK.
Gracias por sus comentarios, y mis disculpas, estoy fuera de tema.
RobVerheyen
Esta publicación es una publicación cruzada de Stack Overflow . La publicación cruzada generalmente se desaconseja en los sitios de Stack Exchange. El protocolo estándar para volver a publicar una pregunta en un sitio diferente es cerrar, eliminar o migrar la publicación original antes de intentar volver a publicar en un sitio diferente. (Si migra la pregunta, se vuelve a publicar automáticamente.)
Geoff Oxberry
Lo siento, no estaba al tanto del protocolo. Espero que aún pueda obtener una respuesta.
RobVerheyen

Respuestas:

15

Hay una serie de problemas en su pregunta.

No utilice la eliminación gaussiana (factorización LU) para calcular el rango numérico de una matriz. La factorización LU no es confiable para este propósito en aritmética de coma flotante.En su lugar, use una descomposición QR reveladora de rango (como xGEQPXo xGEPQYen LAPACK, donde x es C, D, S o Z, aunque esas rutinas son difíciles de rastrear; vea la respuesta de JedBrown en una pregunta relacionada ), o use un SVD (descomposición de valores singulares, como xGESDDo xGESVD, donde x es nuevamente C, D, S o Z). El SVD es un algoritmo más preciso y confiable para la determinación del rango numérico, pero requiere más operaciones de punto flotante.

Sin embargo, para resolver un sistema lineal, la factorización LU (con pivote parcial, que es la implementación estándar en LAPACK) es extremadamente confiable en la práctica. Hay algunos casos patológicos para los que la factorización LU con pivote parcial es inestable (ver Lección 22 en Álgebra lineal numérica).por Trefethen y Bau para más detalles). La factorización QR es un algoritmo numérico más estable para resolver sistemas lineales, por lo que es probable que le proporcione resultados tan precisos. Sin embargo, requiere más operaciones de punto flotante que la factorización LU por un factor de 2 para matrices cuadradas (creo; JackPoulson puede corregirme sobre eso). Para los sistemas rectangulares, la factorización QR es una mejor opción porque generará soluciones de mínimos cuadrados para sistemas lineales sobredeterminados. SVD también se puede usar para resolver sistemas lineales, pero será más costoso que la factorización QR.

janneb tiene razón en que numpy.linalg.svd es una envoltura xGESDDen LAPACK. Las descomposiciones de valores singulares proceden en dos etapas. Primero, la matriz a descomponer se reduce a forma bidiagonal. El algoritmo utilizado para reducir a forma bidiagonal en LAPACK es probablemente el algoritmo Lawson-Hanson-Chan, y utiliza la factorización QR en un punto. La lección 31 en Álgebra lineal numérica de Trefethen y Bau ofrece una visión general de este proceso. Luego, xGESDDutiliza un algoritmo de divide y vencerás para calcular los valores singulares y los vectores singulares izquierdo y derecho de la matriz bidiagonal. Para obtener información sobre este paso, deberá consultar Matrix Computations de Golub y Van Loan, o Applied Numerical Linear Algebra de Jim Demmel.

Finalmente, no debe confundir valores singulares con valores propios . Estos dos conjuntos de cantidades no son lo mismo. El SVD calcula los valores singulares de una matriz. La computación numérica de Cleve Moler con MATLAB ofrece una buena descripción de las diferencias entre valores singulares y valores propios . En general, no existe una relación obvia entre los valores singulares de una matriz dada y sus valores propios, excepto en el caso de las matrices normales , donde los valores singulares son el valor absoluto de los valores propios.

Geoff Oxberry
fuente
Creo que "no relacionado" es bastante fuerte para la relación entre valores propios y valores singulares. La relación es bastante oscura a menos que conozca la descomposición completa de Jordan de su matriz, pero puede usar una para obtener estimaciones de la otra si tiene información (o está dispuesto a hacer suposiciones) sobre dicha descomposición de Jordan.
Dan
¿Qué sugerirías en su lugar?
Geoff Oxberry
En primer lugar, gracias por la elaborada respuesta. Descubrí que no puedo usar la descomposición LU para determinar el rango de la matriz de la manera difícil. Su respuesta parece implicar que la factorización QR sería un método más rápido para resolver mi problema, ¿correcto? ¿Existe una clara ventaja en el uso de SVD? Era muy consciente del hecho de que los valores singulares no son valores propios. Me refería al hecho de que los valores singulares pueden calcularse como valores propios de la matriz multiplicada con su transposición desde la izquierda. Lo siento, eso no estaba claro.
RobVerheyen
Podría agregar que la matriz que estoy resolviendo es realmente singular. De hecho, el rango de la matriz es solo aproximadamente la mitad del tamaño de la matriz. ¿Quizás esto hace que algún método sea más preferible?
RobVerheyen
1
@RobVerheyen: QR será más lento de lo que sería LU, pero considerablemente más preciso. SVD será aún más lento que QR, pero SVD se considera el método más confiable para determinar el rango numérico (por ejemplo, MATLAB usa el SVD en su rankfunción). También hay un poco de discreción al usar cualquiera de los enfoques; En el enfoque SVD, el rango numérico es el número de valores singulares por encima de un límite específico (generalmente muy pequeño). (El enfoque QR es similar, pero reemplaza valores singulares con entradas diagonales de la matriz R).
Geoff Oxberry
8

Debido a la redacción de su pregunta, supongo que su matriz es cuadrada. Las rutinas SVD de LAPACK, como zgesvd , esencialmente proceden en tres etapas para matrices cuadradas:

  1. UAVAAB:=UAHAVAUAVABO(n3)
  2. {UB,VB,Σ}B=UBΣVBHO(n2)O(n3)
  3. UABVAH=AA=(UAUB)Σ(VAVB)HUAVAUBVBO(n3)
Jack Poulson
fuente
7

numpy.linalg.svd es un contenedor alrededor de {Z, D} GESDD de LAPACK. LAPACK, a su vez, está escrito con mucho cuidado por algunos de los principales expertos del mundo en álgebra lineal numérica. De hecho, sería muy sorprendente que alguien que no esté familiarizado con el campo tenga éxito en vencer a LAPACK (ya sea en velocidad o precisión).

En cuanto a por qué QR es mejor que la eliminación gaussiana, eso es probablemente más apropiado para /scicomp//

janneb
fuente
Gracias por la respuesta y la referencia. Lo intentaré allí.
RobVerheyen