Thursday 20 April 2017

Moving Average Rekursive Implementierung


Der Hauptfehler in Ihrem Programm ist, dass die rekursive Berechnung falsch ist. 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, da 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. Beantwortet Nov 22 14 um 17: 44The Moving Average als Filter Der gleitende Durchschnitt wird oft für die Glättung von Daten in Anwesenheit von Rauschen verwendet. Der einfache gleitende Durchschnitt wird nicht immer als der Finite Impulse Response (FIR) - Filter erkannt, der es ist, während er tatsächlich einer der gebräuchlichsten Filter in der Signalverarbeitung ist. Wenn man sie als Filter betrachtet, kann man sie beispielsweise mit gefensterten Filtern vergleichen (siehe Artikel zu Tiefpaß-, Hochpass - und Bandpass - und Bandsperrfiltern für Beispiele). Der Hauptunterschied zu diesen Filtern besteht darin, daß der gleitende Durchschnitt für Signale geeignet ist, für die die Nutzinformation im Zeitbereich enthalten ist. Von denen Glättungsmessungen durch Mittelung ein Paradebeispiel sind. Window-sinc-Filter, auf der anderen Seite, sind starke Künstler im Frequenzbereich. Mit Ausgleich in der Audioverarbeitung als typisches Beispiel. Es gibt einen detaillierteren Vergleich beider Arten von Filtern in Time Domain vs. Frequency Domain Performance von Filtern. Wenn Sie Daten haben, für die sowohl die Zeit als auch die Frequenzdomäne wichtig sind, dann möchten Sie vielleicht einen Blick auf Variationen auf den Moving Average werfen. Die eine Anzahl gewichteter Versionen des gleitenden Durchschnitts zeigt, die besser sind. Der gleitende Durchschnitt der Länge (N) kann so definiert werden, wie er üblicherweise implementiert ist, wobei der aktuelle Ausgabeabtastwert der Durchschnitt der vorhergehenden (N) Abtastwerte ist. Als Filter betrachtet, führt der gleitende Durchschnitt eine Faltung der Eingangsfolge (xn) mit einem rechteckigen Puls der Länge (N) und der Höhe (1N) durch (um den Bereich des Pulses und damit die Verstärkung des Filters zu erzeugen , eins ). In der Praxis ist es am besten, (N) ungerade zu nehmen. Obwohl ein gleitender Durchschnitt auch unter Verwendung einer geraden Anzahl von Abtastwerten berechnet werden kann, hat die Verwendung eines ungeradzahligen Wertes für (N) den Vorteil, daß die Verzögerung des Filters eine ganzzahlige Anzahl von Abtastwerten ist, da die Verzögerung eines Filters mit (N) Proben genau ((N-1) 2). Der gleitende Durchschnitt kann dann exakt mit den ursprünglichen Daten ausgerichtet werden, indem er um eine ganze Zahl von Abtastwerten verschoben wird. Zeitdomäne Da der gleitende Durchschnitt eine Faltung mit einem rechteckigen Puls ist, ist sein Frequenzgang eine sinc-Funktion. Dies macht es ähnlich dem Dual des Fenstersynchronfilters, da es sich hierbei um eine Faltung mit einem Sinc-Puls handelt, der zu einem rechteckigen Frequenzgang führt. Es ist diese sinc Frequenzantwort, die den gleitenden Durchschnitt ein schlechter Darsteller im Frequenzbereich macht. Allerdings führt es sehr gut im Zeitbereich. Daher ist es perfekt, um Daten zu löschen, um Rauschen zu entfernen, während gleichzeitig eine schnelle Sprungantwort beibehalten wird (1). Für das typische Additiv-Weiß-Gauß-Rauschen (AWGN), das oft angenommen wird, hat die Mittelung (N) - Proben den Effekt, das SNR um einen Faktor von (sqrt N) zu erhöhen. Da das Rauschen für die einzelnen Proben unkorreliert ist, gibt es keinen Grund, jede Probe unterschiedlich zu behandeln. Daher wird der gleitende Durchschnitt, der jeder Probe das gleiche Gewicht gibt, die maximale Menge an Rauschen für eine gegebene Sprungantwortschärfe beseitigen. Implementierung Da es sich um ein FIR-Filter handelt, kann der gleitende Durchschnitt durch Faltung implementiert werden. Es hat dann die gleiche Effizienz (oder das Fehlen davon) wie jedes andere FIR-Filter. Sie kann aber auch rekursiv und effizient umgesetzt werden. Es folgt unmittelbar aus der Definition, daß diese Formel das Ergebnis der Ausdrücke für (yn) und (yn1) ist, dh, daß die Veränderung zwischen (yn1) und (yn) ein zusätzlicher Term (xn1N) ist Das Ende, während der Term (xn-N1N) von Anfang entfernt wird. In praktischen Anwendungen ist es oft möglich, die Division durch (N) für jeden Term auszulassen, indem die resultierende Verstärkung von (N) an einer anderen Stelle kompensiert wird. Diese rekursive Umsetzung wird viel schneller als Faltung. Jeder neue Wert von (y) kann mit nur zwei Additionen anstelle der (N) Additionen berechnet werden, die für eine einfache Implementierung der Definition erforderlich wären. Eine Sache, mit der Sie nach einer rekursiven Implementierung Ausschau halten, ist, dass Rundungsfehler akkumulieren. Dies kann ein Problem für Ihre Anwendung sein oder auch nicht, aber es bedeutet auch, dass diese rekursive Implementierung tatsächlich mit einer Integer-Implementierung besser funktionieren wird als mit Gleitkommazahlen. Dies ist sehr ungewöhnlich, da eine Gleitkomma-Implementierung gewöhnlich einfacher ist. Der Schluss davon muss sein, dass Sie die Nützlichkeit des einfachen gleitenden Durchschnittsfilters in Signalverarbeitungsanwendungen nie unterschätzen sollten. Filter Design Tool Dieser Artikel wird mit einem Filter Design Tool ergänzt. Experimentiere mit verschiedenen Werten für (N) und visualisiere die resultierenden Filter. Probieren Sie es jetztIm Implementierung eines 80-72-64-48 Multi-Pass-Gleitmittel-Filter für ein eingebettetes System in C und in festen Punkt. Die Implementierung ist ein kreisförmiger Puffer, der eine laufende Summe beibehält und yn yn-1 xn - xn-M berechnet, wobei M die Länge eines Filters ist. Dies geschieht für jedes Subfilter mit der Ausgabe von einem, das als Eingang für ein anderes dient. Im Skalierung meine Koeffizienten durch 2, die mir Koeffizienten der Länge 2 oder 2 in Abhängigkeit von der Filterlänge. Dann wird das Ergebnis wieder um 2 skaliert, um die richtige Ausgabe zu erhalten. Nun sieht alles gut auf kurze Zeit Skalen aber über lange Zeit bekomme ich eine Drift. Der Grund für die rekursive Implementierung besteht darin, Berechnungen auf einem eingebetteten Prozessor zu speichern. Ich habe Bild von einigen der Einbauten meines Filters enthalten, dies ist, wenn eine Sprungantwort angewendet wird, und wir können die Übertragungsfunktionen der Filter sehen, die Form, Quadrat, Dreieck und dann annähernd ein Gaussian, so dass der Filter wie erwartet funktioniert. Gibt es eine Möglichkeit, dies zu beheben, und wo ist die wahrscheinlichste Quelle für diese. Ist diese Drift aufgrund ein bisschen verloren in der Verschiebung oder etwas anderes. Die Drift ist bei DC-Eingängen nicht vorhanden, bei AC-Signalen dagegen langsam. LÖSUNG: Das Problem war in der Akkumulator als robert vorgeschlagen in den Kommentaren. Das Problem war, dass ein Element der Berechnung durch eine zusätzliche Auf-und Ab-Verschiebung im Vergleich zu den anderen gegangen, die einen runden Versatz, dass angesammelt erstellt. Dass der xn-M, der subtrahiert wird, genau der gleiche Wert wie xn ist, der M Samples hinzugefügt wurde, ist der Akkumulator yn, der gerundet oder in irgendeiner Weise quantisiert wird. So dass Sie wirklich wollen, eine bewegliche Summe zu tun. Anstatt einen gleitenden Durchschnitt und skalieren Sie die Ausgabe Ihrer bewegten Summe (mit 1M), um Ihnen den Durchschnitt. Dies ist ziemlich machbar und noch besser in Fixpunkt statt Gleitkomma getan. Ndash robert bristow-johnsonScaling der Koeffizientenquot Ich gehe davon aus, dass Sie durch M nach jeder Stufe teilen, und das ist der Koeffizient, den Sie skalieren Das ist wahrscheinlich die Ursache des Offsets. Besser dann durch Prod Mi am Ende aller Filter zu teilen. Sie müssen den Überblick über die internen Amplituden aber wie Sie schließlich überlaufen die Akkumulatoren zu halten. Dies ist jedoch leicht durch Modulo-Arithmetik (von denen zwei39s Komplement ist ein spezieller Fall) gelöst. Ndash Oscar Apr 28 15 at 7:00 Oscar, das ist ein Fixpunktfilter. Bedeutung i only do integer arithmetic. Für einen gleitenden Mittelwert der Länge gt 1 mit Verstärkung 1 werden die Filterkonstanten ein Bruch sein, der nicht in ganzen Zahlen darstellbar ist. Also werden die Koeffizienten skaliert, um sie ganzzahlig zu machen, indem man sie links x viele Bits verschiebt. Aus diesem Grund muss der endgültige Ausgang auch um so viele Bits nach rechts verschoben werden. Ich kann keine laufende Summe durch alle 4 Filter halten, ohne den Ausgang dazwischen wiederherzustellen, das Eingangssignal beträgt 16 Bit und mit dem Koeffizienten Skalierung und Längen Ein einzelner filter mein gesamter akkumulatorraum von 32 bit ndash user70614 Apr 28 15 um 8:20

No comments:

Post a Comment