Sunday 3 December 2017

Przenoszenie średnie źródło c


Czy możliwe jest zaimplementowanie średniej ruchomej w C bez potrzeby okna z próbkami, które mogę zoptymalizować nieco, wybierając rozmiar okna, który ma potęgę dwóch, aby umożliwić przesunięcie bitowe zamiast dzielenia, ale niewymagające bufor byłby miły. Czy istnieje sposób wyrażenia nowego wyniku średniej kroczącej tylko jako funkcję starego wyniku i nowej próbki Zdefiniuj przykładową średnią ruchomą w oknie 4 próbek: Dodaj nową próbkę e: Średnia ruchoma może zostać zaimplementowana rekurencyjnie , ale do dokładnego obliczenia średniej ruchomej trzeba zapamiętać najstarszą próbkę wejściową w sumie (tj. a w twoim przykładzie). Dla długości N średniej ruchomej obliczamy: gdzie yn jest sygnałem wyjściowym, a xn jest sygnałem wejściowym. Eq. (1) może być napisany rekurencyjnie jako Więc zawsze musisz zapamiętać próbkę xn-N w celu obliczenia (2). Jak wskazał Conrad Turner, można zamiast tego użyć (nieskończenie długiego) okna wykładniczego, które pozwala obliczyć wyjście tylko z poprzedniego wyjścia i bieżącego wejścia: ale nie jest to standardowa (nieważona) średnia ruchoma, ale wykładniczo ważona średnia ruchoma, gdzie próbki w przeszłości mają mniejszą masę, ale (przynajmniej teoretycznie) nigdy niczego nie zapominasz (ciężary stają się mniejsze i mniejsze dla próbek daleko w przeszłości). Zaimplementowałem średnią ruchomą bez pamięci pojedynczych elementów dla programu do śledzenia GPS, który napisałem. Zaczynam od 1 próbki i dzielę przez 1, aby uzyskać aktualną średnią. Następnie dodaję próbkę anothe i dzielę przez 2 do aktualnej avg. To trwa, dopóki nie osiągnę długości średniej. Za każdym razem dodawam nową próbkę, otrzymuję średnią i usuwam tę średnią z całości. Nie jestem matematykiem, ale wydawało mi się, że to dobry sposób. Pomyślałem, że to zmieni żołądek prawdziwego matematyka, ale okazuje się, że jest to jeden z akceptowanych sposobów robienia tego. I działa dobrze. Pamiętaj tylko, że im większa długość, tym wolniej podążasz za tym, co chcesz obserwować. To może nie mieć większego znaczenia, ale gdy podążamy za satelitami, jeśli jesteś wolny, trasa może być daleko od aktualnej pozycji i będzie wyglądać źle. Możesz mieć przerwę między sob i końcowymi kropkami. Wybrałem długość 15 aktualizacji 6 razy na minutę, aby uzyskać odpowiednie wygładzenie i nie za bardzo oddalić się od faktycznej pozycji siedzącej z wygładzonymi kropkami. odpowiedziała 16 listopada 16 o 23:03 zainicjalizuj całość 0, count0 (za każdym razem, gdy zobaczysz nową wartość Następnie jedno wejście (scanf), jedno dodaj totalnewValue, jeden przyrost (count), jedna średnia dzieląca (totalcount) Byłaby to średnia ruchoma ponad wszystkie wejścia Aby obliczyć średnią tylko z ostatnich 4 wejść, wymagałyby 4 zmiennych wejściowych, być może skopiowania każdego wejścia do starszej zmiennej wejściowej, a następnie obliczenia nowej średniej ruchomej jako sumy 4 zmiennych wejściowych, podzielonej przez 4 (prawe przesunięcie 2 byłoby dobrze, jeśli wszystkie dane wejściowe były dodatnie, aby uzyskać średnią obliczoną odpowiedź 3 lutego 15 o 4:06 To faktycznie obliczyć całkowitą średnią, a NIE średnią ruchomą. Jak liczba staje się większa wpływ nowej próbki wejściowej staje się znikały małe ndash Hilmar lutego 3 15 at 13:53 Twoja wymiana stosów w 2017 r. Inc. Wiem, że jest to możliwe dzięki zwiększeniu liczby na: Ale naprawdę chciałbym uniknąć stosowania boost. Mam google i nie znalazłem żadnych odpowiednich lub czytelnych przykładów. Zasadniczo chcę śledzić w ruchu średnia z ciągłego strumienia strumienia liczb zmiennoprzecinkowych z wykorzystaniem najnowszych 1000 liczb jako próbki danych. Jaki jest najłatwiejszy sposób, aby to osiągnąć? Eksperymentowałem z użyciem okrągłej tablicy, wykładniczej średniej kroczącej i prostszej średniej ruchomej, i odkryłem, że wyniki z okrągłej macie najlepiej pasują do moich potrzeb. Zapytany 12 czerwca 12 o 4:38 Jeśli twoje potrzeby są proste, możesz po prostu spróbować użyć wykładniczej średniej kroczącej. Mówiąc prościej, tworzysz zmienną akumulatora, a ponieważ twój kod wygląda na każdą próbkę, kod aktualizuje akumulator o nową wartość. Wybierasz stałą alfa, która jest pomiędzy 0 a 1, i obliczasz to: Musisz tylko znaleźć wartość alfa, gdzie efekt danej próbki trwa tylko około 1000 próbek. Hmm, nie jestem właściwie pewien, czy ci to pasuje, teraz, kiedy go tu umieściłem. Problem polega na tym, że 1000 to dość długie okno dla wykładniczej średniej kroczącej Nie jestem pewien, czy istnieje alfa, które rozłożyłoby średnią z ostatnich 1000 liczb, bez dolnego limitu w obliczeniach zmiennoprzecinkowych. Ale jeśli chcesz mieć mniejszą średnią, na przykład około 30 numerów, jest to bardzo łatwy i szybki sposób na zrobienie tego. odpowiedź 12 czerwca 12 o 4:44 1 na twój post. Wykładnicza średnia ruchoma może pozwolić na zmienną alfa. Dzięki temu można go wykorzystać do obliczenia średniej podstawy czasu (na przykład bajtów na sekundę). Jeśli czas od ostatniej aktualizacji akumulatora jest dłuższy niż 1 sekunda, zezwalasz alfa na 1.0. W przeciwnym razie możesz pozwolić na alfa (usecs od ostatniej aktualizacji1000000). ndash jxh 12 czerwca 12 o 6:21 Zasadniczo chcę śledzić średnią ruchomą ciągłego strumienia strumienia liczb zmiennoprzecinkowych z wykorzystaniem najnowszych 1000 liczb jako próbki danych. Zauważ, że poniższe aktualizacje aktualizują sumę jako elementy dodane z powrotem, unikając kosztownego przejścia przez O (N) w celu obliczenia sumy - potrzebnej dla średniej - na żądanie. Total otrzymuje inny parametr od T do obsługi np. użycie długiej długości, gdy suma wynosi 1000 długich s, int dla char s lub double do total float s. Jest to trochę wadliwe, ponieważ liczba poprawek może przekroczyć INTMAX - jeśli chcesz, możesz użyć długiej długości bez znaku. lub użyj dodatkowego elementu danych typu bool, aby zarejestrować, kiedy pojemnik jest pierwszy wypełniony, podczas gdy liczba próbkowania w cyklu wokół tablicy (najlepiej wtedy przemianowana na coś nieszkodliwego jak pos). odpowiedź 12 czerwca 12 o 5:19 zakłada się, że quotvoid operator (T sample) quot jest w rzeczywistości quotvoid operatorltlt (T sample) quot. ndash oPless cze 8 14 o 11:52 o Bez ahhh. dobrze zauważył. faktycznie miałem na celu unieważnienie operatora () (próbka T), ale oczywiście można użyć dowolnej notacji, którą lubisz. Naprawię, dzięki. ndash Tony D cze 8 14 przy algorytmie 14: 27C dla globalnej ruchomej średniej z zerowym latencją Ostatnia modyfikacja: 2017-08-13 Próbowałem wprowadzić niską wartość odcięcia w c, która w istocie przyjmuje strumień liczb i wygładza wyjście ( odfiltrowanie mechanizmu ruchu wysokiej częstotliwości), jednak ważne jest, aby przednie ważone liczby były rozpatrywane natychmiast, ponieważ dane są krytyczne w czasie (ma to na celu kontrolowanie bazy symulacji ruchu za pomocą danych wyjściowych z oprogramowania gry). Mam algoithm z ruchomą średnią ważoną, ale może zrobić coś bardziej responsywnego na początku, i znalazłem to: - Pseudo-kod jest następujący: Wejścia: Cena (NumericSeries), Okres (NumericSimple) Zmienne: współczynnik (0), opóźnienie (0), jeśli CurrentBar lt 1 następnie rozpocznie ZLEMA 2 opóźnienie (okres 1) opóźnienie (okres-1) 2 koniec jeszcze rozpocznie czynnik ZLEMA (2Price-Pricelag) (1-czynnik) ZLEMA1 koniec Ive przetłumaczył go na do C i mój kod wygląda następująco: nie wydaje się jednak zachowywać tak, jak oczekuję. Wydaje się, że jest prawie na miejscu, ale czasami otrzymuję nieco niższą wartość niż wszystkie elementy w kolejce (gdy wszystkie są wyższe). Moja kolejka i liczba pozycji w nim jest przekazywana jako parametry, a ostatnia z nich jest zawsze od przodu, a także przekazuję licznik inkrementujący, rozpoczynający się od 0, zgodnie z wymaganiami tej funkcji. Nie jestem pewien, czy Ive interpretował znaczenie ZLEMA1 poprawnie, ponieważ nie jest jasne w jego pseudokod, więc założyłem, że to jest ostatni zlema połączeń, a także Im zakładając Price faktycznie oznacza Price0. Być może mam to źle Czy mam kopiować rzeczywiste wartości obliczone zlema z powrotem do mojej oryginalnej kolejki przed następnym wywołaniem Nie zmieniam oryginalnej kolejki na wszystko inne niż tylko przesunięcie wszystkich wartości jeden na koniec i wstawienie najnowszego na początku . Kod, którego używam, aby to zrobić jest: Byłbym niezmiernie wdzięczny, gdyby ktoś z lepszym zrozumieniem matematyki mógł zadowalać zdrowie psychiczne sprawdzić to dla mnie, aby zobaczyć, czy coś złego się nie stało Dziękuję z góry, jeśli możesz pomóc Najpierw dziękuję wszystkim za Twój wkład, bardzo doceniany To ma sens, tak myślę, więc przypuszczam, że wtedy najlepsze, na co mogę liczyć, to po prostu wykładnicza średnia ruchoma, przyjmując, że będzie niewielkie opóźnienie, ale to będzie zminimalizowane przez cięższe przednie ważenie niż podane w typowym ważonym średnia ruchoma Mam również ten algorytm, ale podobny problem polega na tym, że wartości nie wydają się całkiem poprawne (chyba, że ​​taka jest natura formuły). Na przykład, powiedzmy, że moja tablica zawiera 16 wartości, wszystkie 0.4775 - wynik wynosi 0.4983, ale oczekuję, że będzie to 0,4775 Czy to wygląda dobrze dla Ciebie. Wykładnicza średnia ruchoma. float ema (zmiennoprzecinkowe, int numVale, int currentSample) statyczny współczynnik float 0 statyczny float lastema 0 float ema jeśli (currentSample lt 1) ema vals0 factor 2.0 (((float) numVals) 1.0) else ema (factor vals0) ((1.0 - factor) lastema) lastema ema return ema Odwrotnie, czasami wynik jest niższy niż każde z wejść, nawet jeśli wszystkie są wyższe. Nazywa się to w taki sam sposób, jak zlema (.) Powyżej, z inkrementującym się licznikiem. Wzór i pseudokod dla tego są tutaj: - autotradingstrategy. wordpress20091130exponential-moving-average Jeszcze raz dziękuję, przepraszam za nieporozumienie niektórych z podstaw :( Z pozdrowieniami, Chris J. Co do kodu, który napisałem, masz rację co do rozmiaru tablicy W przypadku pytań: 1) Stała filtra reprezentuje ograniczenie częstotliwości. Użyłem cyfrowego przetwarzania sygnału (DSP) dla tej techniki. en. wikipedia. orgwi kiLow-pas sfilter jest prostym wyjaśnieniem. Chcesz sekcję Discrete-Time Realization. W moim przypadku A jest stałą RC, o której mówią. Częstotliwość, którą wycina, wynosi powyżej 1 (2piA). Jeśli nie rozumiesz teorii częstotliwości, to może się to skomplikować. W twoim przypadku Im wyższy A, tym niższa częstotliwość, na jaką pozwala ten filtr, co oznacza, że ​​wygładzi krzywą coraz więcej. Im niższy wynik, tym więcej hałasu jest dozwolone w systemie. Pamiętaj, że wartość A musi być większa lub równa 1, aby była skuteczna. Ponownie przyłączyłem XLS, tym razem bez numerów rand (). Wyreguluj stałą A i obserwuj, jak wygładza quoty lub filtruje wariacje o wysokiej częstotliwości. 2) Ostatni punkt tablicy wejściowej ma najnowszą wartość. 3) To samo dotyczy macierzy wyjściowej. Ostatnia jest ostatnią wartością. 5) NUMVALS jest arbitralny. Możesz ciągle dodawać do tablicy wejścia i wyjścia tyle razy, ile chcesz i nie wpłynie to na filtr. W szczególności wykorzystałem 49 punktów. Ale mogę łatwo usunąć ostatnie 20, a pierwsze 29 wyników pozostanie niezmienione. Funkcja nie opiera się na liczbie punktów. Chciałbym wspomnieć, że opracowałem tę funkcję do jednorazowej konwersji. Jeśli chcesz wykonać konwersję dla następnej wartości w locie, możesz spróbować czegoś prostszego (w załączeniu). Znowu jestem zardzewiały na c. Mam nadzieję, że to prawda. Jedyne, co musisz podać, to stała wejścia i filtra. Daj mi znać, jeśli to pomoże.

No comments:

Post a Comment