2009-06-16 19 views
7

mam ten wiersz kodu w programie MATLAB, napisanej przez kogoś innego:Array division- tłumaczenia z MATLAB do Pythona

c=a.'/b 

muszę ją przetłumaczyć na Pythonie. a, b i c to wszystkie tablice. Wymiary, które Obecnie używam do testowania kodu to:

a: 18x1,
b: 25x18,

który daje mi c o wymiarach 1x25.

Tablice nie są kwadratowe, ale nie chciałbym, aby kod się nie powiódł. Czy ktoś może wyjaśnić dokładnie, co robi ta linia (matematycznie) i jak to zrobić w Pythonie? (tj. odpowiednik wbudowanej funkcji mrdivide w MATLAB, jeśli istnieje w Pythonie?)

+0

myślę, że masz literówkę. Jeśli "a" wynosi 1-na-18, nie potrzebujesz transpozycji. – gnovice

+0

To nie jest literówka, kod Matlab działa doskonale. – EmilyS

+1

@Emily: Następnie "a" musi być 18-by-1 (przed transpozycją), a nie 1-na-18. W przeciwnym razie MATLAB zgłasza błąd. – gnovice

Odpowiedz

7

Linia

c = a.'/b 

oblicza rozwiązanie równania C B = a T dla c. Numpy nie ma operatora, który robi to bezpośrednio. Zamiast tego należy rozwiązać b T c T = a dla c T i transpozycji Rezultat:

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

Możesz mieć "a" i "b" w swoim równaniu odwrócone względem OP "a" i "b". Wiersz "c = a."/B "rozwiązuje równanie w postaci" x * b = a. "", Które staje się "(b. ') * (X.') = A". OP "b" (to jest macierz współczynników równania) powinny być pierwszym wejściem do lstsq, transponowanym oczywiście. – gnovice

+0

Dzięki za wskazanie tego. Będę edytować moją odpowiedź. –

5

W Matlab, A.' oznacza transponowanie macierzy A. Tak matematycznie, co osiągnięto w kodzie jest A T/B.


Jak przejść o wdrażaniu podziału matrycy w Pythonie (lub każdy inny język)(Uwaga: Chodźmy na prosty podział postaci A/B; dla przykładu trzeba by zrobić T pierwszy, a następnie T/B obok, i to dość łatwo zrobić operację transpozycji w Pythonie | left-as-a-ćwiczenie:))

masz równanie macierzy C * B = a (Chcesz znaleźć C jako A/B)

prawy rozdzielającej (/) jest następująca:

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

można następnie wyizolować C przez odwracanie (B * B T)

tj

C = * B T* (B * B T)”----- [1]

zatem, by podziału matrycy w Pythonie (lub dowolny język), otrzymujemy następujące trzy metody.

  • Mnożenie macierzy
  • macierzy przeniesienia
  • macierzy odwrotnej

stosowania ich w sposób iteracyjny w celu uzyskania podziału według [1].

Tylko trzeba zrobić T/B, dlatego Twoja końcowa operacja po wdrożeniu trzy podstawowe metody powinny być:

T* B T* (B * B T)”

Uwaga: nie należy zapominać podstawowe zasady pierwszeństwa operatora :)

7

Symbol jest operatorem prawego macierzy w MATLAB, który wywołuje funkcję mrdivide. Z dokumentacji, matryca prawo podział związany jest z matrix left division w następujący sposób:

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

Jeśli A jest macierzą kwadratową, B/A jest w przybliżeniu równa B*inv(A) (chociaż jest obliczana w inny, bardziej wytrzymałe sposób). W przeciwnym razie, x = B/A jest rozwiązaniem w sensie najmniejszych kwadratów do nieokreślonego lub nadmiernie określonego układu równań x*A = B. Więcej szczegółów na temat algorytmów używanych do rozwiązywania układu równań podano here. Zazwyczaj pod maską używane są pakiety takie jak LAPACK lub BLAS.

NumPy package dla Pythona zawiera procedurę lstsq do obliczania rozwiązania najmniejszych kwadratów do układu równań. Procedura ta prawdopodobnie da wyniki porównywalne do użycia funkcji mrdivide w programie MATLAB, ale jest mało prawdopodobne, aby była ona dokładna. Wszelkie różnice w podstawowych algorytmach używanych przez każdą funkcję będą prawdopodobnie powodować odpowiedzi, które różnią się nieznacznie od siebie (tj. Można zwrócić wartość 1,0, podczas gdy druga może zwrócić wartość 0,999). Względna wielkość tego błędu może być większa, w zależności od konkretnego układu równań, które rozwiązujesz.

Do korzystania z lstsq może być konieczne nieznaczne dostosowanie problemu. Wydaje się, że chce rozwiązać równanie postać Cb = A, gdzie B się 25 po 18 jest 1 po 18 i C jest 1 po 25. Stosowanie transpose na obie strony daje równanie B T C T = a T, która jest normowana postaci (tj Ax = b). Argumenty lstsq powinny być (w tej kolejności) B T (tablica 18 o-25) i T (macierzy 18 elementu). lstsq powinien zwrócić tablicę składającą się z 25 elementów (c T).

Uwaga: podczas gdy NumPy nie wprowadza rozróżnienia między tablicą 1 na 1 lub N na 1, MATLAB na pewno robi i będzie krzyczeć na ciebie, jeśli nie użyjesz właściwego.

+1

Numpy nie dokonuje rozróżnienia między tablicą 1 na 1 lub N na 1. Tablica 1D to tablica 1D. Jeśli utworzysz tablicę 2D o jednym wymiarze długości 1, możesz ją rozróżnić, ale zazwyczaj nie ma powodu, aby to robić. – endolith

1

[edytuj] Jak zauważył Suvesh, całkowicie się myliłem. Jednak numpy wciąż może łatwo wykonać procedurę oddaje swoje stanowisko:

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

Operator/Python jest zdefiniowany jako standardowy podział macierzy dla macierzy kwadratowych, tj. A * inv (B). W swoim przykładzie stara się osiągnąć właściwy podział na matryce o dowolnej wielkości. Twój kod nie zadziałałby. –

+0

+1 za zmianę i tłumaczenie mojej matematyki na kod Pythona. :) Nie znam Pythona, ale w każdym razie chciałem, żeby to rozwinęła, więc nie zadałem sobie trudu, aby opublikować kod wraz z moją matematyką. –

+0

To przynajmniej daje mi macierz wyników o właściwych wymiarach, ale wartości w tej macierzy nie pasują do wartości w Matlab - jakieś pomysły? – EmilyS

1

Można też podejść do tego za pomocą pseudo-odwrotność B następnie dodawać pomnożenie to wynik z A. Spróbuj użyć numpy.linalg.pinv następnie połączyć to z mnożenia macierzy przez numpy.dot:

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