Domanda

Ho questa riga di codice in MATLAB, scritta da qualcun altro:

c=a.'/b

Devo tradurlo in Python. a, b e c sono tutti array. Le dimensioni che sto attualmente utilizzando per testare il codice sono:

a: 18x1,
b: 25x18,

che mi dà c con dimensioni 1x25.

Gli array non sono quadrati, ma non vorrei che il codice fallisse se lo fossero. Qualcuno può spiegare esattamente cosa sta facendo questa linea (matematicamente) e come farlo in Python? (vale a dire, l'equivalente per la funzione mrdivide integrata in MATLAB se esiste in Python?)

È stato utile?

Soluzione

La linea

c = a.' / b

calcola la soluzione dell'equazione c b = a T per c . Numpy non ha un operatore che lo fa direttamente. Invece dovresti risolvere b T c T = a per cT e trasporre il risultato:

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

Altri suggerimenti

Il simbolo / è l'operatore di divisione della matrice destra in MATLAB, che chiama mrdivide . Dalla documentazione, la divisione destra matrice è correlata a divisione sinistra matrice in il seguente modo:

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

Se A è una matrice quadrata, B / A è approssimativamente uguale a B * inv (A) (sebbene sia calcolato in un modo diverso e più robusto). Altrimenti, x = B / A è la soluzione nel senso dei minimi quadrati al sistema di equazioni sotto o sovradeterminato x * A = B . Maggiori dettagli sugli algoritmi utilizzati per risolvere il sistema di equazioni sono forniti qui . Tipicamente pacchetti come LAPACK o BLAS sono usati sotto il cofano.

Il pacchetto NumPy per Python contiene una routine lstsq per il calcolo dei minimi quadrati soluzione a un sistema di equazioni. Questa routine fornirà probabilmente risultati comparabili all'uso della funzione mrdivide in MATLAB, ma è improbabile che sia esatto . Eventuali differenze negli algoritmi sottostanti utilizzati da ciascuna funzione risulteranno probabilmente in risposte leggermente diverse l'una dall'altra (ad esempio, uno può restituire un valore di 1,0, mentre l'altro può restituire un valore di 0,999). La dimensione relativa di questo errore potrebbe finire per essere più grande, a seconda del sistema specifico di equazioni che stai risolvendo.

Per utilizzare lstsq , potresti dover correggere leggermente il problema. Sembra che tu voglia risolvere un'equazione del modulo cB = a , dove B è 25 per 18, a è 1- per 18 e c è 1 per 25. Applicare un trasporre su entrambi i lati ti dà l'equazione B T c T = a T , che è un modulo più standard (cioè Ax = b ). Gli argomenti per lstsq dovrebbero essere (in questo ordine) BT (un array 18 per 25) e un T (un array di 18 elementi). lstsq dovrebbe restituire un array di 25 elementi ( c T ).

Nota: mentre NumPy non fa alcuna distinzione tra un array 1 per N o N per 1, MATLAB certamente lo farà e ti urlerà se non usi quello giusto.

In Matlab, A. ' significa trasporre la matrice A. Quindi matematicamente, ciò che si ottiene nel codice è A T / B.


Come implementare la divisione matrice in Python (o in qualsiasi lingua) (Nota: passiamo a una semplice divisione del modulo A / B ; per il tuo esempio dovresti prima fare A T e poi A T / B, ed è abbastanza facile eseguire l'operazione di trasposizione in Python | left-as-an -esercizio:) |)

Hai un'equazione di matrice C * B = A (Vuoi trovare C come A / B)

DIVISIONE DESTRA (/) è la seguente:

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

Quindi isolare C capovolgendo (B * B T )

cioè.,

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

Pertanto, per implementare la divisione matrice in Python (o in qualsiasi lingua), ottenere i seguenti tre metodi.

  • Moltiplicazione di matrici
  • Trasposizione matrice
  • Matrice inversa

Quindi applicali in modo iterativo per ottenere la divisione come in [1].

Solo, devi fare A T / B, quindi la tua operazione finale dopo aver implementato i tre metodi di base dovrebbe essere:

A T * B T * (B * B T ) '

Nota: non dimenticare le regole di base della precedenza dell'operatore :)

[modificato] Come sottolineato da Suvesh, prima avevo sbagliato completamente. tuttavia, numpy può ancora facilmente eseguire la procedura che dà nel suo post:

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

Puoi anche avvicinarti a questo usando lo pseudo-inverso di B quindi postare moltiplicando quel risultato con A . Prova a utilizzare numpy.linalg.pinv quindi combinalo con la moltiplicazione della matrice via < code> numpy.dot :

c = numpy.dot(a, numpy.linalg.pinv(b))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top