Monday 6 November 2017

Przenoszenie średnio filtr implementacja c


W statystykach prosta średnia ruchoma jest algorytmem obliczającym nieważoną średnią z ostatnich n próbek. Parametr n jest nazywany rozmiarem okna, ponieważ algorytm może być traktowany jako okno, które przesuwa się nad punktami danych. Przy użyciu formuły rekurencyjnej algorytmu liczba operacji wymaganych na próbkę jest zmniejszona do jednego dodatku, jednego odejmowania i jednego podziału. Ponieważ formulacja jest niezależna od wielkości okna n. złożoność wykonania jest O (1). tzn. stała. Rekurencyjna formuła nieważonej średniej ruchomej jest, gdzie średnią jest średnią kroczącą, a x reprezentuje punkt danych. Kiedy więc okno przesuwa się w prawo, jeden punkt danych, ogon, zrzuca się i jeden punkt danych, głowa, przenosi się do środka. Wdrożenie Wdrażanie prostej średniej ruchomej musi uwzględniać następujące inicjowanie algorytmów okno nie jest w pełni wypełnione wartościami, formuła rekurencyjna nie powiedzie się. Magazynowanie Wymagany jest dostęp do elementu końcowego, który w zależności od implementacji wymaga przechowywania n elementów. Moja implementacja wykorzystuje prezentowaną formułę, gdy okno jest całkowicie wypełnione wartościami i w inny sposób przechodzi do formuły, która aktualizuje średnią przez ponowne obliczenie sumy poprzednich elementów. Należy zauważyć, że może to prowadzić do niestabilności liczbowych z powodu arytmetyki zmiennoprzecinkowej. Jeśli chodzi o zużycie pamięci, implementacja wykorzystuje iteratory, aby śledzić elementy głowy i ogona. Prowadzi to do wdrożenia ze stałymi wymaganiami pamięci niezależnie od wielkości okna. Oto procedura aktualizacji, która przesuwa okno po prawej stronie. W większości kolekcji unieważnia ich enumeratory, gdy zmodyfikowana jest kolekcja bazowa. Wdrożenie opiera się jednak na właściwych wyliciach. Szczególnie w aplikacjach opartych na transmisjach strumieniowych biblioteka bazowa musi zostać zmodyfikowana, gdy pojawi się nowy element. Jednym ze sposobów radzenia sobie z tym jest utworzenie prostego okrągłego rozmiaru o stałym rozmiarze o rozmiarze n1, który nigdy nie unieważnia iteratorów i na przemian dodaj element i wywołuje Shift. Chciałbym móc dowiedzieć się, w jaki sposób faktycznie to wdrożyć, ponieważ funkcja testu jest bardzo myląca dla me8230 Czy muszę konwertować dane na tablicę, a następnie uruchomić SMA sma nową macierz SMA (20) w okresie 20 SMA Jak sobie radzić? Funkcja shift () Czy konieczne jest wdrożenie konstruktorów. (przepraszam za zamieszanie). Czy ty don8217t nie musisz konwertować danych na tablicę, dopóki Twoje dane będą implementować IEnumerable1, a typ wyliczony jest podwójny. Jeśli chodzi o prywatne wiadomości, musisz przekonwertować DataRow do czegoś, co jest wartościami podwójnymi. Twoje podejście działa. Przesuń, przesuwa okno o jedną pozycję w lewo. Dla zbioru danych mówiących 40 wartości i 20 okresu SMA masz 21 pozycji, w których mieści się okno (40 8211 20 1). Za każdym razem, gdy zadzwonisz do Shift (), okno zostanie przesunięte w lewo o jedną pozycję, a funkcja Average () zwraca SMA dla bieżącej pozycji okna. Oznacza to nieważoną średnią wszystkich wartości wewnątrz okna. Dodatkowo moja implementacja pozwala obliczyć SMA, nawet jeśli okno nie jest w pełni wypełnione na początku. Więc w istocie nadzieję, że to pomaga. Wszelkie dodatkowe pytania O PRAWO AUTORSKICH Christoph Heindl i cheind. wordpress, 2009-2017. Nieautoryzowane użycie i powielanie tego materiału bez wyraźnej pisemnej zgody autora tego autora i jego właściciela jest surowo zabronione. Mogą być wykorzystane fragmenty i linki, pod warunkiem pełnego i wyraźnego przyznania Christoph Heindl i cheind. wordpress z odpowiednim i konkretnym kierunkiem oryginalnej zawartości. Ostatnie wpisyCałość przemieszczania jako filtr Średnia średnia ruchoma jest często wykorzystywana do wygładzania danych w obecności hałasu. Zwykła średnia ruchoma nie zawsze jest rozpoznawana jako filtr Finite Impulse Response (FIR), chociaż jest to jeden z najpopularniejszych filtrów w przetwarzaniu sygnału. Traktowanie go jako filtra pozwala na porównanie go z, na przykład, filtrami windowed-sinc (zob. Artykuły dotyczące filtrów górnoprzepustowych i filtrów pasmowo-odbijających pasek na przykład). Główną różnicą tych filtrów jest to, że średnia ruchoma jest odpowiednia dla sygnałów, dla których przydatne informacje są zawarte w domenie czasowej. z których pomiary wygładzania są uśrednione. Z drugiej strony filtry Windowed-sinc są silnymi wykonawcami w dziedzinie częstotliwości. z wyrównaniem w przetwarzaniu dźwięku jako typowy przykład. Dokładniejsze porównanie obu typów filtrów w domenach czasowych a skuteczność filtrów w domenie częstotliwości. Jeśli masz dane, dla których ważne jest zarówno czas, jak i częstotliwość, możesz zajrzeć do Wariacje na temat Ruchowej Średniej. który przedstawia kilka ważonych wersji ruchomych średnich, które są lepsze w tym. Ruchome średnie długości (N) można zdefiniować tak, jak zazwyczaj jest to możliwe, przy czym aktualna próbka wyjściowa jest średnią z poprzednich (N) próbek. Widoczne jako filtr, średnia ruchoma powoduje splot sekwencji wejściowej (xn) z prostokątnym impulsem o długości (N) i wysokości (1N) (w celu uzyskania obszaru impulsu, a tym samym wzmocnienia filtra , jeden). W praktyce najlepiej jest podjąć (N) nieparzyste. Mimo, że średnia ruchoma może być obliczona przy użyciu parzystej liczby próbek, przy nieparzystej wartości dla (N) ma tę zaletę, że opóźnienie filtru będzie liczbą całkowitą próbek, ponieważ opóźnienie filtru (N) próbki są dokładnie ((N-1) 2). Średnia ruchoma może być wyrównana dokładnie do oryginalnych danych, przesuwając ją przez liczbę całkowitą próbek. Domena czasu Ponieważ średnia ruchoma jest splotem z prostokątnym impulsem, jej odpowiedź częstotliwościowa jest funkcją sinc. To sprawia, że ​​coś takiego jak podwójny filtr windowed-sinc, ponieważ jest to splot z impemem sinc, który powoduje prostokątną odpowiedź częstotliwościową. To pasuje do odpowiedzi częstotliwościowej, która powoduje, że średnia ruchoma jest słabą wartością w dziedzinie częstotliwości. Jednak w dziedzinie czasu działa bardzo dobrze. Dlatego doskonale nadaje się do wygładzania danych w celu usunięcia zakłóceń, przy jednoczesnym zachowaniu szybkiej reakcji krokowej (rysunek 1). Dla typowego, dodatniego białego szumu Gaussa (AWGN), który często zakłada się, próbki uśredniające (N) skutkują zwiększeniem współczynnika SNR o współczynnik (sqrt N). Ponieważ hałas poszczególnych próbek nie jest ze sobą związany, nie ma powodu, aby traktować każdą próbkę inaczej. W związku z tym średnia ruchoma, która daje każdą próbkę tej samej masie, pozbędzie się maksymalnej ilości hałasu dla danej ostrości odpowiedzi na etapie. Wdrożenie Ponieważ jest to filtr FIR, średnia ruchoma może być realizowana przez splot. Będzie wtedy miał taką samą wydajność (lub jej brak), jak każdy inny filtr FIR. Jednakże, może on być również realizowany rekursywnie, w bardzo skuteczny sposób. Wynika to bezpośrednio z definicji, że ta formuła jest wynikiem wyrażeń dla (yn) i (yn1), tj. Gdy zauważymy, że zmiana pomiędzy (yn1) i (yn) polega na tym, że dodatkowy termin (xn1N) pojawia się na koniec, a termin (xn-N1N) jest usuwany od początku. W praktycznych zastosowaniach często można pominąć podział przez (N) dla każdego terminu, kompensując uzyskane zysk (N) w innym miejscu. Ta rekursywna implementacja będzie znacznie szybsza niż konwertowanie. Każda nowa wartość (y) może być obliczona z tylko dwoma dodatkami, zamiast dodawania (N), które byłyby konieczne do prostej implementacji definicji. Jedną rzeczą, na którą trzeba zwrócić uwagę na rekursywną implementację, są błędy zaokrąglania. Może to być problem z aplikacją, ale sugeruje również, że ta implementacja rekurencyjna będzie działać lepiej w przypadku implementacji całkowitej niż w przypadku liczb zmiennoprzecinkowych. Jest to dość niezwykła, ponieważ implementacja zmiennoprzecinkowa jest zwykle prostsza. Koniec z tym wszystkim musi polegać na tym, że nigdy nie należy lekceważyć użyteczności prostej średniej ruchomości filtra w aplikacjach przetwarzania sygnału. Narzędzie do projektowania filtrów Ten artykuł jest uzupełniony o narzędzie do projektowania filtrów. Eksperymentuj z różnymi wartościami dla (N) i wizualizuj otrzymane filtry. Spróbuj to teraz Inni wspominają, należy rozważyć filtrowanie IIR (nieskończony impuls odpowiedzi), a nie filtr FIR (finite impulse response), którego używasz teraz. Jest więcej, ale na pierwszy rzut oka filtry FIR są implementowane jako wyraźne splify i filtry IIR z równaniami. Szczególny filtr IIR używam dużo w mikrokontrolerach jest jednym biegunowym filtrem dolnoprzepustowym. Jest to cyfrowy odpowiednik prostego filtra analogowego R-C. W większości zastosowań mają lepsze właściwości niż używany przez Ciebie filtr. Większość zastosowań filtru pudełkowego, który napotkam, jest wynikiem, że ktoś nie zwraca uwagi na klasę przetwarzania sygnału cyfrowego, a nie w wyniku potrzeby ich szczególnych cech. Jeśli chcesz złagodzić wysokie częstotliwości, które znasz są hałas, jeden biegun filtr dolnoprzepustowy jest lepszy. Najlepszym sposobem na implementację cyfrowo w mikrokontrolerze jest zwykle: FILT FILT FF (NEW - FILT) FILT to kawałek trwalszego stanu. To jedyna trwała zmienna, którą musisz obliczyć. NEW to nowa wartość, którą filtr jest aktualizowany za pomocą tej iteracji. FF jest frakcją filtrującą. co poprawia ciężar filtra. Spójrz na ten algorytm i zobacz, że dla FF 0 filtr jest nieskończenie ciężki, ponieważ wyjście nigdy się nie zmienia. Dla FF 1, jego naprawdę żaden filtr w ogóle, ponieważ wyjście po prostu następuje na wejściu. Przydatne wartości są pomiędzy nimi. W małych systemach wybierasz FF na 12 N, dzięki czemu mnożenie przez FF może być dokonane jako poprawna zmiana przez N bitów. Na przykład, FF może być 116 i pomnożyć przez FF, a więc prawo przesunięcia 4 bity. W przeciwnym razie filtr ten wymaga tylko jednego odejmowania, a jeden zostanie dodany, chociaż numery muszą być szersze niż wartość wejściowa (więcej o dokładności numerycznej w oddzielnej sekcji poniżej). Zazwyczaj biorę odczyty AD znacznie szybciej niż są potrzebne i zastosuj dwa z tych filtrów kaskadowych. Jest to cyfrowy odpowiednik dwóch filtrów R-C w szeregu i tłumi o 12 dBoctave powyżej częstotliwości rolloff. Jednak w przypadku odczytów AD zwykle bardziej trafne jest przejrzenie filtru w dziedzinie czasu przez rozważenie odpowiedzi krokowej. To informuje, jak szybko Twój system będzie widzieć zmianę, gdy coś, co mierzysz, zmienia się. Aby ułatwić projektowanie tych filtrów (co oznacza jedynie pobranie FF i określenie, ile z nich jest kaskadowych), używam mojego programu FILTBITS. Można określić liczbę bitów przesuwnych dla każdego FF w kaskadowej serii filtrów, a także obliczyć odpowiedź kroku i inne wartości. Właściwie to zwykle uruchamiam to za pomocą mojego skryptu PLOTFILT. Spowoduje to uruchomienie FILTBITS, który tworzy plik CSV, a następnie rzutuje na plik CSV. Na przykład jest to wynik PLOTFILT 4 4: Dwa parametry PLOTFILT oznaczają, że będą dwa filtry kaskadowe typu opisanego powyżej. Wartości 4 wskazują liczbę bitów przesunięcia, aby zrealizować mnożenie przez FF. W tym przypadku dwie wartości FF są więc 116. Czerwony ślad jest odpowiedzią na jednostkę kroku i jest najważniejszą sprawą. Na przykład oznacza to, że jeśli dane wejściowe ulegną zmianie, wyjście połączonego filtra osiądzie do 90 nowej wartości w 60 iteracjach. Jeśli zależy Ci na około 95 czasach rozliczania, musisz poczekać około 73 iteracji, a dla 50 czasu rozliczania wystarczy tylko 26 iteracji. Zielony ślad wskazuje wynik z pojedynczego impulsu o pełnej amplitudzie. Daje to pewien pomysł na przypadkowe tłumienie hałasu. Wygląda na to, że żadna pojedyncza próbka nie spowoduje więcej niż 2,5 zmiany w produkcie. Niebieskim śladem jest subiektywne odczucie tego, co ten filtr działa z białym hałasem. Nie jest to rygorystyczny test, ponieważ nie ma gwarancji, jaka była zawartość losowych liczb pobranych jako białe szumy w tej rundzie PLOTFILT. To tylko daje poczucie, jak bardzo będzie zgnieciona i jaka jest gładka. PLOTFILT, może FILTBITS i wiele innych użytecznych rzeczy, zwłaszcza w zakresie rozwoju oprogramowania PIC, jest dostępny w witrynie oprogramowania do pobierania oprogramowania na płycie PIC Development Tools. Dodano dokładność liczbową, którą widzę w komentarzach, a teraz nową odpowiedź, która interesuje się dyskusją na temat liczby bitów potrzebnych do wdrożenia tego filtra. Zauważ, że pomnożenie przez FF spowoduje utworzenie nowych bitów Log 2 (FF) poniżej punktu binarnego. W małych systemach, FF jest zwykle wybierany jako 12 N, dzięki czemu mnożenie jest faktycznie realizowane przez prawo przesunięcia N bitów. FILT jest więc zazwyczaj liczbą całkowitą o stałej liczbie punktów. Zauważ, że to nie zmienia żadnej matematyki z punktu widzenia procesorów. Na przykład, jeśli filtrujesz odczyty 10-bitowe AD i N 4 (FF 116), potrzebujesz 4 bitów ułamkowych poniżej 10-bitowych odczytów liczb całkowitych. Jedna większość procesorów, wykonujących 16-bitowe operacje całkowite z powodu odczytów 10-bitowych AD. W takim przypadku można nadal wykonywać dokładnie takie same 16-bitowe operacje całkowite, ale zaczynaj od odczytów AD przesuniętych o 4 bity. Procesor nie zna różnicy i nie musi. Wykonywanie matematyki na całych 16-bitowych liczb całkowitych działa niezależnie od tego, czy uważasz je za 12,4 punktu stałego czy prawdziwe 16-bitowe liczby całkowite (16,0 punkt stały). Ogólnie, musisz dodać N bity każdego bieguna filtra, jeśli nie chcesz dodawać hałasu z powodu liczby reprezentacji. W powyższym przykładzie drugi filtr dwóch musiałby mieć 1044 18 bitów, aby nie utracić informacji. W praktyce na 8-bitowej maszynie oznacza to, że używasz 24 bitowych wartości. Technicznie tylko drugi biegun dwóch wymagałby szerszej wartości, ale dla uproszczenia oprogramowania zwykle używam tej samej reprezentacji, a tym samym tego samego kodu, dla wszystkich biegunów filtra. Zwykle piszę podprogram lub makro, aby wykonać jedną operację słupa filtra, a następnie zastosować ją do każdego bieguna. Niezależnie od tego, czy podprocedura czy makra zależy od tego, czy cykle czy pamięć programu są ważniejsze w danym projekcie. Tak czy owak, używam pewnego stanu, aby przejść NEW do podprogramu, który aktualizuje plik FILT, ale ładuje się do tego samego stanu scratch NEW. To ułatwia stosowanie wielu biegunów, ponieważ aktualizacja FILT jednego bieguna jest NOWA następnego. Kiedy procedura podprogramu jest przydatna, gdy pojawi się wskaźnik po FILT, który zostanie zaktualizowany do chwili, gdy FILT wyjdzie. W ten sposób podprogram automatycznie uruchamia kolejne filtry w pamięci, jeśli jest wywołany wiele razy. Za pomocą makra nie potrzebujesz wskaźnika, ponieważ prześlesz adres, aby działał w każdej iteracji. Przykłady kodów Oto przykład makra opisanego powyżej dla PIC 18: A oto podobne makro dla PIC 24 lub dsPIC 30 lub 33: Obydwa przykłady są implementowane jako makra przy użyciu mojego preprocesora assemblera PIC. który jest bardziej zdolny niż jeden z wbudowanych urządzeń makr. clabacchio: Innym problemem, o którym wspomniałem, jest implementacja oprogramowania. Możesz raz napisać pojedynczą podprogramę filtra dolnoprzepustowego, a następnie zastosować ją wielokrotnie. W zasadzie zwykle piszę taką podprogram, aby wziąć wskaźnik w pamięci do stanu filtra, a następnie go wyprzedzić wskaźnik, aby można było z łatwością zadzwonić w celu realizacji wielobiegunowych filtrów. ndash Olin Lathrop 20 kwietnia 12 w 15:03 1. bardzo dziękuję za odpowiedzi - wszystkie z nich. Zdecydowałem się korzystać z tego filtru IIR, ale ten filtr nie jest używany jako filtr standardowy LowPass, ponieważ muszę przeanalizować średnie wartości liczników i porównać je, aby wykryć zmiany w określonym zakresie. ponieważ te Wartości mają bardzo różne wymiary, w zależności od sprzętu, które chciałem przeciętnie, aby móc automatycznie reagować na te specyficzne dla sprzętu zmiany. ndash sensslen May 21 12 at 12:06 Jeśli możesz żyć z ograniczeniem mocy dwóch liczb elementów do średniej (tj. 2,4,8,16,32 itd.), dzielenie można łatwo i skutecznie zrobić na niskiej wydajności mikro bez dedykowanego podziału, ponieważ można to zrobić jako przesunięcie bitowe. Każde prawo zmiany jest jedną moc dwóch, np .: OP myśli, że miał dwa problemy, dzieląc się PIC16 i pamięci na jego pierścień buforu. Ta odpowiedź pokazuje, że dzielenie nie jest trudne. Trzeba przyznać, że nie rozwiązuje problemu pamięci, ale system SE pozwala na częściowe odpowiedzi, a użytkownicy mogą wziąć coś z każdej odpowiedzi na siebie, a nawet edytować i połączyć inne odpowiedzi. Ponieważ niektóre inne odpowiedzi wymagają operacji podziału, są one podobnie niekompletne, ponieważ nie pokazują, jak skutecznie osiągnąć to na PIC16. ndash Martin Kwiecień 20 12 w 13:01 Jest odpowiedź na prawdziwy średniometrażowy filtr (aka boxcar filter) z mniejszymi wymaganiami pamięci, jeśli nie masz ochoty pobierać próbkowania. Nazywa się on kaskadowym integratorem-filtr grzebieniowy (CIC). Chodzi o to, że masz integrator, który podejmujesz w różnych odstępach czasu, a kluczowym urządzeniem oszczędzającym pamięć jest to, że dzięki zmniejszeniu próbkowania nie trzeba przechowywać każdej wartości integratora. Może być zaimplementowana za pomocą następującej pseudokodów: Twoja efektywna średnia długość ruchu to decimationFactorstatesize, ale wystarczy zachować próbki z miaridowania. Oczywiście można uzyskać lepszą wydajność, jeśli twój stateize i decimationFactor są uprawnieniami 2, tak aby operatorzy działów podziału i pozostałych otrzymali zastąpienia zmianami i maskowaniem. Postscript: Zgadzam się z Olinem, że należy zawsze rozważyć proste filtry IIR przed średnim filtrem ruchomym. Jeśli nie potrzebujesz częstotliwości-nulls z filtrem bokserskim, 1-biegunowy lub 2-biegunowy filtr dolnoprzepustowy prawdopodobnie działa dobrze. Z drugiej strony, jeśli filtruje się do celów decymacji (pobieranie danych o wysokiej liczbie próbek i uśrednianie go do użycia przy użyciu procesu o niskim współczynniku szybkości), wówczas filtr CIC może być właśnie tym, czego szukasz. (zwłaszcza jeśli można użyć statesize1 i uniknąć ringbuffer razem z tylko jedną poprzednią wartością integratora) Istnieją pewne pogłębione analizy matematyki za pomocą pierwszego filtru IIR zamówienia, które Olin Lathrop już opisał w sprawie wymiany stosunków przetwarzania sygnałów cyfrowych (zawiera mnóstwo ładnych zdjęć). Równanie dla tego filtru IIR to: Można to wykonać za pomocą tylko liczb całkowitych i żadnego podziału, używając następującego kodu (może potrzebować trochę debugowania podczas pisania z pamięci). Ten filtr przybliża średnią ruchomej ostatnie próbki K, ustawiając wartość alfa na 1K. Zrób to w poprzednim kodzie poprzez zdefiniowanie BITS na LOG2 (K), tj. Dla K 16 set BITS na 4, dla K 4 ustawić BITS na 2 itd. (Sprawdź kod podany tutaj, gdy tylko otrzymam zmianę i w razie potrzeby, zmień tę odpowiedź w razie potrzeby). Odpowiedź # 5 dnia: Październik 23, 2008, 04:04:38 am »Heres jeden-biegunowy filtr dolnoprzepustowy (średnia ruchoma, z cutoff częstotliwości CutoffFrequency). Bardzo prosty, bardzo szybki, działa świetnie i prawie nie ma pamięci. Uwaga: Wszystkie zmienne mają zakres poza funkcją filtru, z wyjątkiem przekazania w newInput Uwaga: Jest to filtr pojedynczego etapu. Wielokrotne etapy mogą być kaskadowe ze sobą w celu zwiększenia ostrości filtra. Jeśli używasz więcej niż jednego etapu, musisz wyregulować wartość DecayFactor (co dotyczy częstotliwości odcięcia), aby zrekompensować. I oczywiście wszystko, czego potrzebujesz to te dwie linie umieszczone w dowolnym miejscu, nie potrzebują własnej funkcji. Filtr ten ma czas pobudzenia, zanim średnia ruchoma odpowiada wartości sygnału wejściowego. Jeśli musisz obejść ten czas, możesz zainicjować MovingAverage tylko do pierwszej wartości newInput zamiast 0, i mam nadzieję, że pierwsza newInput nie jest lepsza. (CutoffFrequencySampleRate) ma zakres od 0 do 0.5. DecayFactor jest wartością od 0 do 1, zwykle blisko 1. Pojedyncze pływaki są wystarczająco dobre dla większości rzeczy, wolę tylko podwójnie. Jeśli musisz trzymać się liczb całkowitych, możesz przekonwertować DecayFactor i Amplitude Factor na ułamkowe liczby całkowite, w których licznik jest zapisany jako liczba całkowita, a mianownik jest liczbą całkowitą 2 (więc możesz przesunąć bit na prawo, mianownika, a nie dzielenia się podczas pętli filtracyjnej). Na przykład, jeśli DecayFactor 0.99 i chcesz używać liczb całkowitych, możesz ustawić wartość DecayFactor 0.99 65536 64881. A następnie w dowolnym momencie pomnożyć przez DecayFactor w pętli filtru, po prostu przesuń wynik 16. Aby uzyskać więcej informacji na ten temat, online, rozdział 19 na plikach rekursywnych: dspguidech19.htm PS Dla paradygmatu Moving Average, innego podejścia do ustawienia DecayFactor i AmplitudeFactor, które mogą być bardziej odpowiednie dla Twoich potrzeb, powiedzmy, że chcesz poprzednio, około 6 elementów uśrednio ze sobą, robi to dyskretnie, dodasz 6 pozycji i podzielisz przez 6, więc można ustawić AmplitudeFactor na 16 i DecayFactor na (1.0 - AmplitudeFactor). Odpowiedział 14 maja na 22:55. Wszyscy inni skomentowali dokładnie użyteczność IIR vs. FIR, i na władzę dwóch dywizji. Id tak, aby podać pewne szczegóły implementacji. Poniżej działa dobrze na małych mikrokontrolerach bez FPU. Nie ma mnożenia, a jeśli zachowasz N moc dwóch, cały podział jest jednorazowym cyklem przesuwania. Podstawowy bufor pierścieniowy FIR: zachowuje bieżący bufor z ostatnich wartości N i uruchomiony SUM wszystkich wartości w buforze. Za każdym razem, gdy pojawia się nowa próbka, odejmij najstarszą wartość w buforze z SUM, zastąp ją nową próbką, dodaj nową próbkę do SUMA i wydrukuj SUMN. Zmodyfikowany bufor pierścieniowy IIR: zachować bieżący SUM z ostatnich wartości N. Za każdym razem, gdy pojawia się nowa próbka, SUM - SUMN, dodaj nową próbkę i wyjdź SUMN. Odpowiedziałem 28 sierpnia 13 w 13:45 Jeśli czytam Ci dobrze, to opisujesz filtr IIR pierwszego rzędu, którego wartość odejmujesz nie jest najstarszą wartością wypadającą, ale raczej średnią z poprzednich wartości. Filtry IIR z pierwszego rzędu mogą z pewnością być użyteczne, ale nie jestem pewien co masz na myśli, gdy sugerujesz, że dane wyjściowe są takie same dla wszystkich okresowych sygnałów. Przy szybkości próbkowania 10 kHz, zasilanie falą kwadratową 100 Hz w 20-stopniowym filtrze pola, daje sygnał, który wzrasta równomiernie dla 20 próbek, siedzi na wysokościach 30, kropel równomiernie dla 20 próbek i siedzi na niskim poziomie 30. Pierwsze rzędy Filtr IIR. ndash supercat 28 sierpnia 13 w 15:31 przyniesie fali, która ostro zaczyna rosnąć i stopniowo wyrównywać blisko (ale nie na) maksimum wejściowe, a następnie gwałtownie zaczyna spadać i stopniowo wyrównać się blisko (ale nie na) minimalnego wejścia. Bardzo inne zachowania. ndash supercat 28 sierpnia 13 w 15:32 Jednym z problemów jest to, że prosta średnia ruchoma może być lub nie być użyteczna. Dzięki filtrowi IIR możesz uzyskać ładny filtr o stosunkowo niewielkiej liczbie calków. FIR, który opisujesz, może tylko dać prostokąt w czasie - szczerze freq - i nie możesz manipulować bocznymi płatkami. Być może warto rzucać kilka liczb całkowitych, aby uczynić to ładnym, symetrycznym tuningiem FIR, jeśli możesz oszczędzić zegary. ndash Scott Seidman 29 sierpnia 13 w 13:50 ScottSeidman: Nie ma potrzeby pomnożenia, jeśli jeden ma po prostu każdy etap FIR albo wyprowadzić średnio wejście na ten etap i jego poprzednią zapisaną wartość, a następnie zapisać dane wejściowe (jeśli ma w zakresie numerycznym, można by użyć sumy, a nie średniej). Niezależnie od tego, czy jest to lepsze od filtru pudełkowego zależy od aplikacji (odpowiedź krokowa filtru pudełkowego o całkowitym opóźnieniu 1ms, na przykład będzie miała paskudny skok d2dt przy zmianie wejścia, a następnie o 1 ms później, ale będzie miał minimum możliwe dd dla filtra o całkowitym opóźnieniu 1ms). ndash supercat Jak mikeselectricstuff powiedział, jeśli naprawdę trzeba zmniejszyć potrzeby pamięci, a nie pamiętam, twój impuls odpowiedzi jest wykładniczy (zamiast prostokątnego impulsu), chciałbym przejść do wykładniczej średniej ruchomych filtr . Używam ich w znacznym stopniu. Przy takim typie filtra nie potrzebujesz żadnego buforu. Nie musisz przechowywać N ostatnich próbek. Tylko jeden. Tak więc, Twoje wymagania pamięci zostały obniżone przez czynnik N. Ponadto, nie potrzebujesz żadnego podziału na to. Tylko multiplikacje. Jeśli masz dostęp do arytmetyki zmiennoprzecinkowej, użyj multiplikacji zmiennoprzecinkowych. W przeciwnym razie wykonaj multiplikacje całkowite i przesuń w prawo. Jednak jesteśmy w 2017 roku i zalecam używanie kompilatorów (i MCU), które umożliwiają pracę z liczbami zmiennoprzecinkowymi. Poza tym, że więcej pamięci jest wydajniejsze i szybsze (nie trzeba aktualizować elementów w dowolnym okrągłym buforze), chciałbym powiedzieć, że jest to również bardziej naturalne. ponieważ odpowiedź impulsowa jest lepsza w zachowaniu charakteru, w większości przypadków. Odpowiedziała 20 kwietnia o godz. 9:59 Jeden problem z filtrem IIR niemal dotknięty przez olin i supercat, ale najwyraźniej zignorowany przez innych jest taki, że zaokrąglanie wprowadza pewną nieprecyzyjność (i potencjalnie biastruncation). przy założeniu, że N jest mocą dwóch, a tylko arytmetyka całkowita jest używany, prawo przesunięcia systematycznie eliminuje LSBs nowej próbki. Oznacza to, że jak długo serie mogłyby się pojawić, średnia nigdy ich nie uwzględnia. Załóżmy na przykład, że powoli zmniejszają się serie (8,8, 8, 7, 7, 7, 6, 6) i zakładają, że średnia na początku wynosi 8. Próbka 7 piórki przyniesie średnią do 7, niezależnie od siły filtra. Tylko na jedną próbkę. Ta sama historia dla 6 itd. Teraz myśl o tym przeciwnie. seria idzie w górę. Średnia pozostanie na 7 na zawsze, dopóki próbka nie jest wystarczająco duża, aby ją zmienić. Oczywiście można poprawić nastawienie dodając 12N2, ale to naprawdę nie rozwiązuje problemu dokładności. w tym przypadku malejące serie pozostaną na zawsze w temperaturze 8, aż próbka wynosi 8-12 (N2). Dla przykładu N4, każda próba powyżej zera utrzyma średnią na niezmienionym poziomie. Sądzę, że rozwiązanie to oznaczałoby utrzymanie akumulatora utraconych LSB. Ale nie zrobiłem tego na tyle, aby mieć gotowy kod, i nie jestem pewien, że nie zaszkodzi mocy IIR w innych przypadkach serii (na przykład czy 7,9,7,9 średnio do 8 następnie). Olin, twoja dwustopniowa kaskada również potrzebuje wyjaśnienia. Czy masz na myśli trzymanie dwóch średnich wartości w wyniku pierwszego podania do drugiej w każdej iteracji. Co to jest korzyść z tego, wiem, że jest to osiągalne dzięki zwiększeniu: Ale naprawdę chciałbym uniknąć zwiększenia. Mam googled i nie znaleziono żadnych odpowiednich lub czytelnych przykładów. Zasadniczo chcę śledzić ruchomą średnią ciągłego strumienia strumienia liczb zmiennoprzecinkowych przy użyciu najnowszych 1000 numerów jako próbki danych. Jaki jest najłatwiejszy sposób na to, eksperymentowałem z użyciem okrągłej tablicy, wykładniczej średniej ruchomej i bardziej prostej średniej ruchomej i stwierdziła, że ​​wyniki okrągłej tablicy odpowiadały moim potrzebom najlepiej. zapytał 12 czerwca 12 w 4:38 Jeśli Twoje potrzeby są proste, możesz spróbować użyć wykładniczej średniej ruchomej. Po prostu wprowadzasz zmienną akumulatora, a kod wygląda na każdą próbkę, kod aktualizuje akumulator o nową wartość. Wybierasz stałą wartość alfa, która wynosi od 0 do 1, i oblicz ją: Wystarczy, że znajdziesz wartość alfa, w której efekt danej próbki trwa tylko około 1000 próbek. Hmm, nie jestem pewien, że to jest dla ciebie odpowiednie, teraz, że to tutaj. Problem polega na tym, że 1000 jest dość długie okno dla wykładniczej średniej ruchomej Im nie wiesz, że istnieje alfa, która rozprzestrzenia się średnią w ciągu ostatnich 1000 numerów, bez underflow w obliczaniu zmiennoprzecinkowych. Ale jeśli chcesz mieć mniejsze średnie, jak 30 liczb, jest to bardzo łatwy i szybki sposób na to. odpowiedziało cze 12 12 w 4:44 1 na Twoim stanowisku. Wyższa średnia ruchoma może pozwolić na zmienną alfa. Pozwala to na obliczanie średnich baz czasu (na przykład bajtów na sekundę). Jeśli czas od ostatniej aktualizacji akumulatora przekracza 1 sekundę, to niech alpha wynosi 1.0. W przeciwnym razie możesz pozwolić alpha be (usecs od ostatniej aktualizacji1000000). ndash jxh Cze 12 12 at 6:21 Zasadniczo chcę śledzić średnią ruchu ciągłego strumienia strumienia liczb zmiennoprzecinkowych przy użyciu najnowszych 1000 numerów jako próbki danych. Należy zauważyć, że poniżej uaktualnia całkowitą wartość jako elementy dodawane, co pozwala uniknąć kosztownego przebiegu O (N) w celu obliczenia sumy potrzebnej na przeciętnie na żądanie. Razem uzyskuje się inny parametr od T do obsługi np. używając długiej długi podczas łączenia 1000 długich s, int dla char s lub double-total float. Jest to nieco błędne, że liczby czcionek mogą przechodzić przez INTMAX - jeśli zależy Ci na długich długach bez podpisu. lub użyj dodatkowego członka danych bool do nagrywania, gdy pojemnik jest najpierw napełniany, podczas cyklicznych numsamples wokół tablicy (najlepiej zamienić coś nieszkodliwego jak pos). odpowiedziało 12 czerwca 12 w 5:19 zakłada się, że operator kwotowania (przykład T) jest w rzeczywistości operatorem cudzysłowów (przykład T). ndash oPless 8 czerwca o godz. 11:52 oPless ahhh. dobrze spotykane. właściwie miałem na myśli operatora void () (przykład T), ale oczywiście można użyć dowolnej notacji, którą lubisz. Naprawdę, dzięki. ndash Tony D cze 8 14 o 14:27

No comments:

Post a Comment