Rozwiązuję równania różniczkowe, które wymagają odwrócenia gęstych macierzy kwadratowych. Ta inwersja macierzy zużywa najwięcej mojego czasu obliczeniowego, więc zastanawiałem się, czy używam najszybszego dostępnego algorytmu.
Mój obecny wybór to numpy.linalg.inv . Z moich danych liczbowych wynika, że skaluje się jako gdzie n jest liczbą rzędów, więc metoda wydaje się być eliminacją Gaussa.
Według Wikipedii dostępne są szybsze algorytmy. Czy ktoś wie, czy istnieje biblioteka, która je implementuje?
Zastanawiam się, dlaczego numpy nie używa tych szybszych algorytmów?
numpy
dense-matrix
inverse
fizyka
źródło
źródło
scipy.sparse
pomogło?scipy.sparse
to jest istotne?Odpowiedzi:
(Robi się zbyt długo na komentarze ...)
Zakładam, że faktycznie musisz obliczyć odwrotność w swoim algorytmie. 1 Po pierwsze, należy zauważyć, że te alternatywne algorytmy nie są tak naprawdę twierdzone, że są szybsze , tylko że mają lepszą asymptotyczną złożoność (co oznacza, że wymagana liczba elementarnych operacji rośnie wolniej). W rzeczywistości są one w rzeczywistości (znacznie) wolniejsze niż standardowe podejście (dla danego ) z następujących powodów:n
-notation skóry stałym przed mocy , które mogą być astronomically duża - tak duża, że może być znacznie mniejszy niż dla każdego , że może być obsługiwany przez dowolny komputer w dającej się przewidzieć przyszłości. (Tak jest na przykład w przypadku algorytmu Coppersmith – Winograd.) n C 1 n 3 C 2 n 2. x nO n C1n3 C2n2.x n
Złożoność zakłada, że każda (arytmetyczna) operacja zajmuje ten sam czas - ale w praktyce nie jest to prawdą: Mnożenie wiązki liczb o tej samej liczbie jest znacznie szybsze niż pomnożenie tej samej liczby różnych liczb. Wynika to z faktu, że głównym wąskim gardłem w bieżącym przetwarzaniu danych jest umieszczanie danych w pamięci podręcznej, a nie faktyczne operacje arytmetyczne na tych danych. Dlatego algorytm, który można zmienić tak, aby miał pierwszą sytuację (zwaną pamięcią podręczną ), będzie znacznie szybszy niż ten, w którym nie jest to możliwe. (Tak jest na przykład w przypadku algorytmu Strassena).
Ponadto stabilność numeryczna jest co najmniej tak samo ważna jak wydajność; i tutaj znowu standardowe podejście zwykle wygrywa.
Z tego powodu standardowe wysokowydajne biblioteki (BLAS / LAPACK, które Numpy wywołuje, gdy poprosi go o obliczenie odwrotności) zwykle implementują to podejście. Oczywiście istnieją implementacje Numpy np. Algorytmu Strassena, ale algorytm ręcznie dostrojony na poziomie asemblera wyraźnie pokona algorytm napisany w języku wysokiego poziomu dla dowolnego rozsądnego rozmiaru matrycy.O ( n 2. x )O(n3) O(n2.x)
1 Byłbym jednak zły, gdybym nie zauważył, że jest to bardzo rzadko naprawdę konieczne: za każdym razem, gdy trzeba obliczyć produkt , należy zamiast tego rozwiązać układ liniowy (np. using ) i zamiast tego użyj - jest to znacznie bardziej stabilne i można to zrobić (w zależności od struktury macierzy ) znacznie szybciej. Jeśli musisz użyć wiele razy, możesz wstępnie obliczyć faktoryzację (która jest zwykle najdroższą częścią rozwiązania) i użyć go później.A x = b x A A - 1 A
numpy.linalg.solve
źródło
Prawdopodobnie powinieneś zauważyć, że pochowany głęboko w kodzie źródłowym numpy (patrz https://github.com/numpy/numpy/blob/master/numpy/linalg/umath_linalg.c.src ) procedura inv próbuje wywołać funkcję dgetrf z systemowego pakietu LAPACK, który następnie dokonuje dekompozycji LU oryginalnej macierzy. Jest to moralnie równoważne z eliminacją Gaussa, ale można je dostroić do nieco mniejszej złożoności, stosując szybsze algorytmy mnożenia macierzy w wysokowydajnym BLAS.
Jeśli podążysz tą drogą, powinieneś zostać ostrzeżony, że zmuszanie całego łańcucha bibliotek do korzystania z nowej biblioteki zamiast systemowej dostarczonej z twoją dystrybucją jest dość złożone. Jedną alternatywą we współczesnych systemach komputerowych jest spojrzenie na równoległe metody przy użyciu pakietów takich jak scaLAPACK lub (w świecie python) petsc4py. Jednak zazwyczaj są one szczęśliwsze, gdy są stosowane jako solwery iteracyjne dla systemów algebry liniowej, niż stosowane do metod bezpośrednich, a PETSc w szczególności do układów rzadkich bardziej niż gęstych.
źródło