(Sta diventando troppo lungo per i commenti ...)
Suppongo che in realtà devi calcolare un inverso nel tuo algoritmo. 1 In primo luogo, è importante notare che questi algoritmi alternativi non sono effettivamente dichiarati più veloci , ma solo che hanno una migliore complessità asintotica (il che significa che il numero richiesto di operazioni elementari cresce più lentamente). In pratica, in pratica questi sono (molto) più lenti dell'approccio standard (per una data ), per i seguenti motivi:n
La notazione nasconde una costante di fronte alla potenza di , che può essere astronomicamente grande - così grande che può essere molto più piccola di per qualsiasi che può essere gestito da qualsiasi computer nel prossimo futuro. (Questo è il caso dell'algoritmo Coppersmith – Winograd, per esempio.) n C 1 n 3 C 2 n 2. x nOnC1n3C2n2.xn
La complessità presuppone che ogni operazione (aritmetica) richieda lo stesso tempo, ma nella pratica reale ciò è tutt'altro che vero: moltiplicare un gruppo di numeri con lo stesso numero è molto più veloce che moltiplicare la stessa quantità di numeri diversi . Ciò è dovuto al fatto che il principale collo di bottiglia nell'attuale elaborazione sta portando i dati nella cache, non le effettive operazioni aritmetiche su tali dati. Quindi un algoritmo che può essere riorganizzato per avere la prima situazione (chiamata cache-aware ) sarà molto più veloce di quello in cui ciò non è possibile. (Questo è il caso dell'algoritmo Strassen, per esempio.)
Inoltre, la stabilità numerica è importante almeno quanto le prestazioni; e qui, di nuovo, l'approccio standard di solito vince.
Per questo motivo, le librerie standard ad alte prestazioni (BLAS / LAPACK, che Numpy chiama quando gli chiedi di calcolare un inverso) di solito implementano solo questo approccio. Naturalmente, ci sono implementazioni Numpy di, ad esempio, l'algoritmo di Strassen là fuori, ma un algoritmo sintonizzato a mano a livello di assemblaggio batterà profondamente un algoritmo scritto in un linguaggio di alto livello per qualsiasi dimensione di matrice ragionevole.O ( n 2. x )O(n3)O(n2.x)
1 Ma mi dispiacerebbe se non facessi notare che questo è molto raramente davvero necessario: ogni volta che devi calcolare un prodotto , dovresti invece risolvere il sistema lineare (ad es. usando ) e usa invece - questo è molto più stabile e può essere fatto (a seconda della struttura della matrice )
molto più velocemente. Se è necessario utilizzare più volte, è possibile pre-calcolare una fattorizzazione di (che di solito è la parte più costosa della risoluzione) e riutilizzarla in seguito.
A x = b x A A - 1 AA−1bAx=bnumpy.linalg.solve
xAA−1A