Er det mulig å implementere et bevegelige gjennomsnitt i C uten at det er behov for et vindu med prøver Ive har funnet ut at jeg kan optimalisere litt ved å velge en vindustørrelse som er en kraft på to for å tillate bitforskyvning i stedet for å dele, men ikke trenger en buffer ville være hyggelig. Er det en måte å uttrykke et nytt glidende gjennomsnittsresultat bare som en funksjon av det gamle resultatet og den nye prøven. Definer et eksempel glidende gjennomsnitt, over et vindu på 4 prøver å være: Legg til ny prøve e: Et glidende gjennomsnitt kan implementeres rekursivt , men for en nøyaktig beregning av det bevegelige gjennomsnittet må du huske den eldste innsatsprøven i summen (dvs. a i eksempelet ditt). For et lengde N bevegelige gjennomsnitt beregner du: hvor yn er utgangssignalet og xn er inngangssignalet. Eq. (1) kan skrives rekursivt som Så du må alltid huske prøven xn-N for å beregne (2). Som påpekt av Conrad Turner, kan du bruke et (uendelig langt) eksponensielt vindu i stedet, som gjør det mulig å beregne utgangen bare fra tidligere utgang og gjeldende inngang: men dette er ikke et standard (uvevet) glidende gjennomsnitt, men eksponentielt vektet glidende gjennomsnitt, hvor prøver tidligere i det siste får en mindre vekt, men (i det minste i teorien) glemmer du aldri noe (vektene blir bare mindre og mindre for prøver langt i det siste). Jeg implementerte et glidende gjennomsnitt uten individuelt elementminne for et GPS-sporingsprogram jeg skrev. Jeg starter med 1 prøve og deler med 1 for å få dagens avg. Jeg legger til en prøve og deler med 2 til den nåværende avg. Dette fortsetter til jeg kommer til lengden av gjennomsnittet. Hver gang etterpå legger jeg til den nye prøven, får gjennomsnittet og fjerner det gjennomsnittet fra totalen. Jeg er ikke en matematiker, men dette virket som en god måte å gjøre det på. Jeg skjønte at det ville slå magen til en ekte matte fyr, men det viser seg at det er en av de aksepterte måtene å gjøre det på. Og det fungerer bra. Bare husk at jo høyere lengden jo tregere følger det du vil følge. Det kan ikke være noe som helst mesteparten av tiden, men når du følger satellitter, hvis du er treg, kan stien være langt fra den faktiske posisjonen, og det vil se dårlig ut. Du kan ha et mellomrom mellom lørdager og de etterfølgende prikkene. Jeg valgte en lengde på 15 oppdatert 6 ganger i minuttet for å få tilstrekkelig utjevning og ikke komme for langt fra den faktiske lette stillingen med glattestrekpunktene. besvart 16 nov 16 kl 23:03 initialiser totalt 0, count0 (hver gang vi ser en ny verdi) En innskriving (scanf), en legger til totalnewValue, ett inkrement (telle), en del av gjennomsnitt (totalt antall) Dette ville være et bevegelige gjennomsnitt over alle innganger For å beregne gjennomsnittet over bare de siste 4 inngangene, ville det kreve 4 inngangsvariabler, kanskje kopiering av hvert inngang til en eldre inputvariable og deretter beregning av det nye glidende gjennomsnittet. Som summen av de 4 inngangsvariablene delt med 4 (høyre skift 2 ville være bra hvis alle inngangene var positive for å gjøre gjennomsnittlig beregning besvart 3. februar klokken 4:06 som faktisk vil beregne gjennomsnittet og IKKE det bevegelige gjennomsnittet. Etter hvert som tellingen blir større, blir virkningen av en ny inngangsprøve forsvunnet liten ndash Hilmar Feb 3 15 kl 13:53 Svaret 2017 Stack Exchange, IncIm koder noe for øyeblikket hvor jeg tar en mengde verdier over tid fra et maskinvarekompass. Dette kompasset er veldig nøyaktig og oppdateres veldig ofte, med det resultat at hvis det jiggles litt, jeg ender med den merkelige verdien som er vildt inkonsekvent med sine naboer. Jeg vil glatte ut disse verdiene. Etter å ha gjort noe å lese rundt, ser det ut til at det jeg ønsker er et høypassfilter, et lavpassfilter eller et bevegelig gjennomsnittsnivå. Flytte gjennomsnittet jeg kan komme ned med, bare hold en historie om de siste 5 verdiene eller hva som helst, og bruk gjennomsnittet av disse verdiene nedstrøms i koden min, der jeg en gang bare brukte den nyeste verdien. Det burde, tror jeg, glatt ut de jiggles pent, men det synes meg at det er nokså ineffektivt, og dette er trolig en av de kjente problemene til de riktige programmene som det er en veldig fin Clever Math-løsning. Jeg er imidlertid en av de forferdelige selvlærte programmørene uten å ha en formell utdannelse i noe som helst vevt relatert til CompSci eller Math. Lese rundt litt tyder på at dette kan være et høyt eller lavt passfilter, men jeg kan ikke finne noe som forklarer i forståelse for en hack som meg, hvordan effekten av disse algoritmene ville være på en rekke verdier, enn si hvordan matematikken virker. Svaret gitt her. for eksempel teknisk svar på spørsmålet mitt, men bare når det gjelder forståelig for de som sikkert ville vite hvordan å løse problemet. Det ville være en veldig fin og smart person som kunne forklare hva slags problem dette er, og hvordan løsningene fungerer, forståelig for en kunsteksamen. spurte 21 september 10 kl 13:01 Hvis det bevegelige gjennomsnittet ditt må være lengre for å oppnå den nødvendige utjevningen, og du egentlig ikke trenger noen bestemt form for kjernen, så er du bedre hvis du bruker et eksponentielt forfallende glidende gjennomsnitt: hvor du velg liten for å være en passende konstant (f. eks. hvis du velger liten 1 - 1N, vil den ha samme mengde gjennomsnitt som et vindu med størrelse N, men fordelt annerledes over eldre punkter). Uansett, siden den neste verdien av glidende gjennomsnitt bare avhenger av den forrige og dataene dine, trenger du ikke å holde en kø eller noe. Og du kan tenke på dette som å gjøre noe som, Vel, jeg har et nytt poeng, men jeg stoler ikke på det, så jeg skal holde 80 av mitt gamle estimat av målingen, og bare stol på dette nye datapunktet 20. Thats Tja, det samme som å si: Vel, jeg stoler bare på dette nye punktet 20, og jeg bruker 4 andre poeng som jeg stoler på i samme mengde, bortsett fra at i stedet for å eksplisitt ta de 4 andre punktene, antar du at gjennomsnittsverdien du gjorde sist var fornuftig, slik at du kan bruke ditt tidligere arbeid. svaret 21 september 10 kl 14:27 Hei, jeg vet at dette er 5 år sent, men takk for et fantastisk svar. I39m jobber på et spill hvor lyden endres basert på hastigheten din, men på grunn av å kjøre spillet på en slow-ass-datamaskin, vil hastigheten svinge vilt, noe som var fint for styring, men veldig irriterende når det gjelder lyd. Dette var en veldig enkel og billig løsning på noe jeg trodde ville være et veldig komplekst problem. ndash Adam Mar 16 15 kl 20:20 Hvis du prøver å fjerne en og annen merkelig verdi, er et lavpassfilter det beste av de tre alternativene du har identifisert. Lavpasningsfiltre tillater lavhastighetsendringer som de som forårsakes ved å rotere et kompass for hånd, mens for eksempel avslag på høyhastighets endringer som for eksempel forårsaket av støt på veien. Et glidende gjennomsnitt vil trolig ikke være tilstrekkelig, siden effekten av et enkelt blip i dataene dine vil påvirke flere påfølgende verdier, avhengig av størrelsen på det bevegelige gjennomsnittsvinduet. Hvis de ulige verdiene enkelt oppdages, kan du til og med være bedre med en glitch-fjerningsalgoritme som helt ignorerer dem: Her er en guikdiagram som illustrerer: Den første grafen er inngangssignalet, med en ubehagelig glitch. Den andre grafen viser effekten av et 10-prøve glidende gjennomsnitt. Den endelige grafen er en kombinasjon av 10-prøve gjennomsnittet og den enkle glitchdeteksjonsalgoritmen vist ovenfor. Når feilen oppdages, brukes 10-prøve gjennomsnittet i stedet for den faktiske verdien. besvart 21 sep 10 kl 13:38 pent forklart og bonuspoeng for grafen) ndash Henry Cooke 22. september kl 10:50 Wow. Svært så så et fint svar ndash Muis 4 juni 13 kl 9:14 Det bevegelige gjennomsnittet er et lavpasfilter. ndash nomen 21 okt 13 kl 19:36 Prøv en runningstreaming median i stedet. ndash kert Apr 25 14 kl 22:09 Flytende gjennomsnitt jeg kan komme ned med. men det synes meg at det sannsynligvis er ganske ineffektivt. Theres egentlig ingen grunn til at et glidende gjennomsnitt burde være ineffektivt. Du beholder antall datapunkter du vil ha i noen buffer (som en sirkulær kø). På hvert nytt datapunkt poperer du den eldste verdien og trekker den fra en sum, og trykker den nyeste og legger den til summen. Så hvert nytt datapunkt innebærer egentlig bare en poppush, et tillegg og en subtraksjon. Ditt bevegelige gjennomsnitt er alltid denne skiftende summen delt på antall verdier i bufferen din. Det blir litt vanskeligere hvis du mottar data samtidig fra flere tråder, men siden dataene kommer fra en maskinvareenhet som synes svært tvilsom for meg. Oh og også: forferdelige selvlærte programmører forene) Det bevegelige gjennomsnittet virket ineffektivt for meg fordi du må lagre en buffer av verdier - bedre å bare gjøre litt Clever Maths med din inngangsverdi og nåværende arbeidsverdi Jeg tror det er hvordan eksponentiell glidende gjennomsnitt virker. En optimalisering jeg har sett for denne typen bevegelige gjennomsnitt, innebærer å bruke en forsterker med fast lengde-kø, en peker til hvor du befinner deg i den køen, og bare pakker pekeren rundt (med eller en hvis). Voila Ingen dyr pushpop. Kraft til amatørene, bror ndash Henry Cooke Sep 22 10 på 0:54 Henry: For et glatt gjennomsiktig gjennomsnitt trenger du bare bufferen, slik at du vet hvilken verdi som dukker opp når den neste verdien blir presset. Når det er sagt, den kvoterte lengden køforsterkeren en pointerquot du beskriver, er akkurat hva jeg mente ved kvitteringskøen. Det var derfor jeg sa at det ikke er ineffektivt. Hva syntes du jeg mente Og hvis svaret ditt er kvotearray som skifter sine verdier tilbake på hver indeksert fjerningsquot (som std :: vektor i C). Nå, da har jeg det så vondt jeg vil ikke engang snakke med deg lenger) ndash Dan Tao 22. september 10 kl 1:58 Henry: Jeg vet ikke om AS3, men en Java-programmerer har samlinger som CircularQueue på hisher disposisjon (I39m ikke en Java-utvikler så jeg er sikker på at det finnes bedre eksempler der ute, det er bare det jeg fant fra et raskt Google-søk), som utfører nøyaktig funksjonaliteten vi snakker om. Jeg er ganske sikker på at flertallet av mellomstore og lavt nivå språk med standardbiblioteker har noe lignende (f. eks. I QueueltTgt). Uansett, jeg var selvsagt filosofi. alt er tilgitt. ndash Dan Tao 22 september 10 kl 12:44 Et eksponentielt forfallende glidende gjennomsnitt kan beregnes for hånd med bare trenden hvis du bruker de riktige verdiene. Se fourmilab. chhackdiete4 for en ide om hvordan du gjør dette raskt med en penn og papir hvis du er ute etter eksponentielt glatt glidende gjennomsnitt med 10 utjevning. Men siden du har en datamaskin, vil du sannsynligvis gjøre binær skifting i motsetning til desimalforskyvning) På denne måten er alt du trenger en variabel for din nåværende verdi og en for gjennomsnittet. Det neste gjennomsnittet kan da beregnes ut fra det. besvart 21 sep 10 kl 14:39 theres en teknikk kalt en rekkevidde gate som fungerer bra med lav forekomst falske prøver. Forutsatt bruken av en av filterteknikkene nevnt ovenfor (glidende gjennomsnitt, eksponentiell), når du har tilstrekkelig historie (en tids konstant), kan du teste den nye innkommende datasammen med rimelighet før den legges til i beregningen. Det kreves viss kunnskap om den maksimale fornuftige endring av signalet. Råprøven sammenlignes med den siste glattede verdien, og hvis absoluttverdien av denne forskjellen er større enn det tillatte området, blir denne prøven kastet ut (eller erstattet med noen heuristiske, for eksempel en prediksjon basert på skrå differensial eller trenden prediksjonsverdi fra dobbel eksponensiell utjevning) besvart apr 30 16 ved 6: 56C algoritme for null-ventetid eksponentiell glidende gjennomsnitt Sist endret: 2012-08-13 Jeg har prøvd å implementere en lavfrekvens cutoff i c som i hovedsak tar en strøm av tall og jevner ut utgangen (filtrerer ut høyfrekvent bevegelsesjitter), men det er viktig at de forhåndsviktede tallene anses umiddelbart når dataene er tidskritiske (det er å styre en bevegelsessimulasjonsbase ved bruk av utgang fra litt av spillprogramvaren). Jeg har en arbeidsvektet glidende gjennomsnittlig algoitme, men kan gjøre med noe litt mer responsivt på forsiden, og jeg fant dette: - Pseudokoden er som følger: Inputs: Price (NumericSeries), Period (NumericSimple) Variabler: faktor (0), lag (0) hvis CurrentBar lt 1 deretter begynner ZLEMA Prisfaktor 2 (Period1) lag (Period 1) 2 End else start ZLEMA faktor (2Price-Pricelag) (1-faktor) ZLEMA1 ende Ive oversatt den til C og koden min er som følger: Men det virker ikke å oppføre seg ganske som jeg forventer. Det ser ut til å være nesten der, men noen ganger får jeg en litt lavere verdi enn alle elementene i køen (når de er alle høyere). Min kø og antall elementer i den er bestått som parametere, med den siste som er foran på alle tider, passerer jeg også en inkrementerende teller som starter ved 0 som kreves av funksjonen. Jeg er ikke sikker på at jeg har tolket betydningen av ZLEMA1 riktig, da den ikke er tydelig i sin pseudokode, så jeg antok at dette er de siste samtalene Zlema, og jeg antar at Pris faktisk betyr Pris0. Kanskje jeg har det galt Skal jeg kopiere den faktiske Zlema-kalkulerte verdiene tilbake til min opprinnelige kø før neste anrop, endrer jeg ikke den opprinnelige køen i det hele tatt enn bare skifter alle verdier en til enden og legger inn det siste i begynnelsen . Koden jeg bruker til å gjøre dette er: Ville være ekstremt takknemlig hvis noen med en bedre forståelse av matematikken kunne behage forstanden, sjekk dette for meg for å se om jeg har noe litt galt, takk så mye på forhånd hvis du kan hjelpe Først takk alt for Din innspill, mye verdsatt Det er fornuftig jeg antar, så jeg antar at det beste jeg kan håpe på, er bare et eksponentielt glidende gjennomsnitt, og aksepterer det vil være et lite lag, men dette vil bli minimert av tyngre frontvekt enn gitt i typisk vektet glidende gjennomsnitt Jeg har denne algoritmen også, men et lignende problem ved at verdiene ikke virker ganske riktige (med mindre dette er formens natur). For eksempel, si at mitt utvalg inneholder 16 verdier, alle 0.4775 - utgangen er 0.4983, men Id forventer at den skal være 0.4775 Ser dette ut til deg. Eksponentiell flytende gjennomsnitt. float ema (float vals, int numVals, int currentSample) statisk float faktor 0 statisk float lastema 0 float ema hvis (currentSample lt 1) ema vals0 faktor 2.0 ((float) numVals) 1.0) andre ema (faktor vals0) - faktor) lastema) lastema ema return ema Omvendt er produksjonen lavere enn hver av inngangene, selv om alle er høyere. Den kalles på samme måte som zlema (.) Ovenfor, med en økende teller. Formelen og pseudokoden for denne er her: - autotradingstrategy. wordpress20091130exponential-moving-average Takk igjen, unnskyld for min misforståelse av noen av grunnleggende: (Med vennlig hilsen, Chris J Som for koden jeg postet, har du rett om array størrelse Situasjonen. Det bør være lett å fikse. Som for dine spørsmål: 1) Filterkonstanten representerer en frekvens cutoff. Jeg brukte en digital signalbehandling (DSP) for denne teknikken. en. wikipedia. orgwi kiLow-pas sfilter er en enkel forklaring. Du vil ha avdelingen for diskret tid. I mitt tilfelle er A RC-Konstanten de snakker om. Så frekvensen som den kutter ut er over 1 (2piA). Hvis du ikke har en forståelse av Frequency-Domain teori, kan dette bli komplisert. I ditt tilfelle, jo høyere du lager A, desto lavere frekvens vil dette filteret tillate, noe som betyr at det vil jevne kurven ut mer og mer. Jo lavere du gjør det, jo mer støy som er tillatt i systemet. Husk at en må være større enn eller lik 1 for å være effektiv. Jeg reattached XLS igjen, denne gangen uten endring av rand () tallene. Juster A-konstanten og se hvordan den quotsmoothsquot (eller filter) ut høyfrekvensvariasjonene. 2) Det siste punktet i inngangsarrangementet har den nyeste verdien. 3) Det samme gjelder for utmatningsarrayen. Den siste er den nyeste verdien. 5) NUMVALS er vilkårlig. Du kan kontinuerlig legge til på input og output array så mange ganger du liker, og det ville ikke påvirke filteret. Spesielt brukte jeg 49 poeng. Men jeg kan enkelt slette de siste 20 og de første 29 utgangene vil forbli de samme. Funksjonen er ikke basert på hvor mange poeng blir brukt. Jeg vil nevne at jeg utviklet denne funksjonen for en engangskonvertering. Hvis du ønsket å gjøre en konvertering for den neste verdien på flyet, kan du prøve noe enklere (som vedlagt). Igjen er jeg rusten på c. Jeg håper dette er riktig. Det eneste du trenger å levere er inngang og filter konstant. Gi meg beskjed hvis dette hjelper. Er det mulig å implementere et bevegelige gjennomsnitt i C uten at det er behov for et vindu med prøver, har jeg funnet at jeg kan optimalisere litt ved å velge en vindustørrelse som er en kraft på to for å tillate bitskifting i stedet for å dele, men ikke trenger en buffer ville være fint. Er det en måte å uttrykke et nytt glidende gjennomsnittsresultat bare som en funksjon av det gamle resultatet og den nye prøven. Definer et eksempel glidende gjennomsnitt, over et vindu på 4 prøver å være: Legg til ny prøve e: Et glidende gjennomsnitt kan implementeres rekursivt , men for en nøyaktig beregning av det bevegelige gjennomsnittet må du huske den eldste innsatsprøven i summen (dvs. a i eksempelet ditt). For et lengde N bevegelige gjennomsnitt beregner du: hvor yn er utgangssignalet og xn er inngangssignalet. Eq. (1) kan skrives rekursivt som Så du må alltid huske prøven xn-N for å beregne (2). Som påpekt av Conrad Turner, kan du bruke et (uendelig langt) eksponensielt vindu i stedet, som gjør det mulig å beregne utgangen bare fra tidligere utgang og gjeldende inngang: men dette er ikke et standard (uvevet) glidende gjennomsnitt, men eksponentielt vektet glidende gjennomsnitt, hvor prøver tidligere i det siste får en mindre vekt, men (i det minste i teorien) glemmer du aldri noe (vektene blir bare mindre og mindre for prøver langt i det siste). Jeg implementerte et glidende gjennomsnitt uten individuelt elementminne for et GPS-sporingsprogram jeg skrev. Jeg starter med 1 prøve og deler med 1 for å få dagens avg. Jeg legger til en prøve og deler med 2 til den nåværende avg. Dette fortsetter til jeg kommer til lengden av gjennomsnittet. Hver gang etterpå legger jeg til den nye prøven, får gjennomsnittet og fjerner det gjennomsnittet fra totalen. Jeg er ikke en matematiker, men dette virket som en god måte å gjøre det på. Jeg skjønte at det ville slå magen til en ekte matte fyr, men det viser seg at det er en av de aksepterte måtene å gjøre det på. Og det fungerer bra. Bare husk at jo høyere lengden jo tregere følger det du vil følge. Det kan ikke være noe som helst mesteparten av tiden, men når du følger satellitter, hvis du er treg, kan stien være langt fra den faktiske posisjonen, og det vil se dårlig ut. Du kan ha et mellomrom mellom lørdager og de etterfølgende prikkene. Jeg valgte en lengde på 15 oppdatert 6 ganger i minuttet for å få tilstrekkelig utjevning og ikke komme for langt fra den faktiske lette stillingen med glattestrekpunktene. besvart 16 nov 16 kl 23:03 initialiser totalt 0, count0 (hver gang vi ser en ny verdi) En innskriving (scanf), en legger til totalnewValue, ett inkrement (telle), en del av gjennomsnitt (totalt antall) Dette ville være et bevegelige gjennomsnitt over alle innganger For å beregne gjennomsnittet over bare de siste 4 inngangene, ville det kreve 4 inngangsvariabler, kanskje kopiering av hvert inngang til en eldre inputvariable og deretter beregning av det nye glidende gjennomsnittet. Som summen av de 4 inngangsvariablene delt på 4 (høyre skift 2 ville være bra hvis alle inngangene var positive for å gjøre gjennomsnittlig beregning besvart 3. februar klokken 4:06 som faktisk vil beregne gjennomsnittet og IKKE det bevegelige gjennomsnittet. Etter hvert som tellingen blir større, blir virkningen av en ny inngangsprøve forsvunnet liten ndash Hilmar Feb 3 15 kl 13:53 Ditt svar 2017 Stack Exchange, Inc
No comments:
Post a Comment