Rekursiv Gleitender Mittelwert Algorithmus


Im noch auf dem Groking der F-Sache arbeiten - versuchen, herauszufinden, wie in F denken, anstatt nur die Übersetzung aus anderen Sprachen, die ich kenne. Ive vor kurzem denkend über die Fälle, in denen Sie nicht eine 1: 1 Karte zwischen vorher und nach haben. Fälle, in denen List. map fällt. Ein Beispiel hierfür sind gleitende Mittelwerte, wobei in der Regel len-n1 Ergebnisse für eine Liste der Länge len bei Mittelung über n Elemente. Für die Gurus da draußen, ist dies ein guter Weg, es zu tun (mit der Warteschlange gequetscht von Jomo Fisher) (Vielleicht ein besserer Weg wäre, eine MovingAverageQueue durch Erben von Fifo umzusetzen) fragte Nov 17 08 um 11:12 Ich hatte zu erklären Wie es MovingAverage n (s. Seqltfloatgt), um diese in einem Utility-Modul, weg von der Call-Site, um das Typ-System zu beruhigen. Soweit ich sagen kann, funktioniert dies nur mit Floats, aufgrund einer Einschränkung von Array. average. MSDN Ansprüche kann ich ersetzen, die mit Array. averageBy, um diese auf eine int-Sequenz verwenden, aber das gibt einen anderen Fehler. Brian, können Sie reformulieren diese Antwort, um in generischen Kontexten zu arbeiten, so dass es mit seq-of-any-arithmetic-type, ohne Typpraten arbeiten ndash Warren Young Ich sollte darauf hinweisen, dass meine Notwendigkeit für Diese gleitende Mittelfunktion ist, ein kurzes Fenster (30ish) über einer Folge der ganzen Zahlen zu erhalten, die fast alle in den Millionen sind, also ich don39t Gleitkomma brauchen. Auch eine einzige Stelle rechts vom Dezimalpunkt ist in meiner Anwendung nicht praktikabel. Umwandlung meiner ganzen Zahlen in FP und das Ergebnis zurück zu int nur um die F-Standard-Bibliothek zu beschwichtigen doesn39t appellieren. Ndash Warren Young Wenn Sie kümmern sich um Leistung, dann können Sie berechnen einen gleitenden Durchschnitt effizient mit so etwas (vorausgesetzt waren die Berechnung eines gleitenden Durchschnitt über ein 3-Tage-Fenster) Der harte Teil über dieses hält Auf Ihrer vorherigen laufenden Gesamt - und Anzahl N-Fenster. Ich kam mit dem folgenden Code: Diese Version ist nicht so schön aussehende wie die Haskell-Code, aber es sollte Performance-Probleme mit der Neuberechnung Ihres Fensters bei jedem Lauf zu vermeiden. Es hält eine laufende Summe und hält zuvor verwendeten Zahlen in einer Warteschlange, so sollte es sehr schnell sein. Nur für Spaß, schrieb ich einen einfachen Benchmark: Wenn Sie über Leistung und wie eleganten Code dann versuchen Verwenden Sie FSUnit können wir es testen Der Trick des Algorithmus ist die erste Summe die ersten n-Zahlen und dann eine laufende Summe, indem Sie den Kopf Des Fensters und Subtrahieren des Schwanzes des Fensters. Das Schiebefenster wird erreicht, indem man einen Selbstzip auf der Sequenz ausführt, aber mit dem zweiten Argument zum Zip, das durch die Fenstergröße erweitert wird. Am Ende der Pipeline teilen wir die laufende Summe mit der Fenstergröße auf. Anmerkung scan ist gerade wie Falte aber liefert jede Version des Zustandes in eine Reihenfolge. Eine noch elegantere Lösung, obwohl possibley mit Performance-Hit ist es, die Beobachtung, dass, wenn wir Null-Pad die Sequenz brauchen wir nicht brauchen, um die anfängliche Summe zu berechnen. Es könnte ein Performance-Hit aufgrund der zweiten Indirektion im Zusammenhang mit der Umhüllung der beiden Sequenzen, aber vielleicht ist es nicht signifikant abhängig von der Größe des Fensters beantwortet Aug 31 12 at 8: 06Der Hauptfehler in Ihrem Programm ist, dass die rekursive Berechnung ist falsch. Um den Durchschnitt zu berechnen, müssen Sie die Summe aus dem aktuellen Wert und den verbleibenden Werten erhalten. Dann teilen Sie diese Summe durch die Anzahl der Werte. Die Anzahl der Werte ist num. Der aktuelle Wert ist, was calculatenumber () zurückgibt. Die Summe der verbleibenden Werte ist num-1 multipliziert mit dem Mittelwert der verbleibenden Werte. Der Mittelwert der verbleibenden Werte wird durch einen rekursiven Aufruf von average () berechnet. So schreiben wir folgendes: Ein komplettes Programm, das diese Funktion verwendet, könnte so aussehen: Beachten Sie, dass dies kein sehr guter Weg ist, um den Durchschnitt zu berechnen, weil Sie die Genauigkeit jedes Mal verlieren, wenn Sie die aktuelle Summe durch num teilen. Wenn dieser Durchschnitt wieder multipliziert wird, wenn der rekursive Aufruf zurückkehrt, werden die signifikanten Stellen, die Sie in der Abteilung verloren haben, nicht wiederhergestellt. Sie zerstören Informationen, indem Sie die Summe dividieren und dann multiplizieren. Für mehr Präzision, würden Sie wollen, um die Summe zu halten, wie Sie durch die Elemente gehen, dann teilen sich am Ende. Ein weiterer Punkt zu betrachten ist, was durch einen gleitenden Durchschnitt gemeint ist. Was wir oben implementiert haben, ist kein gleitender Durchschnitt, sondern ein fester Durchschnitt. Es ist der Durchschnitt eines festen Fensters von Elementen. Wenn Sie das Fenster um eine Position verschieben, müssen Sie alles von vorne beginnen und die Summe erneut berechnen. Der richtige Weg, um ein bewegliches Fenster zu implementieren ist, alle Elemente im Fenster zu verfolgen. Wenn Sie das Fenster um eine Position nach rechts verschieben, entfernen Sie das am weitesten links liegende Element aus dem Fenster und subtrahieren dessen Wert aus der Summe, fügen dann das neue Element am rechten Rand dem Fenster hinzu und fügen seinen Wert zur Summe hinzu. Das macht es eine bewegliche Summe. Das Teilen der beweglichen Summe durch die Anzahl der Elemente gibt Ihnen den gleitenden Durchschnitt. Die natürliche Weise, ein sich bewegendes Fenster zu implementieren, ist mit einer Warteschlange, weil Sie dem Kopf neue Elemente hinzufügen und alte Elemente aus dem Schwanz entfernen können. Antwort Zitiert am 22. November 14 um 17: 44Die Wissenschaftler und Ingenieure Leitfaden für digitale Signalverarbeitung Von Steven W. Smith, Ph. D. Ein enormer Vorteil des gleitenden Mittelfilters besteht darin, dass er mit einem sehr schnellen Algorithmus implementiert werden kann. Um diesen Algorithmus zu verstehen, stellen Sie sich vor, ein Eingangssignal, x, durch ein siebenpunktiges gleitendes Durchschnittsfilter zu führen, um ein Ausgangssignal y zu bilden. Nun wird untersucht, wie zwei benachbarte Ausgangspunkte y 50 und y 51 berechnet werden: Es sind fast dieselben Berechnungspunkte x 48 bis x 53 für y 50 und für y 51 zu addieren. Wenn y 50 bereits berechnet wurde Ist der effizienteste Weg zum Berechnen von y 51: Nachdem y 51 unter Verwendung von y 50 gefunden worden ist, kann y 52 aus der Probe y 51 und so weiter berechnet werden. Nachdem der erste Punkt in y berechnet ist, können alle anderen Punkte mit nur einer Addition und Subtraktion pro Punkt gefunden werden. Dies kann in der Gleichung ausgedrückt werden: Beachten Sie, dass diese Gleichung zwei Datenquellen verwendet, um jeden Punkt in der Ausgabe zu berechnen: Punkte von der Eingabe und vorher berechnete Punkte von der Ausgabe. Dies wird als rekursive Gleichung bezeichnet, dh das Ergebnis einer Berechnung wird in zukünftigen Berechnungen verwendet. (Der Begriff rekursive hat auch andere Bedeutungen, vor allem in der Informatik). Kapitel 19 behandelt eine Vielzahl von rekursiven Filtern genauer. Beachten Sie, dass sich das gleitende, durchschnittliche rekursive Filter sehr von den typischen rekursiven Filtern unterscheidet. Insbesondere haben die meisten rekursiven Filter eine unendlich lange Impulsantwort (IIR), bestehend aus Sinusoiden und Exponentialen. Die Impulsantwort des gleitenden Mittelwertes ist ein Rechteckimpuls (endliche Impulsantwort oder FIR). Dieser Algorithmus ist aus mehreren Gründen schneller als andere digitale Filter. Erstens gibt es nur zwei Berechnungen pro Punkt, unabhängig von der Länge des Filterkerns. Zweitens sind Addition und Subtraktion die einzigen mathematischen Operationen, während die meisten digitalen Filter eine zeitaufwändige Multiplikation erfordern. Drittens ist das Indexierungsschema sehr einfach. Jeder Index in Gl. 15-3 durch Addieren oder Subtrahieren von ganzzahligen Konstanten gefunden, die berechnet werden können, bevor die Filterung beginnt (d. h. p und q). Weiter kann der gesamte Algorithmus mit Ganzzahldarstellung durchgeführt werden. Abhängig von der verwendeten Hardware können ganze Zahlen mehr als eine Größenordnung schneller als der Gleitpunkt sein. Überraschenderweise arbeitet die Ganzzahldarstellung besser als der Gleitkommawert mit diesem Algorithmus, zusätzlich zu dem, was schneller ist. Der Rundungsfehler der Gleitpunktarithmetik kann zu unerwarteten Ergebnissen führen, wenn Sie nicht vorsichtig sind. Stellen Sie sich zum Beispiel ein 10.000 Probensignal vor, das mit diesem Verfahren gefiltert wird. Der letzte Abtastwert im gefilterten Signal enthält den akkumulierten Fehler von 10.000 Additionen und 10.000 Subtraktionen. Dies erscheint im Ausgangssignal als Driftversatz. Integers dont haben dieses Problem, weil es keine Round-off-Fehler in der Arithmetik. Wenn Sie mit diesem Algorithmus Fließkommazahlen verwenden müssen, zeigt das Programm in Tabelle 15-2, wie ein Doppelpräzisionsakkumulator verwendet wird, um diese Drift zu eliminieren.

Comments

Popular Posts