Pregunta

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: 18x1,
b: 25x18,

que me da c con dimensiones 1x25.

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 de la función mrdivide incorporada en MATLAB si existe en Python?)

¿Fue útil?

Solución

La línea

c = a.' / b

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

c = numpy.linalg.lstsq(b.T, a.T)[0].T

Otros consejos

El símbolo / es el operador de división de matriz derecha en MATLAB, que llama a función mrdivide . De la documentación, la división derecha de la matriz está relacionada con división izquierda de la matriz en 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 en un forma diferente, 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 x * A = B insuficiente o sobredeterminado. Más detalles sobre los algoritmos utilizados para resolver el sistema de ecuaciones se encuentran en aquí . Por lo general, paquetes como LAPACK o BLAS se utilizan debajo del capó.

El paquete NumPy para Python contiene una rutina lstsq para calcular los mínimos cuadrados Solución a 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 exacto . 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 más grande, dependiendo en gran medida del sistema específico de ecuaciones que estés resolviendo.

Para usar lstsq , puede que tenga que ajustar ligeramente su problema. Parece que desea 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. Aplicar una transposición a ambos lados le da la ecuación B T c T = a T , que es una forma más estándar (es decir, Ax = b ). Los argumentos para lstsq deberían ser (en este orden) BT (una matriz de 18 por 25) y a T (una matriz de 18 elementos). lstsq debería devolver una matriz de 25 elementos ( c T ).

Nota: mientras NumPy no hace ninguna distinción entre una matriz 1 por N o N por 1, MATLAB ciertamente lo hace y le gritará si no usa la adecuada.

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


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

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

Luego 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 matricial en Python (o cualquier lenguaje), obtenga los siguientes tres métodos.

  • multiplicación de matrices
  • transposición de matriz
  • 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:

AT*BT * (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 = A.T * B.T * (B * B.T).I

También puede abordar esto utilizando el pseudoinvertido de B y 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 < code> numpy.dot :

c = numpy.dot(a, numpy.linalg.pinv(b))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top