Thursday, March 2, 2017

Moving Average Pic

Wie andere schon erwähnt haben, solltest du einen IIR unendlichen Impulsantwortfilter und nicht den FIR Finite Impulsantwortfilter betrachten, den du jetzt benutzt hast. Es gibt noch mehr, aber auf den ersten Blick sind FIR Filter als explizite Windungen und IIR Filter mit Gleichungen implementiert Besonders IIR Filter Ich benutze viel in Mikrocontroller ist ein einpoliger Tiefpassfilter Dies ist das digitale Äquivalent eines einfachen RC Analog Filters Für die meisten Anwendungen haben diese bessere Eigenschaften als der Box Filter, den Sie verwenden Die meisten Anwendungen eines Boxfilters Dass ich begegnet bin ein Ergebnis von jemand nicht Aufmerksamkeit in der digitalen Signalverarbeitung Klasse, nicht als Ergebnis der Notwendigkeit ihrer besonderen Eigenschaften Wenn Sie nur wollen, um hohe Frequenzen abzuschwächen, die Sie wissen, sind Rauschen, ein einpoliger Tiefpassfilter ist besser Der beste Weg, um ein digital in einem Mikrocontroller zu implementieren ist in der Regel. FILT - FILT FF NEU - FILT. FILT ist ein Stück persistenten Zustand Dies ist die einzige persistente Variable, die Sie benötigen, um diesen Filter zu berechnen NEU ist der neue Wert, den der Filter ist Aktualisiert mit dieser Iteration FF ist die Filterfraktion, die die Schwere des Filters anpasst. Schauen Sie sich diesen Algorithmus an und sehen Sie, dass für FF 0 der Filter unendlich schwer ist, da sich die Ausgabe niemals für FF 1 ändert. Es ist wirklich kein Filter seit dem Ausgang Folgt gerade die Eingabe Nützliche Werte sind dazwischen Auf kleinen Systemen wählst du FF auf 1 2 N, so dass die Multiplikation mit FF als rechte Verschiebung durch N Bits erreicht werden kann. Beispielsweise könnte FF 1 16 sein und die Multiplikation mit FF also Eine rechte Verschiebung von 4 Bits Andernfalls braucht dieser Filter nur einen Subtrahier und ein Hinzufügen, obwohl die Zahlen in der Regel breiter sein müssen als der Eingabewert mehr auf numerische Präzision in einem separaten Abschnitt unten. Ich nehme normalerweise AD Lesungen deutlich schneller als sie benötigt werden Und wähle zwei dieser Filter kaskadiert Dies ist das digitale Äquivalent von zwei RC-Filtern in Serie und dämpft um 12 dB Oktave über der Rolloff-Frequenz. Für AD-Messungen ist es in der Regel meist wichtiger, den Filter im Zeitbereich zu betrachten, indem man bedenkt Seine Schrittantwort Dies sagt Ihnen, wie schnell Ihr System eine Veränderung sehen wird, wenn das, was Sie Messungen ändern. Zu erleichtern die Gestaltung dieser Filter, die nur bedeutet Kommissionierung FF und entscheiden, wie viele von ihnen zu kaskaden, ich benutze mein Programm FILTBITS Sie geben die Nummer Von Shift Bits für jede FF in der kaskadierten Reihe von Filtern, und es berechnet die Schrittantwort und andere Werte Eigentlich habe ich in der Regel laufen diese über meine Wrapper-Skript PLOTFILT Dies läuft FILTBITS, die eine CSV-Datei macht, dann zeichnet die CSV-Datei Zum Beispiel, Hier ist das Ergebnis von PLOTFILT 4 4. Die beiden Parameter zu PLOTFILT bedeuten, dass es zwei Filter gibt, die von der oben beschriebenen Art kaskadiert sind. Die Werte von 4 geben die Anzahl der Verschiebungsbits an, um die Multiplikation mit FF zu realisieren. Die beiden FF-Werte sind daher 1 16 In diesem Fall. Die rote Spur ist die Einheit Schritt Antwort, und ist die Hauptsache zu betrachten Zum Beispiel, dies sagt Ihnen, dass, wenn die Eingabe sofort ändert, wird die Ausgabe des kombinierten Filters auf 90 des neuen Wertes in 60 zu begleichen Iterationen Wenn Sie sich um 95 Einschwingzeit kümmern, dann müssen Sie auf 73 Iterationen warten, und für 50 Einschwingzeit nur 26 Iterationen. Die grüne Spur zeigt Ihnen die Ausgabe von einer einzigen Amplitudenspitze Dies gibt Ihnen eine Vorstellung von der zufälligen Geräuschunterdrückung Sieht aus wie keine einzelne Probe wird mehr als eine 2 5 ändern in der Ausgabe. Die blaue Spur ist, um ein subjektives Gefühl von dem, was dieser Filter mit weißen Rauschen Dies ist kein strenger Test, da gibt es keine Garantie, was genau der Inhalt war Der zufälligen Zahlen, die als der weiße Rauschen Eingang für diesen Lauf von PLOTFILT ausgewählt werden Es ist nur, um Ihnen ein grobes Gefühl, wie viel es zerquetscht werden und wie glatt es ist. FOTFILT, vielleicht FILTBITS, und viele andere nützliche Sachen, vor allem Für PIC-Firmware-Entwicklung ist in der PIC-Entwicklungstools Software-Version auf meiner Software-Downloads-Seite verfügbar. Erweiterte über numerische Präzision. I sehen aus den Kommentaren und jetzt eine neue Antwort, dass es Interesse an der Diskussion über die Anzahl der Bits benötigt, um diesen Filter zu implementieren Hinweis Dass die Multiplikation mit FF log 2 FF neue Bits unterhalb des Binärpunktes erzeugt. Bei kleinen Systemen wird FF gewöhnlich 1 2 N gewählt, so dass diese Multiplikation tatsächlich durch eine Rechtsverschiebung von N Bits realisiert wird. FILT ist also meist ein fester Punkt-Ganzzahl Beachten Sie, dass dies keine Mathe aus der Sicht des Prozessors ändert. Wenn Sie beispielsweise 10-Bit-AD-Messwerte und N 4 FF 1 16 filtern, benötigen Sie 4 Bruchbits unterhalb der 10-Bit-Integer-AD-Messwerte Einer der meisten Prozessoren, du machst 16-Bit-Integer-Operationen aufgrund der 10-Bit-AD-Messungen. In diesem Fall kannst du immer noch genau die gleichen 16-Bit-Integer-Opportunitäten ausführen, aber mit den AD-Messungen, die um 4 Bits verschoben wurden, geht der Prozessor nicht Kenne den Unterschied und brauche nicht, um die Mathematik auf ganze 16-Bit-Ganzzahlen zu arbeiten, ob man sie als 12 4 Fixpunkt oder wahre 16-Bit-Ganzzahlen betrachtet 16 0 fester Punkt. Im Allgemeinen müssen Sie N Bits jeden Filterpol hinzufügen, wenn Sie wollen nicht wegen der numerischen Darstellung Rauschen hinzufügen. Im obigen Beispiel müsste der zweite Filter von zwei 10 4 4 18 Bits haben, um keine Informationen zu verlieren. In der Praxis auf einer 8-Bit-Maschine bedeutet das, dass Sie 24-Bit-Werte verwenden Technisch nur der zweite Pol von zwei würde den breiteren Wert brauchen, aber für die Firmware Einfachheit verwende ich gewöhnlich dieselbe Darstellung und damit denselben Code für alle Pole eines Filters. Normalerweise schreibe ich eine Unterroutine oder ein Makro, um einen Filterpolbetrieb auszuführen , Dann wenden Sie diese auf jeden pole Ob ein Subroutine oder Makro hängt davon ab, ob Zyklen oder Programmspeicher sind wichtiger in diesem bestimmten Projekt So oder so, ich benutze einige Kratzer Zustand, um NEU in die Subroutine Makro, die Updates FILT aktualisiert, aber auch lädt, dass In den gleichen Kratzer Zustand NEU war in Dies macht es einfach, mehrere Pole anzuwenden, da die aktualisierte FILT von einem Pole ist die NEU der nächsten Wenn eine Subroutine, ist es sinnvoll, einen Zeiger auf FILT auf dem Weg in, was zu haben Wird aktualisiert, um kurz nach FILT auf dem Weg nach drauf auf diese Weise die Subroutine automatisch auf aufeinanderfolgenden Filtern im Speicher, wenn mehrere Male mit einem Makro Sie don t brauchen einen Zeiger, da Sie die Adresse eingeben, um auf jedem Iteration. Code Beispiele. Hier Ist ein Beispiel für ein Makro, wie oben für ein PIC 18 beschrieben. Und hier ist ein ähnliches Makro für einen PIC 24 oder dsPIC 30 oder 33.Beide diese Beispiele werden als Makros mit meinem PIC Assembler Preprocessor implementiert, der mehr fähig ist als eine der Eingebaute Makroanlagen. Clabacchio Ein weiteres Problem, das ich erwähnt habe, ist die Firmware-Implementierung Sie können einmal ein einzelnes Pole-Tiefpass-Filter-Subroutine schreiben, dann wenden Sie es mehrmals an. In der Tat schreibe ich normalerweise eine solche Unterroutine, um einen Zeiger im Speicher auf den Filterzustand zu setzen Der Zeiger, so dass es nacheinander einfach aufgerufen werden kann, um mehrpolige Filter zu realisieren Olin Lathrop 20. April 12 um 15 03.1 Vielen Dank für Ihre Antworten - alle von ihnen habe ich beschlossen, diesen IIR Filter zu verwenden, aber dieser Filter wird nicht als verwendet Ein Standard-LowPass-Filter, da ich durchschnittliche Zählerwerte verwerten und sie vergleichen muss, um Änderungen in einer bestimmten Reichweite zu erkennen, da diese Werte von sehr unterschiedlichen Dimensionen abhängig von Hardware sind, wollte ich einen Durchschnitt nehmen, um auf diese Hardware reagieren zu können Spezifische Änderungen automatisch sensslen Mai 21 12 um 12 06.Wenn Sie mit der Beschränkung einer Macht von zwei Anzahl von Gegenständen zu durchschnittlich dh 2,4,8,16,32 etc leben können, dann kann die Kluft einfach und effizient auf einem getan werden Low-Performance-Mikro mit keiner dedizierten Divide, weil es als Bit-Shift getan werden kann Jeder Shift rechts ist eine Potenz von zwei zB. Die OP dachte, er hatte zwei Probleme, die Teilung in einem PIC16 und Speicher für seine Ring-Puffer Diese Antwort zeigt, dass die Teilung Ist nicht schwierig zugegebenermaßen adressiert es nicht das Speicherproblem, aber das SE-System erlaubt teilweise Antworten, und Benutzer können etwas von jeder Antwort für sich selbst nehmen oder sogar bearbeiten und kombinieren andere s Antworten Da einige der anderen Antworten eine Teilungsoperation erfordern, sie Sind ähnlich unvollständig, da sie nicht zeigen, wie man dies effizient auf einem PIC16 Martin Apr 20 12 um 13 01.Es gibt eine Antwort für eine echte gleitende durchschnittliche Filter aka Boxcar Filter mit weniger Speicherbedarf, wenn Sie don t mind downsampling It s Genannt ein kaskadierter Integrator-Kamm-Filter CIC Die Idee ist, dass Sie einen Integrator haben, den Sie Unterschiede über einen Zeitraum nehmen, und das Schlüssel speichersparendes Gerät ist, dass durch Downsampling, Sie don t müssen jeden Wert des Integrators speichern Kann mit dem folgenden Pseudocode implementiert werden. Ihre effektive gleitende durchschnittliche Länge ist decimationFactor stateize aber du musst nur um Zustandsmuster zu halten. Offensichtlich kannst du eine bessere Leistung erzielen, wenn dein Status und DecimationFactor Kräfte von 2 sind, so dass die Division und Restbetreiber ersetzt werden Durch verschiebungen und mask-ands. Postscript Ich bin mit Olin einverstanden, dass man immer einfache IIR-Filter vor einem gleitenden durchschnittlichen Filter betrachten sollte Wenn Sie nicht brauchen die Frequenz-Null von einem Boxcar-Filter, eine 1-polige oder 2-polige Low - Pass-Filter wird wahrscheinlich gut funktionieren. Auf der anderen Seite, wenn Sie filtern für die Zwecke der Dezimierung unter einem High-Sample-Rate-Input und Mittelung es für den Einsatz durch einen Low-Rate-Prozess dann ein CIC-Filter kann genau das, was Sie re Vor allem, wenn Sie stateize 1 verwenden können und vermeiden Sie den Ringbuffer insgesamt mit nur einem einzigen vorherigen Integrator Wert. Es gibt eine eingehende Analyse der Mathematik hinter mit dem ersten Auftrag IIR-Filter, die Olin Lathrop bereits über das digitale Signal beschrieben hat Die Verarbeitung von Stack-Austausch umfasst viele schöne Bilder Die Gleichung für diese IIR-Filter ist. Dies kann mit nur Integers implementiert werden und keine Teilung mit dem folgenden Code könnte einige Debugging, wie ich aus dem Speicher war. This Filter nähert sich ein gleitender Durchschnitt der letzten K-Samples durch Setzen des Wertes von alpha auf 1 K Führen Sie dies im vorhergehenden Code durch, indem Sie BITS auf LOG2 K definieren, dh für K 16 gesetzt BITS bis 4, für K 4 gesetzt BITS bis 2, etc. I ll überprüfen den Code aufgeführt Hier, sobald ich eine Änderung bekomme und diese Antwort editiere, wenn nötig. derwered Jun 23 12 am 4 04.Hier ein einpoliger Tiefpassfilter gleitender Durchschnitt, mit Cutoff-Frequenz CutoffFrequenz Sehr einfach, sehr schnell, funktioniert super und fast Kein Speicher overhead. Note Alle Variablen haben Umfang über die Filterfunktion hinaus, außer dass in newInput. Note passiert ist. Dies ist ein einstufiges Filter Mehrere Stufen können zusammenkaskadiert werden, um die Schärfe des Filters zu erhöhen Wenn Sie mehr als eine Stufe verwenden, werden Sie ll Müssen DecayFactor anpassen, bezogen auf die Cutoff-Frequenz, um zu kompensieren. Und offensichtlich alles, was Sie brauchen, ist die beiden Linien platziert irgendwo, sie don t brauchen ihre eigene Funktion Dieser Filter hat eine Ramp-up-Zeit vor dem gleitenden Durchschnitt repräsentiert die der Eingangssignal Wenn Sie diese Rampenzeit umgehen müssen, können Sie MovingAverage einfach auf den ersten Wert von newInput anstelle von 0 initialisieren und hoffen, dass der erste newInput kein Ausreißer ist. CutoffFrequenz SampleRate hat einen Bereich zwischen 0 und 0 5 DecayFactor ist ein Wert zwischen 0 und 1, in der Regel in der Nähe von 1.Single-Präzision Schwimmer sind gut genug für die meisten Dinge, ich bevorzuge einfach doppelt Wenn Sie mit Integers bleiben müssen, können Sie Konvertieren DecayFactor und Amplitude Factor in gebrochene Ganzzahlen, in denen der Zähler als Ganzzahl gespeichert wird, und der Nenner ist eine ganzzahlige Potenz von 2, so dass Sie sich nach rechts als Nenner bitten können, anstatt sich während der Filterschleife zu teilen Beispiel, wenn DecayFactor 0 99, und du willst ganze Zahlen verwenden, kannst du DecayFactor setzen 0 99 65536 64881 Und dann, wenn du dich von DecayFactor in deiner Filterschleife vermehrst, verschiebe einfach das Ergebnis 16.Für weitere Informationen dazu ein exzellentes Buch S online, Kapitel 19 auf rekursive filter. PS Für das Moving Average Paradigma, ein anderer Ansatz zur Einstellung DecayFactor und AmplitudeFactor, die möglicherweise mehr relevant für Ihre Bedürfnisse, sagen wir, Sie wollen die vorherigen, etwa 6 Artikel gemittelt zusammen, tun es diskret , Du fügst 6 Gegenstände hinzu und teile mit 6, so dass du den AmplitudeFactor auf 1 6 setzen kannst und DecayFactor auf 1 0 - AmplitudeFactor. answered am 14. Mai 12 um 22 55. Jeder andere hat sich kommentiert über den Nutzen von IIR vs FIR, Und auf Power-of-Two-Division Ich möchte nur einige Implementierungsdetails geben Die unten funktioniert gut auf kleine Mikrocontroller ohne FPU Es gibt keine Multiplikation, und wenn Sie N eine Macht von zwei behalten, ist die ganze Teilung Single-Cycle-Bit - shifting. Basic FIR Ringpuffer halten einen laufenden Puffer der letzten N Werte und eine laufende SUM aller Werte im Puffer Jedes Mal, wenn ein neues Sample hereinkommt, subtrahiere den ältesten Wert im Puffer von SUM, ersetze ihn mit dem Neues Sample, fügt das neue Sample zu SUM hinzu und gibt SUM N aus. Modifizierter IIR Ringpuffer behält einen laufenden SUM der letzten N Werte Jedes Mal, wenn ein neues Sample kommt, SUM - SUM N, fügen Sie das neue Sample hinzu und geben Sie SUM aus N. answered Aug 28 13 at 13 45.Wenn ich dich richtig richtig lese, beschreibst du einen IIR-Filter erster Ordnung, den Wert, den du subtrahierst, ist nicht der älteste Wert, der herausfällt, sondern stattdessen der Durchschnitt der vorherigen Werte ist Erste-Ordnung-IIR-Filter können sicherlich nützlich sein, aber ich bin mir nicht sicher, was du meinst, wenn du vorschreibst, dass die Ausgabe für alle periodischen Signale gleich ist. Bei einer 10KHz-Abtastrate wird eine 100Hz-Rechteckwelle in einen 20-stufigen Boxfilter geleitet Ergibt ein Signal, das für 20 Abtastungen gleichmäßig ansteigt, für 30 sitzt, für 20 Proben gleichmäßig abfällt und für 30 A für den ersten A-IIR-Filter-Supercat am 28. August bei 15 31 niedrig sitzt. Es wird eine Welle ergeben, die scharf ansteigt und allmählich ansteigt Levels in der Nähe, aber nicht am Eingangsmaximum, dann fängt man scharf an und schreitet allmählich aus, aber nicht am Eingang Minimum Sehr unterschiedliches Verhalten supercat Aug 28 13 bei 15 32.Ein Problem ist, dass ein einfacher gleitender Durchschnitt kann oder nicht nützlich sein Mit einem IIR-Filter kannst du einen schönen Filter mit relativ wenigen Berechnungen bekommen. Die FIR, die du beschreibst, kann dir nur ein Rechteck geben - ein sinc in freq - und du kannst die Seitenlappen nicht verwalten. Es lohnt sich auch Werfen in ein paar Integer Multiplikationen, um es eine schöne symmetrische abstimmbare FIR, wenn Sie die Uhr ticks Scott Seidman Aug 29 13 bei 13 50. ScottSeidman Keine Notwendigkeit für Multiplikationen, wenn man einfach jede Stufe der FIR entweder die Ausgabe der Durchschnitt der Eingabe in diesem Stadium und seinen vorherigen gespeicherten Wert, und dann speichern Sie die Eingabe, wenn man den numerischen Bereich hat, könnte man die Summe anstelle von Durchschnitt verwenden Ob das besser als ein Kastenfilter hängt von der Anwendung die Schrittantwort eines Kastenfilters mit Eine Gesamtverzögerung von 1ms, zum Beispiel, wird eine böse d2 dt Spike haben, wenn die Eingabe ändern, und wieder 1ms später, aber haben die minimale d dt für einen Filter mit einer Gesamtmenge von 1ms Verzögerung supercat Aug 29 13 bei 15 25. Wie mikeselectricstuff sagte, wenn Sie wirklich brauchen, um Ihre Gedächtnisbedürfnisse zu reduzieren, und Sie don t mind Ihre Impulsantwort ein exponentieller statt eines rechteckigen Pulses, würde ich für einen exponentiellen gleitenden durchschnittlichen Filter Ich benutze sie ausgiebig Mit dieser Art von Filter, Du brauchst keinen Puffer Du musst nicht n hintere Samples speichern Nur ein So, deine Speicheranforderungen werden durch einen Faktor von N abgeschnitten. Auch du brauchst keine Division für das Nur Multiplikationen Wenn du Zugriff auf Floating - Punkt-Arithmetik, verwenden Sie Gleitkomma-Multiplikationen Andernfalls tun Sie ganzzahlige Multiplikationen und Verschiebungen nach rechts Allerdings sind wir im Jahr 2012, und ich würde Ihnen empfehlen, Compiler und MCUs zu verwenden, die Ihnen erlauben, mit Gleitkommazahlen zu arbeiten. Besides ist mehr Speicher Effizient und schneller Sie don t haben, um Elemente in jedem kreisförmigen Puffer zu aktualisieren, würde ich sagen, es ist auch natürlicher, weil eine exponentielle Impulsantwort besser ist die Art und Weise die Natur verhält sich in den meisten Fällen. answered Apr 20 12 bei 9 59.Ein Problem mit Der IIR-Filter, der fast von Olin und Supercat berührt wird, aber anscheinend von anderen nicht beachtet wird, ist, dass die Abrundung eine Ungenauigkeit und eine potenzielle Bias-Trunkierung einnimmt, vorausgesetzt, dass N eine Potenz von zwei ist und nur eine ganzzahlige Arithmetik verwendet wird, das Verschiebungsrecht systematisch eliminiert LSBs der neuen Probe Das bedeutet, dass, wie lange die Serie jemals sein könnte, wird der Durchschnitt niemals diese berücksichtigen. Zum Beispiel nehmen wir eine langsam abnehmende Serie 8,8,8 8,7,7,7 7,6,6 an , Und nehmen Sie den Durchschnitt ist in der Tat 8 am Anfang Die Faust 7 Probe wird den Durchschnitt auf 7 bringen, was auch immer die Filterstärke Nur für eine Probe Gleiche Geschichte für 6, etc Jetzt denken, das Gegenteil der Serie geht nach oben Der Durchschnitt wird bleiben auf 7 für immer, bis die Probe groß genug ist, um es zu ändern. Natürlich können Sie für die Bias durch Hinzufügen von 1 2 N 2 korrigieren, aber das gewann t wirklich lösen das Präzisionsproblem in diesem Fall die abnehmende Serie wird für immer bei 8 bleiben Bis die Probe 8-1 2 N 2 ist Für N 4 zum Beispiel wird jede Probe über Null den Durchschnitt unverändert halten. Ich glaube, eine Lösung für das würde bedeuten, einen Akkumulator der verlorenen LSBs zu halten Aber ich habe es nicht weit genug gemacht Um Code bereit zu haben, und ich bin mir nicht sicher, dass es nicht schaden würde die IIR Macht in einigen anderen Fällen von Serien zum Beispiel, ob 7,9,7,9 würde durchschnittlich bis 8 dann. Olin, deine zweistufige Kaskade müsste auch eine Erklärung haben. Du meinst, dass du zwei durchschnittliche Werte mit dem Ergebnis der ersten in die Sekunde in jeder Iteration gefüttert hast. Was ist der Nutzen von diesem. Durchschnittliche gleitende Durchschnitt. Durchschnittlich gleitender Durchschnitt Du bist Ermutigt, diese Aufgabe entsprechend der Aufgabenbeschreibung zu lösen, indem du jede beliebige Sprache verwende, die du den einfachen gleitenden Durchschnitt einer Reihe von Zahlen kennen möchtest. Erreiche eine Stateful-Funktionsklasse-Instanz, die einen Zeitraum annimmt und eine Routine zurückgibt, die eine Zahl als Argument annimmt und eine zurückgibt Einfacher gleitender Durchschnitt seiner bisherigen Argumente. Ein einfacher gleitender Durchschnitt ist eine Methode, um einen Durchschnitt eines Stroms von Zahlen zu berechnen, indem nur die letzten P-Zahlen aus dem Stream gemittelt werden, wobei P als Periode bekannt ist. Es kann durch Aufruf implementiert werden Eine Initialisierungsroutine mit P als Argument, IP, die dann eine Routine zurückgeben sollte, die, wenn sie mit einzelnen, aufeinanderfolgenden Mitgliedern eines Stroms von Zahlen aufgerufen wird, den Mittelwert von bis zu dem letzten P von ihnen berechnet, lasst uns diese SMA anrufen Wort Stateful in der Aufgabe Beschreibung bezieht sich auf die Notwendigkeit für SMA, sich an bestimmte Informationen zwischen Anrufen zu erinnern. Der Zeitraum, P. An bestellt Container von mindestens die letzten P-Nummern aus jedem seiner einzelnen Anrufe. Stateful bedeutet auch, dass aufeinander folgende Anrufe zu Ich, der Initialisierer, sollte getrennte Routinen zurückgeben, die keinen gespeicherten Zustand teilen, damit sie auf zwei unabhängigen Datenströmen verwendet werden können. Pseudocode für eine Implementierung von SMA ist. Diese Version verwendet eine persistente Warteschlange, um die aktuellsten p-Werte zu halten Jede Funktion, die von init-moving-average zurückgegeben wird, hat ihren Zustand in einem Atom, das einen Warteschlangenwert hält. Diese Implementierung verwendet eine kreisförmige Liste, um die Zahlen innerhalb des Fensters am Anfang jedes Iterationszeigers zu speichern, bezieht sich auf die Listenzelle, die den Wert gerade hält Sich aus dem Fenster zu bewegen und durch den gerade hinzugefügten Wert zu ersetzen. Mit einem Closure edit. Currently dieser sma kann t nogc sein, weil er eine Schließung auf dem Heap zuteilt. Einige Escape-Analyse könnte die Heap-Zuweisung entfernen. Using eine Struct-Bearbeitung. Diese Version vermeidet die Heap-Zuordnung der Schließung, die die Daten im Stapelrahmen der Hauptfunktion beibehält. Gleiche Ausgabe. Um zu vermeiden, dass die Gleitkomma-Approximationen sich häufigen und wachsen, könnte der Code eine periodische Summe auf dem gesamten kreisförmigen Warteschlangen-Array ausführen Implementierung erzeugt zwei Funktionsobjekte, die den Status teilen. Es ist idiomatisch in E, die Eingabe von der Ausgabe zu lesen, die aus dem Schreiben gelesen wird, anstatt sie in ein Objekt zu kombinieren. Die Struktur ist die gleiche wie die Implementierung der Standardabweichung E. Das Elixir-Programm unten erzeugt eine anonyme Funktion mit Eine eingebettete Periode p, die als Periode des einfachen gleitenden Durchschnitts verwendet wird Die Run-Funktion liest numerische Eingabe und übergibt sie an die neu erstellte anonyme Funktion und prüft dann das Ergebnis auf STDOUT. Die Ausgabe wird unten gezeigt, mit dem Durchschnitt, Gefolgt von der gruppierten Eingabe, die die Grundlage für jeden gleitenden Durchschnitt bildet. Erlang hat Schließungen, aber unveränderliche Variablen Eine Lösung ist dann, Prozesse zu verwenden und eine einfache Nachricht übergeben basierte API. Matrix Sprachen haben Routinen, um die Gleitende Avarages für eine gegebene Sequenz zu berechnen Es ist weniger effizient zu schleifen wie in den folgenden Befehlen. Kontinuierlich fordert eine Eingabe I, die am Ende einer Liste hinzugefügt wird L1 L1 kann durch Drücken von 2ND 1 gefunden werden, und Mittelwert finden Sie in Liste OPS. Press ON Um das Programm zu beenden. Funktion, die eine Liste mit den gemittelten Daten des mitgelieferten Arguments zurückgibt. Programm, das einen einfachen Wert bei jeder invocation. list zurückgibt, ist die Liste, die gemittelt wird p ist die Periode 5 gibt die gemittelte Liste zurück. Example 2 Mit dem Programm Movinav2 i, 5 - Initialisierung der gleitenden Durchschnittsberechnung und Definieren der Periode von 5 movinav2 3, xx - neue Daten im Listenwert 3 und Ergebnis wird auf Variable x gespeichert und angezeigt movinav2 4, xx - neuer Datenwert 4 und Das neue Ergebnis wird auf Variable x gespeichert und angezeigt 4 3 2.Beschreibung der Funktion movinavg Variable r - ist das Ergebnis der gemittelten Liste, die zurückgegeben wird Variable i - ist die Indexvariable, und es zeigt auf das Ende der Unterliste der Liste wird gemittelte Variable z - eine Helpervariable. Die Funktion verwendet die Variable i, um zu bestimmen, welche Werte der Liste in der nächsten Durchschnittsberechnung berücksichtigt werden. Bei jeder Iteration zeigt die Variable i auf den letzten Wert in der Liste, In der durchschnittlichen Berechnung verwendet werden Also müssen wir nur herausfinden, welche der erste Wert in der Liste werden In der Regel müssen wir p Elemente zu betrachten, so dass das erste Element wird das eine von ip 1 indiziert werden. Allerdings auf die ersten Iterationen, die Berechnung Wird in der Regel negativ sein, so dass die folgende Gleichung negative Indizes max ip 1,1 oder, die Anordnung der Gleichung, max ip, 0 1 Aber die Anzahl der Elemente auf den ersten Iterationen wird auch kleiner sein, wird der richtige Wert Endindex sein - Beginn der Index 1 oder, Anordnen der Gleichung, i - max ip, 0 1 1 und dann, i - max ip, 0 Variable z hält den gemeinsamen Wert max ip, 0 also ist der Anfangsindex z 1 und die Nummernbezüge werden Iz. mid Liste, z 1, iz wird die Liste der Wert, die gemittelte Summe wird Summe sie Summe iz ri wird sie durchschnittlich und speichern Sie das Ergebnis an der entsprechenden Stelle in der Ergebnisliste. fp1 erstellt eine partielle Anwendung die Festsetzung der in In diesem Fall die zweite und dritte Parameter. Es könnte sein, wenn Sie ein Gewicht anwenden, das umgekehrt proportional zum Fenster size. public Klasse AverageCounter int RunningAvg int RunningCount Dies ersetzt die kreisförmige Liste int WindowSize. public AverageCounter int windowSize WindowSize windowSize. public void AddValue Float NewValue wachsen die Fenstergröße, wenn mehr Samples aufgezeichnet werden, wenn RunningCount WindowSize RunningCount. Rekursive gleitende durchschnittliche Durchschn. W - 1 W avg n-1 1 W Probe, wobei W Fenstergröße ist RunningAvg RunningCount - 1 RunningCount RunningAvg 1 RunningCount NewValue. public float Durchschnittliche Rückkehr RunningAvg .-- geändert um 13 53 Freitag, 9. November 2007.pwasser 8-Jan-08 16 25.Diese Formel funktioniert gut, um den gleitenden Durchschnitt zu schätzen, solange ein paar Einschränkungen im Auge behalten werden. Es berechnet eine Schätzung des gleitenden Durchschnitts nicht den realen gleitenden Durchschnitt auf der Grundlage der wichtigen Annahme, dass die Stichprobenwerte sind Normalerweise verteilt über den Mittelwert. Ich wies darauf hin, in einem früheren Post. toadth 9-Oct-11 15 46.Well das war dumm war es nicht 4 Jahre auf und ich könnte einen besseren Vorschlag Anstatt eine kreisförmige Liste verwenden, verwenden Eine verknüpfte Liste und manuell beibehalten die maximale Listengröße Auf diese Weise können Sie eine laufende Summe des Aggregats beibehalten - beim Hinzufügen zur Verknüpfungsliste, fügen Sie dem Aggregat hinzu, beim Zuschneiden eines Knotens subtrahieren Sie diesen Wert aus dem Aggregat Für einen durchschnittlichen Zähler mit 5 Knoten, vielleicht gewannst du eine Aufmerksamkeit auf eine Leistungsverbesserung, aber für viele Fälle mit Tausenden von Knoten, die es bedeuten würde.1 In der AddValue-Methode füge einen neuen Linklistenknoten hinzu und füge nach AVERAGE hinzu 2 Nach dem Hinzufügen, überprüfe die Größe 3 Wenn die Größenschwelle von AVERAGE subtrahieren und dann den Knoten abschneiden soll. Für noch mehr Effizienz, anstatt die verknüpfte Liste zu verwenden, kannst du deine eigene Zirkelliste auf der Grundlage eines Arrays der Werte implementieren, die von AVERAGE subtrahiert werden, wenn du einen Arraywert ersetzst. Marc Clifton 10-Okt-11 1 37.4 Jahre auf und ich könnte einen besseren Vorschlag haben. Infted, das würde besser funktionieren. Ich bin nicht sicher von der richtigen Lösung aber seit der Summierung der Durchschnitt jeder Probe würde eine angemessene Menge an Rundungsfehler einzuführen. Hmm Ich frage mich, ob die Trennung der Bruchteil aus dem ganzen Teil helfen würde, den ganzen Teil jeder Zahl durch die Zählung zu teilen. Halten Sie drei laufende Summen 1 Der Durchschnitt der ganzen Teile, 2 Der Rest jeder Teilung und 3 Der Bruchteil von jedem Number. Jede Zeit, in der der ganze Teil einer Zahl geteilt wird, wird das gesamte Teilergebnis zu der durchschnittlichen laufenden Summe addiert und der Rest wird der Restlaufsumme addiert Wenn die Restlaufsumme einen Wert erhält, der größer oder gleich der Zählung ist, Es wird durch die Zählung geteilt, wobei das ganze Teilergebnis der durchschnittlichen laufenden Summe hinzugefügt wird und der Rest dem Restlaufsumme hinzugefügt wird. Auch bei jeder Berechnung wird der Bruchteil der Bruchmenge addiert. Wenn die Mittelung beendet ist, Restlaufsumme wird durch die Zählung geteilt und das Ergebnis wird der durchschnittlichen laufenden Summe als fließende Zahl hinzugefügt. Zum Beispiel. Wie was mit der fraktionalen laufenden Summe zu tun ist Die Gefahr des Überlaufs ist hier viel weniger wahrscheinlich, wenn auch noch möglich, so ein Weg, um es zu behandeln wäre es, die gebrochene laufende Summe durch die Zählung am Ende zu teilen und es zu unserem Ergebnis hinzuzufügen. Eine Alternative wäre, die gebrochene laufende Summe bei jeder Berechnung zu überprüfen, um zu sehen, ob sie größer oder gleich gleich ist Das passiert, mach einfach das Gleiche, was wir mit dem Rest laufen lassen.


No comments:

Post a Comment