Effiziente (Schnellste) Weg, um die Summe der Elemente der matrix in matlab
Lets have matrix A
sagen A = magic(100);
. Ich habe gesehen 2 Möglichkeiten zur Berechnung der Summe aller Elemente der matrix A
.
sumOfA = sum(sum(A));
Oder
sumOfA = sum(A(:));
Ist einer von Ihnen schneller (oder besser üben), dann andere? Wenn ja, welches ist es? Oder sind Sie beide gleich schnell?
- Jede Methode muss zu Fuß durch jedes element der matrix. Sie sind also genau das gleiche, wenn es um die Komplexität. Ich würde Ihnen empfehlen, machen Sie zwei Skripte mit den verschiedenen Methoden, riesige Matrizen und berechnen Sie deren Ausführungszeit. Einen langen Schuss hier, ich würde sagen das zweite ist besser, da es nicht beinhaltet das memory-alloc-Operationen, aber wie ich schon sagte, es ist eine lange gedreht, und ich kann hier etwas fehlt.
- Sie konnte mit Hilfe von Matlab-s
tic
undtoc
Funktionen führen Sie das experiment. - Ich habe einen schnellen test und es gab keinen Unterschied in der Geschwindigkeit. Ein Vorteil der
sum(A(:))
ist, dass Sie brauchen nicht zu wissen, wie viele DimensionenA
hat; es funktioniert für eine beliebige Anzahl von dims.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es scheint, dass Sie können nicht make up your mind, ob performance-oder floating-point Genauigkeit ist wichtiger.
Wenn Gleitkomma-Genauigkeit von größter Genauigkeit, dann würden Sie trennt die positiven und negativen Elemente, die Sortierung der einzelnen Segmente. Dann Summe in der Reihenfolge der steigenden absoluten Wert. Ja, ich weiß, mehr Arbeit als jeder tun würde, und es wird wahrscheinlich eine Verschwendung von Zeit.
Stattdessen mit ausreichender Genauigkeit, so dass keine Fehler gemacht werden irrelevant. Verwenden Sie gute numerische Verfahren über tests, etc, so dass es keine Probleme erzeugt.
Soweit die Zeit reicht, für eine NxM array,
sum(A(:)) müssen N*M-1 Additionen.
sum(sum(A)) erfordert (N-1)*M + M-1 = N*M-1 Additionen.
Entweder Methode erfordert die gleiche Zahl addiert, so dass für Sie eine große Palette, auch wenn der Dolmetscher ist nicht schlau genug, zu erkennen, dass Sie beide die gleiche op, who cares?
Es ist einfach nicht ein Problem. Machen Sie nicht einen Berg aus einem Maulwurfshügel zu sorgen.
Edit: in Reaktion auf die Amro-Kommentar über die Fehler, für die eine Methode gegenüber der anderen, es ist etwas, die Sie kontrollieren können. Die Zusätze erfolgen in unterschiedlicher Reihenfolge, aber es gibt keine Gewissheit darüber, welche Reihenfolge besser ist.
Die beiden Lösungen sind sich sehr nahe. In der Tat, im Vergleich zu eps ist der Unterschied kaum erheblich.
Angenommen, Sie wählen das trennen und Sortieren trick, den ich erwähnt. Sehen, dass die negativen und positiven Teile groß genug sein, dass es zu einem Verlust an Präzision.
So dass Sie wirklich brauchen würde, zu sammeln die Stücke, die in einer höheren Präzision array sowieso. Wir könnten versuchen, diese:
Ein Interessantes problem ergibt sich auch in diesen tests. Wird es ein Problem sein, weil die tests fertig sind, auf eine zufällige (normal) array? Im wesentlichen können wir sum(A(:)) als random-walk, ein Säufer zu Fuß. Aber betrachten sum(sum(A)). Jedes element von sum(A) (d.h., die innere Summe) ist selbst eine Summe von 1000 normalen abweicht. Blick auf ein paar von Ihnen:
Wenn wir hinzufügen, Sie, es wird ein Verlust von Präzision. So möglicherweise, den Betrieb als sum(A(:)) vielleicht etwas genauer. Ist es so? Was, wenn wir eine höhere Genauigkeit für die Akkumulation? So werde ich zunächst bilden die Summe unten die Spalten mit Hilfe verdoppelt sind, dann konvertieren zu 25 Ziffern der Nachkommastellen, und die Summe der Zeilen. (Ich habe nur angezeigt, 20 Ziffern hier, wobei 5 Ziffern versteckt als guard-Ziffern.)
Oder konvertieren Sie stattdessen sofort zu 25 Ziffern für die Genauigkeit, dann addieren Sie das Ergebnis.
Also beide Formen in double precision waren ebenso falsch hier, in entgegengesetzte Richtungen. Am Ende, das ist alles völlig irrelevant, da eine der alternativen, die ich gezeigt habe, sind weit mehr Zeit in Anspruch im Vergleich zu den einfachen Varianten sum(A(:)) oder sum(sum(A)). Wählen Sie einfach eine von Ihnen und Mach dir keine sorgen.
sum(sum(A))
ist, wenn der Dolmetscher entscheidet, zuweisen einer temporären matrix zu halten, wird das Ergebnis der innerensum
. Wenn Sie dies tun, in der Mitte von einer Schleife, und Sie haben eine sehr große Anzahl von Spalten, die Aufteilung und die Befreiung, die temporäre matrix könnte wiederum in eine Reale performance ziehen. Es ist möglich, dass der Matlab JIT optimiert werden kann dieser Weg, aber ich habe gesehen Art von ähnlichen Situationen, wo es nicht.sum(A(:))
schafft auch eine temp linearisierte matrix/Vektor vor der Durchführung der äußeren SummeA(:)
sollte copy-on-write optimiert. Matlab wird die Aufteilung der Aufwand für eine matrix (ein paar bytes), sondern die Wiederverwendung der Daten. Im Gegensatz dazu, die innere Summe vonsum(sum(A(:)))
nimmt eine MxN-matrix und generiert eine 1xN matrix. Wenn der JIT nicht optimieren das richtig, dass erfordert eine 1xN-matrix zugeordnet werden. Es gibt keine copy-on-write-Optimierung zur Verfügung.A(:)
Kräfte MATLAB, um eine "echte" Kopie, aber Sie haben Recht. Habe es gerade getestet mitformat debug
mitB=A
vsB=A(:)
, hatten beide die gleiche Adresse im Speicher, wieA
. Ich stehe korrigiert 🙂Performance-wise, ich würde sagen, beide sind sehr ähnlich (vorausgesetzt, eine aktuelle MATLAB-version). Hier ist der quick-test mit dem TIMEIT Funktion:
waren die Ergebnisse:
Was würde ich sorgen, floating-point-Probleme. Beispiel:
Fehler Ausmaß erhöht sich für größere Matrizen
ich denke, eine einfache Möglichkeit, zu verstehen, anwenden "tic_ Inhaltsverzeichnis " - Funktion in der ersten und letzten code.
aber wenn Sie verwendet randn-Funktion ,Elemente davon sind random und Zeitpunkt der Berechnung können
verschiedenen in jedem Zyklus CPU Berechnung .
Besser man verwendet eine einzigartige matrix mit so großen Elementen zu vergleichen, die zur Zeit der Berechnung.