Sunday 8 October 2017

Moving Average C Source Code


Ich weiß, das ist erreichbar mit Schub wie pro: Aber ich möchte wirklich vermeiden, Boost. Ich habe gegoogelt und fand keine geeigneten oder lesbaren Beispiele. Grundsätzlich möchte ich den gleitenden Durchschnitt eines laufenden Stroms eines Stroms von Gleitkommazahlen mit den aktuellsten 1000 Zahlen als Datenmuster verfolgen. Was ist der einfachste Weg, um dies zu erreichen, experimentierte ich mit einem kreisförmigen Array, einem exponentiellen gleitenden Durchschnitt und einem einfacheren gleitenden Durchschnitt und fand, dass die Ergebnisse aus dem kreisförmigen Array meinen Bedürfnissen am besten entsprechen. Gefragt am 12. Juni 12 um 4:38 Wenn Ihre Bedürfnisse einfach sind, können Sie nur versuchen, einen exponentiellen gleitenden Durchschnitt. Setzen Sie einfach, Sie machen eine Akkumulator-Variable, und wie Ihr Code bei jedem Sample sieht, aktualisiert der Code den Akkumulator mit dem neuen Wert. Sie wählen eine konstante Alpha, die zwischen 0 und 1 ist, und berechnen Sie diese: Sie müssen nur einen Wert von Alpha zu finden, wo die Wirkung einer bestimmten Probe nur für etwa 1000 Proben dauert. Hmm, Im nicht wirklich sicher, dass dies für Sie geeignet ist, jetzt, dass Ive es hier. Das Problem ist, dass 1000 ist ein ziemlich langes Fenster für einen exponentiellen gleitenden Durchschnitt Im nicht sicher, es gibt ein Alpha, die den Durchschnitt über die letzten 1000 Zahlen, ohne Unterlauf in der Gleitkomma Berechnung zu verbreiten würde. Aber wenn du einen kleineren Durchschnitt wünschst, wie 30 Zahlen oder so, das ist eine sehr einfache und schnelle Möglichkeit, es zu tun. Antwortete Jun 12 12 um 4:44 1 auf deinem Post. Der exponentielle gleitende Durchschnitt kann das Alpha variabel sein. So kann es verwendet werden, um Zeitbasis-Mittelwerte (z. B. Bytes pro Sekunde) zu berechnen. Wenn die Zeit seit dem letzten Akkumulator-Update mehr als 1 Sekunde ist, lassen Sie Alpha 1,0 sein. Andernfalls kannst du alpha sein (usecs seit letztem update1000000). Ndash jxh Grundsätzlich möchte ich den gleitenden Durchschnitt eines laufenden Stroms eines Stroms von Gleitkommazahlen mit den aktuellsten 1000 Zahlen als Datenmuster verfolgen. Beachten Sie, dass die unten genannte Gesamtsumme als Elemente als addreplaced, Vermeidung kostspieliger O (N) Traversal, um die Summe zu berechnen - benötigt für die durchschnittliche - on demand. Insgesamt wird ein anderer Parameter von T verwendet, um z. B. Mit einer langen langen, wenn insgesamt 1000 lang s, ein int für char s, oder ein doppeltes bis total float s. Dies ist ein bisschen fehlerhaft, dass Numsamples an INTMAX vorbeikommen könnten - wenn man sich vorstellt, dass man eine langjährige langjährige langwierige Zeit haben könnte. Oder verwenden Sie ein zusätzliches bool Datenelement, um aufzuzeichnen, wenn der Container zum ersten Mal gefüllt wird, während er Numsamples um das Array herumtreibt (am besten dann umbenannt etwas Unschuldiges wie Pos). Antwortete am 12. Juni 12 um 5:19 man geht davon aus, dass der Quanten-Operator (T-Stichprobe) tatsächlich quasi Operator (T-Probe) ist. Ndash oPless Jun 8 14 um 11:52 oPless ahhh. Gut beobachtet. Eigentlich habe ich gedacht, dass es nicht leer ist () (T Probe), aber natürlich könntest du auch immer Notizen verwenden, die du mochst. Werde reden, danke Wenn es möglich ist, einen gleitenden Durchschnitt in C ohne die Notwendigkeit für ein Fenster von Proben Ive gefunden, dass ich ein bisschen optimieren kann, indem Sie eine Fenstergröße, die eine Macht von zwei, um für Bit zu ermöglichen, zu implementieren - Shifting statt zu teilen, aber nicht brauchen einen Puffer wäre schön. Gibt es eine Möglichkeit, ein neues gleitendes durchschnittliches Ergebnis nur als eine Funktion des alten Ergebnisses auszudrücken und das neue Sample Definieren Sie ein Beispiel gleitender Durchschnitt, über ein Fenster von 4 Samples: Add new sample e: Ein gleitender Durchschnitt kann rekursiv implementiert werden , Aber für eine genaue Berechnung des gleitenden Durchschnitts müssen Sie sich an die älteste Eingabe Probe in der Summe (dh die a in Ihrem Beispiel) erinnern. Für eine Länge N gleitenden Durchschnitt berechnen Sie: wobei yn das Ausgangssignal ist und xn das Eingangssignal ist. Gl. (1) kann rekursiv geschrieben werden, also musst du dich immer an die Probe xn-N erinnern, um zu berechnen (2). Wie von Conrad Turner hervorgehoben, können Sie stattdessen ein (unendlich langes) exponentielles Fenster verwenden, mit dem Sie die Ausgabe nur aus der Vergangenheit und dem aktuellen Eingang berechnen können. Dies ist jedoch kein Standard (ungewichtet) gleitender Durchschnitt, sondern exponentiell Gewichteter gleitender Durchschnitt, wo Proben in der Vergangenheit ein kleineres Gewicht bekommen, aber (zumindest in der Theorie) vergisst du niemals etwas (die Gewichte werden in der Vergangenheit immer kleiner und kleiner). Ich habe einen gleitenden Durchschnitt ohne Einzelposten-Speicher für ein GPS-Tracking-Programm, das ich geschrieben habe. Ich fange mit 1 Probe an und teile mit 1, um die aktuelle avg zu bekommen. Ich füge dann eine Probe hinzu und teile mit 2 auf die aktuelle avg. Das geht weiter, bis ich die Länge des Durchschnitts erreicht habe. Jedes Mal danach füge ich die neue Probe hinzu, bekomme den Durchschnitt und beseitige diesen Durchschnitt von der Summe. Ich bin kein Mathematiker, aber das schien ein guter Weg, es zu tun. Ich dachte, es würde den Magen eines echten Mathe-Kerls drehen, aber es stellt sich heraus, dass es eine der akzeptierten Möglichkeiten ist, es zu tun. Und es geht gut Denken Sie daran, dass je höher Ihre Länge desto langsamer ist es, was Sie folgen wollen. Das mag die meiste Zeit nicht ausmachen, aber wenn man den Satelliten folgt, wenn man langsam ist, könnte der Weg weit von der aktuellen Position entfernt sein und es wird schlecht aussehen. Du hättest eine Lücke zwischen dem Sat und den hinteren Punkten. Ich wählte eine Länge von 15 aktualisiert 6 mal pro Minute, um ausreichende Glättung zu bekommen und nicht zu weit von der tatsächlichen Sat-Position mit den geglätteten Pfad-Punkten zu bekommen. Antwortete 16. November 16 um 23:03 initialize total 0, count0 (jedes Mal, wenn du einen neuen Wert sehe, dann eine Eingabe (scanf), man add totalnewValue, ein Inkrement (count), ein divide average (totalcount) Dies wäre ein gleitender Durchschnitt über Alle Eingänge Um den Durchschnitt über nur die letzten 4 Eingänge zu berechnen, würde es 4 Eingangsvariablen erfordern, vielleicht jede Eingabe in einen älteren Eingabevariablen kopieren und dann den neuen gleitenden Durchschnitt berechnen, als Summe der 4 Eingangsvariablen, geteilt durch 4 (rechte Verschiebung 2 wäre Gut, wenn alle Eingänge waren positiv, um die durchschnittliche Berechnung beantwortet Feb 3 15 um 4:06 Das wird tatsächlich berechnen den Gesamtdurchschnitt und NICHT der gleitende Durchschnitt. Wie Zähler wird größer die Auswirkungen einer neuen Eingabe Probe wird verschwindend klein ndash Hilmar Feb 3 15 at 13:53 Ihre Antwort 2017 Stack Exchange, IncC Algorithmus für Null-Latenz exponentiell gleitenden Durchschnitt Letzte Änderung: 2012-08-13 Ich habe versucht, eine Niederfrequenz-Cutoff in c, die im Wesentlichen nimmt einen Strom von Zahlen und glättet Die Ausgabe (Ausfiltern von Hochfrequenz-Bewegungsjitter), aber es ist wichtig, dass die vorderen gewichteten Zahlen sofort betrachtet werden, da die Daten zeitkritisch sind (es ist, eine Bewegungssimulationsbasis mit der Ausgabe von einem Bit der Spielsoftware zu steuern). Ich habe eine funktionierende gewichtete gleitende durchschnittliche Algoithm, aber könnte mit etwas ein wenig mehr reaktionsschnell am vorderen Ende zu tun, und ich fand dies: - Der Pseudocode gibt es wie folgt: Eingaben: Preis (NumericSeries), Periode (NumericSimple) Variablen: Faktor (0), Verzögerung (0) Wenn CurrentBar lt 1 dann ZLEMA beginnen Preisfaktor 2 (Periode1) Verzögerung (Periode-1) 2 Ende sonst beginnen ZLEMA-Faktor (2Price-Pricelag) (1-Faktor) ZLEMA1 Ende Ive übersetzt es in Zu C und mein Code ist wie folgt: Allerdings scheint es nicht so gut zu verhalten wie Id erwarten. Es scheint fast da zu sein, aber manchmal bekomme ich einen etwas niedrigeren Wert als alle Artikel in der Warteschlange (wenn sie alle höher sind). Meine Warteschlange und die Anzahl der Artikel in ihr werden als Parameter übergeben, wobei die jüngste an der Front zu allen Zeiten ist, auch ich passiere einen inkrementierenden Zähler beginnend bei 0, wie es die Funktion verlangt. Im nicht sicher Ive interpretiert die Bedeutung von ZLEMA1 richtig als seine nicht klar in seinem Pseudocode, so Ive davon ausgegangen, dass dies die letzten Anrufe zlema und auch Im Annahme Preis tatsächlich bedeutet Preis0. Vielleicht habe ich das falsch verstanden Bin ich eigentlich die tatsächlichen zlema berechneten Werte zurück zu meiner ursprünglichen Warteschlange kopieren, bevor ich den nächsten Anruf ändere, ändere ich nicht die ursprüngliche Warteschlange an alle anderen als nur das Verschieben aller Werte ein bis zum Ende und das Einfügen der spätesten am Anfang . Der Code, den ich benutze, um dies zu tun ist: Wäre sehr dankbar, wenn jemand mit einem besseren Verständnis der Mathematik könnte bitte Verstand überprüfen, dies für mich zu sehen, ob ich etwas etwas falsch habe Danke so viel im Voraus, wenn Sie helfen können Zuerst danke alles für Ihre Eingabe, sehr geschätzt Das macht Sinn, denke ich, also nehme ich dann das Beste an, auf das ich hoffen kann, ist einfach ein exponentieller gleitender Durchschnitt, der dort akzeptiert wird, wird eine kleine Verzögerung sein, aber das wird durch die schwerere Frontgewichtung minimiert, als in typisch gewichtet gegeben Gleitender Durchschnitt habe ich diesen Algorithmus auch, aber ein ähnliches Problem, dass die Werte nicht ganz richtig erscheinen (es sei denn, dies ist die Natur der Formel). Zum Beispiel, sagen, mein Array enthält 16 Werte, alle 0.4775 - die Ausgabe ist 0.4983, aber Id erwarten, dass es 0.4775 Ist dies Blick auf Sie. Exponentieller bewegter Durchschnitt. Float ema (float vals, int numvals, int currentSample) statischer Floatfaktor 0 statischer Float lastema 0 float ema if (currentSample lt 1) ema vals0 Faktor 2.0 ((float) numvals) 1.0) sonst ema (Faktor vals0) ((1.0 - Faktor) lastema) lastema ema return ema Umgekehrt ist manchmal der Ausgang niedriger als jeder einzelne der Eingänge, auch wenn alle höher sind. Es heißt genauso wie zlema (.) Oben, mit einem inkrementierenden Zähler. Die Formel und der Pseudocode für diesen hier sind: - autotradingstrategy. wordpress20091130exponential-moving-average Danke nochmal, entschuldigung für mein Missverständnis von einigen der Grundlagen: (Mit freundlichen Grüßen, Chris J Wie für den Code, den ich gepostet habe, bist du richtig über die Array-Größe Situation: Das sollte leicht behoben werden. Für Ihre Fragen: 1) Die Filterkonstante stellt eine Frequenzabschaltung dar. Ich habe eine digitale Signalverarbeitung (DSP) für diese Technik verwendet. En. wikipedia. orgwi kiLow-pas sfilter ist eine einfache erklärung. Sie wollen den Abschnitt "Diskrete Zeit". In meinem Fall ist das A die RC-Konstante, über die sie sprechen. Also die Häufigkeit, die es ausschneidet, liegt über 1 (2piA). Wenn Sie nicht ein Verständnis der Frequenz-Domain-Theorie haben, kann dies kompliziert werden. In Ihrem Fall, Je höher Sie machen A, desto niedriger die Frequenz, die dieser Filter erlaubt, was bedeutet, dass es die Kurve mehr und mehr glatt wird. Je niedriger du es machst, desto mehr Lärm, das im System erlaubt ist. Denken Sie daran, dass ein größerer oder gleicher Wert wirksam sein muss. Ich habe wieder die XLS wieder, diesmal ohne die ändernden rand () Zahlen. Passen Sie die A-Konstante an und beobachten Sie, wie es sich um die Hochfrequenzvariationen handelt. 2) Der letzte Punkt des Eingabe-Arrays hat den aktuellsten Wert. 3) Das gleiche gilt für das Ausgabe-Array. Der letzte ist der aktuellste Wert. 5) Die NUMVALS ist willkürlich. Sie können kontinuierlich hinzufügen, um die Eingabe-und Ausgabe-Array so oft wie youd wie und es würde nicht Effekt der Filter. Insbesondere habe ich 49 Punkte benutzt. Aber ich kann die letzten 20 leicht löschen und die ersten 29 Ausgänge bleiben gleich. Die Funktion basiert nicht darauf, wie viele Punkte verwendet werden. Ich möchte erwähnen, dass ich diese Funktion für eine einmalige Umwandlung entwickelt habe. Wenn du eine Umwandlung für den nächsten Wert machen wolltest, kannst du etwas einfacheres ausprobieren (wie beigefügt). Wieder im rostig auf c. Ich hoffe das ist richtig. Das einzige, was Sie benötigen, ist die Eingabe und Filter konstant. Lassen Sie mich wissen, ob das hilft.

No comments:

Post a Comment