2009-06-16 10 views
7

tengo esta línea de código en MATLAB, escrito por otra persona:matriz Division- traducir de MATLAB para Python

c=a.'/b 

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

a: 18x1,
b: 25x18,

que me da c con dimensiones de 1x25.

Las matrices no son cuadradas, pero no me gustaría 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 incorporada de mrdivide en MATLAB si existe en Python?)

+0

yo creo que hay un error tipográfico. Si "a" es 1 por 18, no necesita la transposición. – gnovice

+0

No es un error tipográfico, el código Matlab funciona perfectamente. – EmilyS

+1

@Emily: Entonces "a" tiene que ser 18-por-1 (antes de la transposición), no 1-por-18. De lo contrario, MATLAB arroja un error. – gnovice

Respuesta

7

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 c T y transponer el resultado:

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

Puede tener la "a" y la "b" en su ecuación invertidas en relación con los OP "a" y "b". La línea "c = a. '/ B" es la solución de una ecuación de la forma "x * b = a.'", Que se convierte en "(b.) * (X. ') = A". El OPs "b" (es decir, la matriz de coeficientes de ecuación) debe ser la primera entrada a lstsq, transpuesta por supuesto. – gnovice

+0

Gracias por señalar eso. Editaré mi respuesta. –

5

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 ir sobre la implementación de división de matrices en Python (o cualquier otro idioma)(Nota: Vamos a ir a través de una simple división de la forma A/B, por su ejemplo, usted tendría que hacer un T primero y luego un T/B siguiente, y es bastante fácil de hacer la operación de transposición en Python | left-como-un-ejercicio:) |)

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

DERECHO división (/) es como sigue:

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

A continuación, aislar C por inversión (B * B T)

es decir,

C = A * B T* (B * B T)' ----- [1]

Por lo tanto, para poner en práctica la división de la matriz en Python (o cualquier otro idioma), obtener los tres métodos siguientes.

  • multiplicación de matrices
  • transposición de la matriz
  • matriz inversa

Entonces aplicarlas de forma iterativa para lograr la división que en [1].

Sólo, que tiene que hacer un T/B, por lo tanto, su operación final después de la aplicación de los tres métodos básicos debe ser:

Un T* B T* (B * B T)'

Nota: no se olvide de las reglas básicas de la prioridad de los operadores :)

7

El símbolo / es el operador de la división de la matriz de la derecha en MATLAB, que llama a la función mrdivide. A partir de la documentación, la división derecha de la matriz se relaciona con matrix left division 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, más robusto). 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 excesivamente determinado. Se dan más detalles sobre los algoritmos utilizados para resolver el sistema de ecuaciones here. Normalmente, los paquetes como LAPACK o BLAS se utilizan debajo del capó.

El NumPy package para Python contiene una rutina lstsq para calcular la solución de mínimos cuadrados para un sistema de ecuaciones. Esta rutina probablemente le dará 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, uno puede devolver un valor de 1.0, mientras que el otro puede devolver un valor de 0.999). El tamaño relativo de este error podría ser más grande, 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 se quiere resolver una ecuación de la cB forma = a, donde B es 25-por-18, un es de 1 por 18, y c es 1-por-25. La aplicación de un transpose 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 a lstsq deben ser (en este orden) B T (una matriz de 18 por 25) y un T (una matriz 18 de elementos). lstsq debe devolver una matriz de 25 elementos (c T).

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

+1

Numpy no hace ninguna distinción entre una matriz de 1 por N o N por 1. Una matriz 1D es una matriz 1D. Si crea una matriz 2D con una dimensión de longitud 1, puede diferenciar, pero generalmente no hay ninguna razón para hacerlo. – endolith

1

[editado] Como se señaló Suvesh, yo estaba completamente equivocado antes. sin embargo, numpy todavía puede hacer fácilmente el procedimiento que da en su mensaje:

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 
+0

El operador/en Python se define como la división de matriz estándar para matrices cuadradas, es decir, A * inv (B). En su ejemplo, ella está tratando de lograr la división correcta para matrices de cualquier tamaño. Entonces tu código no funcionaría. –

+0

+1 para el cambio y traducir mi matemática al código de Python. :) no sé Python, pero en cualquier caso, quería que ella trabaje a cabo, por lo que no se molestó en publicar código junto con mis matemáticas. –

+0

Esto al menos me da una matriz resultado C con las dimensiones adecuadas, pero los valores en la matriz que no coinciden con los valores de Matlab- alguna idea? – EmilyS

1

También puede acercarse a este uso de la pseudo-inversa de B luego publicar multiplicando ese resultado con A. Trate de usar numpy.linalg.pinv luego combinar esto con la multiplicación de matrices a través de numpy.dot:

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