Veid Bevegelig Gjennomsnitt C


Jeg prøver å beregne det bevegelige gjennomsnittet av et signal. Signalverdien en dobbel blir oppdatert i tilfeldige tider. Jeg leter etter en effektiv måte å beregne det s tidsvektet gjennomsnitt på over et tidsvindu, i sanntid kunne jeg gjøre det selv, men det er mer utfordrende enn jeg trodde. De fleste av ressursene jeg har funnet over Internett, beregner glidende gjennomsnitt av periodisk signal, men mine oppdateringer tilfeldigvis. Noen vet gode ressurser for det. Tricket er følgende Du får oppdateringer ved tilfeldige tider via tomt oppdatering int tid, flyteverdi Du må imidlertid også spore når en oppdatering faller av tidsvinduet, slik at du stiller en alarm som kalles på tidspunktet N som fjerner den forrige oppdateringen, fra å bli vurdert igjen i beregningen . Hvis dette skjer i sanntid, kan du be om operativsystemet for å ringe til en metode for å unngå å ringe opp i tid. Hvis dette er en simulering, kan du ikke få hjelp fra operativsystemet, og du må d o det manuelt I en simulering vil du kalle metoder med tiden som følger med som et argument som ikke korrelerer med sanntid. Det er imidlertid en rimelig antagelse at samtalene er garantert slik at tidsargumentene øker. I dette tilfellet må du opprettholde en sortert liste over alarmtidverdier, og for hver oppdatering og leseanrop, kontroller du om tidsargumentet er større enn hodet til alarmlisten. Mens det er større, slipper du den alarmerende oppdateringen av alarmen, fjerner hodet og sjekk igjen til alle alarmer før den angitte tiden er behandlet. Gjør så oppdateringen. Jeg har så langt antatt at det er åpenbart hva du ville gjøre for den faktiske beregningen, men jeg vil utarbeide bare hvis jeg antar at du har en metode flyt les int tid som du bruker til å lese verdiene Målet er å gjøre denne anrop så effektiv som mulig Så du beregner ikke det bevegelige gjennomsnittet hver gang lesemetoden heter. I stedet forkalkulerer du verdien som for den siste oppdateringen spiste eller den siste alarmen og justere denne verdien ved hjelp av et par flytende punktoperasjoner for å ta hensyn til tidens gang siden siste oppdatering, dvs. et konstant antall operasjoner, bortsett fra kanskje å behandle en liste over stablet alarm. Helt klart er dette klart - Dette bør være en ganske enkel algoritme og ganske effektiv. Ytterligere optimalisering Et av de gjenværende problemene er hvis et stort antall oppdateringer skjer i tidsvinduet, så er det en lang tid som det ikke er lest eller oppdateringer, og deretter en lesning eller oppdatering kommer sammen I dette tilfellet vil ovennevnte algoritme være ineffektiv i trinnvis oppdatering av verdien for hver oppdatering som faller av Dette er ikke nødvendig fordi vi bare bryr oss om den siste oppdateringen utover tidsvinduet, så hvis det er en vei For å effektivt slippe av alle eldre oppdateringer, ville det hjelpe. For å gjøre dette kan vi endre algoritmen for å gjøre et binært søk på oppdateringer for å finne den siste oppdateringen før tidsvinduet Hvis det er relativt få oppdateringer som må slettes, kan man trinnvis oppdatere verdien for hver oppdatert oppdatering. Men hvis det er mange oppdateringer som må slettes, kan man rekomputere verdien fra bunnen av etter å ha slått av de gamle oppdateringene. Vedlegg om inkrementell beregning Jeg bør avklare hva jeg mener ved inkrementell beregning over i setningen, justere denne verdien ved hjelp av et par flytende punktoperasjoner for å regne for tidsovergang siden den siste oppdateringen. Initial ikke-inkrementell beregning. Det er enere over relevante oppdateringer i rekkefølge av økende time. movingaverage sum lastupdate timeincelastupdate windowlength. Now hvis akkurat en oppdatering faller av vinduet, men ingen nye oppdateringer ankommer, juster summen som. Legg merke til at det er forhåndsoppdatert som har sin tidsstempel endret til begynnelsen av det siste vinduet begynnelsen. Og hvis akkurat en oppdatering kommer inn i vinduet, men ingen nye oppdateringer faller av, juster summen som. Som det skal være klart, er dette en grov skisse, men forhåpentligvis viser det hvordan du kan opprettholde gjennomsnittet slik at det er O 1 operasjoner per oppdatering på amortisert basis. Men vær oppmerksom på ytterligere optimalisering i forrige avsnitt. Legg også merke til stabilitetsproblemer referert til i et eldre svar, noe som betyr at flytpunktsfeil kan akkumulere over et stort antall inkrementelle operasjoner slik at det er en avvik fra resultatet av den fullstendige beregningen som er vesentlig for applikasjonen. Hvis en tilnærming er OK, og det er en minimal tid mellom prøver, kan du prøve superprøving. Har en matrise som representerer jevnt fordelte tidsintervaller som er kortere enn minimumet, og i hver tidsperiode lagrer du den siste prøven som ble mottatt. Jo kortere intervallet, jo nærmere gjennomsnittet vil være den sanne verdien e Perioden bør ikke være større enn halvparten av minimumet eller det er en sjanse til å mangle en prøve. ansvaret 15. desember kl. 18 12. Svaret 15. desember kl. 22 38. Takk for svaret En forbedring som ville være nødvendig for å faktisk cache verdien av det totale gjennomsnittet slik at vi ikke løper hele tiden. Det kan også være et mindre punkt, men det ville ikke være mer effektivt å bruke en dekk eller en liste for å lagre verdien, siden vi antar at oppdateringen kommer i riktig rekkefølge Innsetting ville være raskere enn på kartet Arthur 16.12.11 på 8 55.Ja, du kan cache verdien av summen. Trekk verdiene til prøvene du sletter, legg til verdiene av prøvene du legger inn. Også, ja, Et deque par Eksempel, Dato kan være mer effektivt Jeg valgte kartet for lesbarhet, og det er enkelt å påkalle kart overkanten. Som alltid, skriv riktig kode først, så profil og måle trinnvise endringer. Rob Des 16 11 på 15 00. Merknad er dette ikke Måten å nærme seg dette Leaving det her for referanse om hva som er galt med denne ap proach Sjekk kommentarene. OPPDATERT - basert på Oli s kommentar ikke sikker på ustabiliteten han snakker om though. Use et sortert kart over ankomsttider mot verdier Ved ankomst av en verdi legg til ankomsttid til det sorterte kartet sammen med det s verdi og oppdatere glidende gjennomsnitt. advarsel dette er pseudo-kode. Det er ikke fullt fleshed ut, men du får ideen. Ting å merke Som jeg sa ovenfor er pseudokode Du må velge et passende kart Ikke ta parene som du itererer gjennom som du vil ugyldiggjøre iteratoren og må starte igjen Se Oli s kommentar nedenfor also. answered Dec 15 11 på 12 22.This doesn t work det tar ikke hensyn til hvilken andel av vinduslengden hver verdi eksisterer for også denne tilnærmingen til å legge til og deretter subtrahere er bare stabil for heltall typer, ikke flyter oliver Charlesworth desember 15 11 på 12 29. oliCharlesworth - beklager jeg savnet noen viktige punkter i beskrivelsen dobbelt og tidsvektet jeg vil oppdatere takk dennis desember 15 11 kl 12 33. Tidsvektingen er enda et problem Men det er ikke det jeg snakker om, jeg refererte til det faktum at når en ny verdi først kommer inn i tidsvinduet, er bidraget til gjennomsnittsverdien minimal. Dens bidrag fortsetter å øke til en Ny verdi går inn i Oliver Charlesworth Dec 15 11 på 12 35. Jeg vet at dette kan oppnås med boost som per. Men jeg virkelig vil unngå å bruke boost jeg har googled og ikke funnet noen egnede eller lesbare eksempler. Basalt vil jeg spore flyttingen gjennomsnitt av en pågående strøm av en strøm av flytende punktnumre ved å bruke de siste 1000 tallene som en dataprøve. Hva er den enkleste måten å oppnå dette på. Jeg eksperimenterte med å bruke et sirkulært array, eksponentielt glidende gjennomsnitt og et enklere glidende gjennomsnitt og fant ut at resultatene fra den sirkulære gruppen passet mine behov best. asked 12. juni 12 på 4 38. Hvis dine behov er enkle, kan du bare prøve å bruke et eksponentielt glidende gjennomsnitt. Du gjør bare en akkumulatorvariabel, og som din torsk e ser på hver prøve, koden oppdaterer akkumulatoren med den nye verdien du velger en konstant alfa som er mellom 0 og 1, og beregner dette. du trenger bare å finne en verdi av alfa hvor effekten av en gitt prøve bare varer for omtrent 1000 prøver. Hmm, jeg er egentlig ikke sikker på at dette passer for deg, nå som jeg har satt det her Problemet er at 1000 er et ganske langt vindu for et eksponentielt glidende gjennomsnitt. Jeg er ikke sikker på at det er en alfa som vil spre seg gjennomsnittet i løpet av de siste 1000 tallene, uten understrøm i flytpunktsberegningen Men hvis du ønsket et mindre gjennomsnitt, som 30 tall eller så, er dette en veldig enkel og rask måte å gjøre det. Ansatt 12. juni 12 på 4 44. 1 på ditt innlegg Det eksponentielle glidende gjennomsnittet kan tillate at alfaen er variabel Så dette gjør at det kan brukes til å beregne tidsbasen, for eksempel byte per sekund. Hvis tiden siden den siste akkumulatoroppdateringen er mer enn 1 sekund, lar du alfa være 1 0 Ellers , du kan la alfa være usecs siden siste oppdatering 1000000 jxh Jun 12 12 på 6 21. Basisk jeg vil spore det bevegelige gjennomsnittet av en pågående strøm av en strøm av flytende punktnumre ved hjelp av de siste 1000 tallene som en dataprøve. Merk at under oppdateringer summen som elementene som lagt til erstattet, unngå kostbar ON-traversal for å beregne summen som trengs for gjennomsnittet - på forespørsel. Totalt er det laget en annen parameter fra T for å støtte, for eksempel ved å bruke en lang lang når det er totalt 1000 lange s, en int for char s eller en dobbel til total flyt s. Dette er litt feil i at numsamples kan gå forbi INTMAX - hvis du bryr deg om at du kan bruke en usignert lang lang eller bruke et ekstra bool-datamedlem til å registrere når beholderen først fylles mens sykkel nummeprøver rundt arrayet best er omdøpt til noe uskyldig som pos. answered 12 juni 12 på 5 19.one antar at tomrom operatør T-prøven er faktisk tom operatør T-prøve oPless 8. juni 14 på 11 52. oPless ahhh godt oppdaget egentlig mente jeg at den skulle være ugyldig operatør T-prøve, men av selvfølgelig kan du bruke whate ver notation du likte vil fikse, takk Tony D 8 juni 14 14 14. Det er mulig å implementere et bevegelige gjennomsnitt i C uten behov for et vindu med prøver. Jeg har funnet ut at jeg kan optimalisere litt ved å velge et vindu størrelse som er kraften til 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. Eksempel på glidende gjennomsnitt, over et vindu på 4 prøver å være. Legg til nytt prøve eA 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 en lengde N beveger gjennomsnittet du beregner. Hvor yn er utgangssignalet og xn er inngangssignalet Eq 1 kan skrives rekursivt som. Så du må alltid huske prøven x nN for å beregne 2.As påpekt av Conrad Turner, du kan bruke et uendelig langt eksponensielt vindu inste annonse, som gjør det mulig å beregne utgangen bare fra tidligere utgang og nåværende input. but dette er ikke et standard uvevet glidende gjennomsnitt, men et eksponentielt vektet glidende gjennomsnitt, hvor prøvene videre i det siste får en mindre vekt, men minst i teori du aldri glemmer noe vekter blir bare mindre og mindre for prøver langt i fortiden. 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. Og det fungerer bra Bare husk at øke lengden jo tregere det følger med hva du vil følge Det kan ikke hende det meste 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. Du kan ha et mellomrom mellom lørdags og trailing prikker 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 glatt strek dots. answered 16. november 16 kl 23 03.initialiser totalt 0, teller 0 hver gang du ser en ny verdi. Til en inntastingsskanner legger man til en total nyValue, en inkrementtelling, en divisjon gjennomsnittlig total telling. Dette ville være et bevegelige gjennomsnitt over alle innspillene. For å beregne gjennomsnittet over bare de siste 4 inngangene, ville det kreve 4 inputvariables, kanskje kopiere hver inngang til en eldre inputvariabel, og deretter beregne det nye glidende gjennomsnittet som summen av de 4 inputvariablene, delt med 4 høyre skift 2, ville være bra hvis alle inngangene var positive for å gjøre gjennomsnittlig beregning. ansvaret 3. februar kl. Det vil faktisk ca beregne det totale gjennomsnittet og IKKE det bevegelige gjennomsnittet Når tellingen blir større, blir virkningen av en ny inngangsprøve forsinket liten Hilmar 3. februar kl. 13 53. Ditt svar.2017 Stack Exchange, Inc.

Comments

Popular Posts