Wikipedia elenca quattro algoritmi per moltiplicazione di matrice di due matrici nxn .
Quello classico che un programmatore dovrebbe scrivere è O (n 3 ) ed è elencato come "moltiplicazione della matrice scolastica". Sì. O (n 3 ) è un po 'un successo. Diamo un'occhiata al prossimo migliore.
L'algoritmo Strassen è O (n 2.807 ). Questo funzionerebbe - ha alcune restrizioni (come la dimensione è una potenza di due) e ha un avvertimento nella descrizione:
Compared to conventional matrix multiplication, the algorithm adds a considerable O(n2) workload in addition/subtractions; so below a certain size, it will be better to use conventional multiplication.
Per coloro che sono interessati a questo algoritmo e alle sue origini, guardando In che modo Strassen ha trovato il suo metodo di moltiplicazione della matrice? può essere una buona lettura. Fornisce un suggerimento sulla complessità del carico di lavoro iniziale di O (n 2 ) che viene aggiunto e sul motivo per cui ciò sarebbe più costoso della semplice moltiplicazione classica.
Quindi è davvero O (n 2 + n 2.807 ) con quel bit su esponente inferiore n che viene ignorato quando si scrive grande O Sembra che se stai lavorando su una bella matrice 2048x2048, questo potrebbe essere utile. Per una matrice 4x4, probabilmente lo troverà più lento man mano che l'overhead si mangerà tutto il resto.
E poi c'è l'algoritmo Coppersmith-Winograd che è O (n 2.373 ) con alcuni piccoli miglioramenti. Inoltre viene fornito un avvertimento:
The Coppersmith–Winograd algorithm is frequently used as a building block in other algorithms to prove theoretical time bounds. However, unlike the Strassen algorithm, it is not used in practice because it only provides an advantage for matrices so large that they cannot be processed by modern hardware.
Quindi, è meglio quando lavori su matrici super grandi, ma ancora, non utile per una matrice 4x4.
Questo si riflette di nuovo nella pagina di wikipedia in Matrix moltiplicazione: algoritmi sub-cubici che arriva al perché le cose girano più velocemente:
Algorithms exist that provide better running times than the straightforward ones. The first to be discovered was Strassen's algorithm, devised by Volker Strassen in 1969 and often referred to as "fast matrix multiplication". It is based on a way of multiplying two 2 × 2-matrices which requires only 7 multiplications (instead of the usual 8), at the expense of several additional addition and subtraction operations. Applying this recursively gives an algorithm with a multiplicative cost of O(nlog27) ≈ O(n2.807). Strassen's algorithm is more complex, and the numerical stability is reduced compared to the naïve algorithm, but it is faster in cases where n > 100 or so and appears in several libraries, such as BLAS.
E questo è il motivo principale per cui gli algoritmi sono più veloci - si scambiano stabilità numerica e alcune impostazioni aggiuntive. Quella configurazione aggiuntiva per una matrice 4x4 è molto più del costo di fare più moltiplicazione.
E ora, per rispondere alla tua domanda:
But are there some algorithms that are especially efficient for matrices that small?
No, non ci sono algoritmi ottimizzati per la moltiplicazione delle matrici 4x4 perché O (n 3 ) funziona abbastanza ragionevolmente finché non inizi a scoprire che sei disposto a prendere un grande colpisci per sovraccarico. Per la tua situazione specifica, potrebbe esserci un sovraccarico che potresti affrontare conoscendo cose specifiche in anticipo sulle tue matrici (come la quantità di dati che verranno riutilizzati), ma in realtà la cosa più semplice da fare è scrivere un buon codice per O (n 3 ), lascia che sia il compilatore a gestirlo e analizzalo in un secondo momento per vedere se effettivamente il codice è il punto lento nella moltiplicazione della matrice.
Relativo a Math.SE: Numero minimo di moltiplicazioni richieste per invertire una matrice 4x4