Sembra che non si può fare la tua mente su se le prestazioni o la precisione in virgola mobile è più importante.
Se la precisione in virgola mobile era di estrema precisione, si separano gli elementi positivi e negativi, ordinando ciascun segmento. Quindi sommare in ordine crescente di valore assoluto. Sì, lo so, è più lavoro di chiunque altro, e probabilmente sarà una perdita di tempo.
Invece, utilizzare una precisione adeguata in modo che eventuali errori effettuati siano irrilevanti. Utilizzare buone pratiche numeriche sui test, ecc., In modo tale che non ci siano problemi generati.
quanto riguarda il tempo passa, per una matrice NxM,
sum (A (:)) richiederà N * M-1 aggiunte.
somma (somma (A)) richiede (N-1) * M + M-1 = N * M-1 aggiunte.
Entrambi i metodi richiedono lo stesso numero di add, quindi per un array di grandi dimensioni, anche se l'interprete non è abbastanza intelligente da riconoscere che entrambi sono lo stesso operatore, a chi importa?
Non è semplicemente un problema. Non fare una montagna da una talpa per preoccuparti di questo.
Modifica: in risposta al commento di Amro sugli errori per un metodo rispetto all'altro, c'è poco che puoi controllare. Le aggiunte verranno eseguite in un ordine diverso, ma non vi è alcuna garanzia su quale sequenza sarà migliore.
A = randn(1000);
format long g
Le due soluzioni sono piuttosto vicine. In effetti, rispetto all'EPS, la differenza è appena significativa.
sum(A(:))
ans =
945.760668102446
sum(sum(A))
ans =
945.760668102449
sum(sum(A)) - sum(A(:))
ans =
2.72848410531878e-12
eps(sum(A(:)))
ans =
1.13686837721616e-13
Supponiamo che tu scelga il trucco segregato e di ordinamento che ho menzionato. Vedi che le parti negative e positive saranno abbastanza grandi da far perdere precisione.
sum(sort(A(A<0),'descend'))
ans =
-398276.24754782
sum(sort(A(A<0),'descend')) + sum(sort(A(A>=0),'ascend'))
ans =
945.7606681037
Così realmente avrebbe bisogno di accumulare i pezzi in un array maggiore precisione in ogni caso. Potremmo provare questo:
[~,tags] = sort(abs(A(:)));
sum(A(tags))
ans =
945.760668102446
Un problema interessante si presenta anche in questi test. Ci sarà un problema perché i test sono fatti su un array casuale (normale)? In sostanza, possiamo visualizzare la somma (A (:)) come una passeggiata casuale, una passeggiata di un ubriaco. Ma considera la somma (somma (A)). Ogni elemento della somma (A) (cioè la somma interna) è esso stesso una somma di 1000 deviazioni normali. Guardate alcuni di loro:
sum(A)
ans =
Columns 1 through 6
-32.6319600960983 36.8984589766173 38.2749084367497 27.3297721091922 30.5600109446534 -59.039228262402
Columns 7 through 12
3.82231962760523 4.11017616179294 -68.1497901792032 35.4196443983385 7.05786623564426 -27.1215387236418
Columns 13 through 18
Quando li aggiungiamo, ci sarà una perdita di precisione. Quindi, potenzialmente, l'operazione come somma (A (:)) potrebbe essere leggermente più accurata. È così? Cosa succede se usiamo una precisione più elevata per l'accumulo? Quindi, per prima cosa, formerò la somma delle colonne usando il doppio, quindi convertirò in 25 cifre di precisione decimale e sommerò le righe. (Ho visualizzato solo 20 cifre qui, lasciando 5 cifre nascoste come cifra di guardia.)
sum(hpf(sum(A)))
ans =
945.76066810244807408
O, invece, convertire immediatamente a 25 cifre di precisione, quindi sommando il risultato.
sum(hpf(A(:))
945.76066810244749807
Quindi entrambe le forme in doppia precisione erano ugualmente sbagliate qui, in direzioni opposte. Alla fine, tutto è discutibile, dal momento che qualsiasi alternativa che ho mostrato richiede molto più tempo rispetto alla semplice somma delle variazioni (A (:)) o somma (somma (A)). Scegli uno di loro e non preoccuparti.
Ogni metodo deve percorrere tutti gli elementi della matrice. Quindi sono uguali quando si tratta di complessità. Ti consiglierei di creare due script con metodi diversi, enormi matrici e calcolare il tempo di esecuzione. Prendendo una lunga distanza qui, direi che il secondo è migliore, dal momento che non coinvolge le operazioni di allocazione della memoria, ma come ho detto, è un campo lungo e potrei mancare qualcosa qui. –
È possibile utilizzare le funzioni 'tic' e' toc' di Matlab per eseguire l'esperimento. – Turix
Ho fatto un test rapido e non c'era differenza di velocità. Un vantaggio di 'sum (A (:))' è che non è necessario sapere quante dimensioni 'A' ha; funzionerà per qualsiasi numero di dim. – tmpearce