(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 nOnC1n3C2n2.xn
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 AA−1bAx=bnumpy.linalg.solve
xAA−1A