Array división- traduciendo de MATLAB a Python

Tengo esta línea de código en MATLAB, escrita por otra persona:

c=a.'/b 

Necesito traducirlo a Python. a, b, yc son todas matrices. Las dimensiones que estoy usando actualmente para probar el código son:

a: 18×1,
b: 25×18,

Lo que me da c con las dimensiones 1×25.

Las matrices no son cuadradas, pero no quisiera que el código fallara si lo fueran. ¿Puede alguien explicar exactamente qué está haciendo esta línea (matemáticamente) y cómo hacerlo en Python? (es decir, el equivalente para la función mrdivide incorporada en MATLAB si existe en Python?)

La línea

 c = a.' / b 

calcula la solución de la ecuación cb = a T para c . Numpy no tiene un operador que haga esto directamente. En su lugar, debe resolver b T c T T = a para c T y transponer el resultado:

 c = numpy.linalg.lstsq(bT, aT)[0].T 

El símbolo / es el operador de la división derecha de la matriz en MATLAB, que llama a la función mrdivide . De la documentación, la división de la derecha de la matriz está relacionada con la división de la izquierda de la matriz de la siguiente manera:

 B/A = (A'\B')' 

Si A es una matriz cuadrada, B/A es aproximadamente igual a B*inv(A) (aunque se calcula de una manera diferente y más robusta). De lo contrario, x = B/A es la solución en el sentido de mínimos cuadrados para el sistema de ecuaciones insuficiente o sobredeterminado x*A = B Más detalles sobre los algoritmos utilizados para resolver el sistema de ecuaciones se dan aquí . Normalmente, los paquetes como LAPACK o BLAS se utilizan debajo del capó.

El paquete NumPy para Python contiene una rutina lstsq para calcular la solución de mínimos cuadrados para un sistema de ecuaciones. Es probable que esta rutina le brinde resultados comparables al uso de la función mrdivide en MATLAB, pero es poco probable que sea exacta . Cualquier diferencia en los algoritmos subyacentes utilizados por cada función probablemente dará como resultado respuestas que difieren ligeramente entre sí (es decir, una puede devolver un valor de 1.0, mientras que la otra puede devolver un valor de 0.999). El tamaño relativo de este error podría terminar siendo mayor, dependiendo en gran medida del sistema específico de ecuaciones que esté resolviendo.

Para usar lstsq , puede que tenga que ajustar su problema ligeramente. Parece que quieres resolver una ecuación de la forma cB = a , donde B es 25 por 18, a es 1 por 18 y c es 1 por 25. La aplicación de una transposición a ambos lados le da la ecuación B T c T T = a T , que es una forma más estándar (es decir, Ax = b ). Los argumentos para lstsq deben ser (en este orden) B T (una matriz de 18 por 25) y una T (una matriz de 18 elementos). lstsq debe devolver una matriz de 25 elementos ( c T ).

Nota: aunque NumPy no hace ninguna distinción entre una matriz 1-por-N o N-por-1, MATLAB sí lo hace, y te gritará si no usas la correcta.

En Matlab, A.' Significa transponer la matriz A. Entonces matemáticamente, lo que se logra en el código es A T / B.


Cómo implementar la división de matriz en Python (o en cualquier idioma) (Nota: repasemos una división simple de la forma A/B ; para su ejemplo, tendría que hacer A T primero y luego A T / B a continuación, y es bastante fácil realizar la operación de transposición en Python | left-as-an-exercise:) |)

Tienes una ecuación matricial C * B = A (quieres encontrar C como A / B)

DIVISIÓN DERECHA (/) es la siguiente:

C * (B * B T ) = A * B T

A continuación, se aísla C invirtiendo (B * B T )

es decir,

C = A * B T * (B * B T ) ‘—– [1]

Por lo tanto, para implementar la división de matriz en Python (o cualquier idioma), obtenga los siguientes tres métodos.

  • Multiplicación de matrices
  • Transposición matricial
  • Matriz inversa

Luego aplícalos de forma iterativa para lograr la división como en [1].

Solo, necesita hacer A T / B, por lo tanto, su operación final después de implementar los tres métodos básicos debe ser:

A T * B T * (B * B T ) ‘

Nota: No olvide las reglas básicas de la precedencia del operador 🙂

[editado] Como señaló Suvesh, antes estaba completamente equivocado. Sin embargo, Numpy todavía puede hacer fácilmente el procedimiento que da en su publicación:

 A = numpy.matrix(numpy.random.random((18, 1))) # as noted by others, your dimensions are off B = numpy.matrix(numpy.random.random((25, 18))) C = AT * BT * (B * BT).I 

También puede acercarse a esto utilizando el pseudoinverso de B luego publique multiplicando ese resultado con A Intente usar numpy.linalg.pinv luego combine esto con la multiplicación de matrices a través de numpy.dot :

 c = numpy.dot(a, numpy.linalg.pinv(b))