Thursday 20 July 2017

Moving Average Filter Implementation


Moving Average sebagai Filter Rata-rata bergerak sering digunakan untuk merapikan data dengan adanya noise. Rata-rata pergerakan sederhana tidak selalu dikenali sebagai filter Finite Impulse Response (FIR) yang sebenarnya, padahal sebenarnya adalah filter yang paling umum dalam pemrosesan sinyal. Mengobati itu sebagai filter memungkinkan membandingkannya dengan, misalnya filter windowed-sinc (lihat artikel tentang filter low-pass, high-pass, dan band-pass dan band-reject untuk contohnya). Perbedaan utama dengan filter tersebut adalah bahwa rata-rata bergerak cocok untuk sinyal yang informasi bermanfaatnya terdapat dalam domain waktu. Pengukuran perataan dengan rata-rata adalah contoh utama. Saringan berjejer-sinc, di sisi lain, adalah pemain yang kuat dalam domain frekuensi. Dengan pemerataan dalam pengolahan audio sebagai contoh tipikal. Ada perbandingan yang lebih rinci dari kedua jenis filter dalam Domain Time vs. Frekuensi Kinerja Filter. Jika Anda memiliki data yang baik waktu dan domain frekuensi penting, Anda mungkin ingin melihat Variasi pada Moving Average. Yang menyajikan sejumlah versi bobot rata-rata bergerak yang lebih baik dalam hal itu. Rata-rata pergerakan panjang (N) dapat didefinisikan sebagai ditulis seperti biasanya diterapkan, dengan sampel keluaran saat ini sebagai rata-rata sampel (N) sebelumnya. Terlihat sebagai filter, moving average melakukan konvolusi dari urutan input (xn) dengan pulsa panjang persegi panjang (N) dan tinggi (1N) (untuk membuat area pulsa, dan, karenanya, gain filter , satu ). Dalam prakteknya, yang terbaik adalah mengambil (N) ganjil. Meskipun rata-rata bergerak juga dapat dihitung dengan menggunakan sejumlah sampel, dengan menggunakan nilai ganjil untuk (N) memiliki keuntungan bahwa penundaan filter akan menjadi jumlah sampel integer, karena penundaan filter dengan (N) Contohnya persis ((N-1) 2). Rata-rata bergerak kemudian dapat disesuaikan persis dengan data asli dengan menggesernya dengan bilangan bulat sampel. Domain Waktu Karena rata-rata bergerak adalah konvolusi dengan pulsa persegi panjang, respons frekuensinya adalah fungsi sinc. Hal ini membuat sesuatu seperti dual filter windowed-sinc, karena itu adalah konvolusi dengan pulsa sinc yang menghasilkan respons frekuensi persegi panjang. Ini adalah respon frekuensi sinc yang membuat rata-rata bergerak menjadi pemain miskin dalam domain frekuensi. Namun, kinerjanya sangat bagus dalam domain waktu. Oleh karena itu, sangat sempurna untuk memperlancar data agar terhapus noise sementara pada saat bersamaan tetap melakukan respon langkah cepat (Gambar 1). Untuk Additive White Gaussian Noise (AWGN) biasa yang sering diasumsikan, sampel rata-rata (N) memiliki efek meningkatkan SNR dengan faktor (sqrt N). Karena kebisingan untuk sampel individu tidak berkorelasi, tidak ada alasan untuk memperlakukan setiap sampel secara berbeda. Oleh karena itu, rata-rata bergerak, yang memberi setiap sampel bobot yang sama, akan menyingkirkan jumlah suara maksimal untuk ketajaman respons langkah tertentu. Implementasi Karena itu adalah filter FIR, moving average bisa diimplementasikan melalui konvolusi. Ini kemudian akan memiliki efisiensi yang sama (atau kurang) seperti filter FIR lainnya. Namun, bisa juga diimplementasikan secara rekursif, dengan cara yang sangat efisien. Ini mengikuti langsung dari definisi bahwa Rumus ini adalah hasil dari ungkapan untuk (yn) dan (yn1), yaitu, di mana kita melihat bahwa perubahan antara (yn1) dan (yn) adalah bahwa istilah tambahan (xn1N) muncul di Akhir, sementara istilah (xn-N1N) dihapus dari awal. Dalam aplikasi praktis, seringkali memungkinkan untuk meninggalkan pembagian dengan (N) untuk setiap istilah dengan mengkompensasi keuntungan yang dihasilkan (N) di tempat lain. Implementasi rekursif ini akan jauh lebih cepat daripada konvolusi. Setiap nilai baru (y) dapat dihitung hanya dengan dua penambahan, dan bukan penambahan (N) yang diperlukan untuk implementasi definisi yang langsung. Satu hal yang harus diwaspadai dengan implementasi rekursif adalah kesalahan pembulatan akan terakumulasi. Ini mungkin atau mungkin tidak menjadi masalah bagi aplikasi Anda, namun ini juga menyiratkan bahwa implementasi rekursif ini akan benar-benar bekerja lebih baik dengan implementasi bilangan bulat daripada dengan bilangan floating-point. Ini sangat tidak biasa, karena implementasi floating point biasanya lebih sederhana. Kesimpulan dari semua ini pasti bahwa Anda tidak boleh meremehkan kegunaan filter rata-rata bergerak sederhana dalam aplikasi pemrosesan sinyal. Filter Design Tool Artikel ini dilengkapi dengan alat Filter Design. Percobaan dengan nilai yang berbeda untuk (N) dan visualisasikan filter yang dihasilkan. Cobalah sekarang saya pada dasarnya memiliki sejumlah nilai seperti ini: Array di atas disederhanakan, saya mengumpulkan 1 nilai per milidetik dalam kode sebenarnya dan saya perlu mengolah keluaran pada algoritma yang saya tulis untuk menemukan puncak terdekat sebelum sebuah titik pada waktunya. . Logika saya gagal karena dalam contoh saya di atas, 0,36 adalah puncak sebenarnya, tapi algoritme saya akan terlihat mundur dan melihat angka terakhir 0,25 sebagai puncaknya, karena ada penurunan menjadi 0,24 sebelum itu. Tujuannya adalah untuk mengambil nilai-nilai ini dan menerapkan algoritma kepada mereka yang akan menghaluskannya sedikit sehingga saya memiliki nilai linier yang lebih banyak. (Yaitu: Id seperti hasil saya melengkung, tidak bergerigi) Saya telah diberitahu untuk menerapkan filter rata-rata bergerak eksponensial ke nilai-nilai saya. Bagaimana saya bisa melakukan ini Sangat sulit bagi saya untuk membaca persamaan matematis, saya jauh lebih baik dengan kode. Bagaimana cara memproses nilai dalam array saya, menerapkan perhitungan rata-rata bergerak eksponensial bahkan sampai mereka bertanya pada 8 Februari pukul 20:27 untuk menghitung rata-rata pergerakan eksponensial. Anda perlu menyimpan beberapa keadaan di sekitar dan Anda memerlukan parameter tuning. Ini memerlukan kelas kecil (dengan asumsi Anda menggunakan Java 5 atau yang lebih baru): Instantiate dengan parameter peluruhan yang Anda inginkan (mungkin mengambil tuning harus antara 0 dan 1) dan kemudian gunakan rata-rata () untuk memfilter. Saat membaca sebuah halaman tentang beberapa kekambuhan mathmatical, semua yang Anda benar-benar perlu ketahui saat mengubahnya menjadi kode adalah matematikawan suka menulis indeks menjadi array dan urutan dengan subskrip. (Ada beberapa notasi lain juga, yang tidak membantu). Namun, EMA cukup sederhana karena Anda hanya perlu mengingat satu nilai lama tanpa susunan negara yang rumit. Jawab Feb 8 12 jam 20:42 TKKocheran: Cukup banyak. Tidak masalah jika hal-hal sederhana (Jika dimulai dengan urutan baru, dapatkan rata-rata baru.) Perhatikan bahwa beberapa istilah pertama dalam urutan rata-rata akan melompat sedikit karena efek batas, namun Anda mendapatkan yang memiliki rata-rata bergerak lainnya. terlalu. Namun, keuntungan yang bagus adalah Anda dapat membungkus logika rata-rata bergerak ke rata-rata dan bereksperimen tanpa mengganggu keseluruhan program Anda. Ndash Donal Fellows Feb 9 12 at 0:06 Saya mengalami kesulitan untuk memahami pertanyaan Anda, tapi saya akan mencoba menjawabnya juga. 1) Jika algoritma Anda menemukan 0,25 bukan 0,36, maka itu salah. Ini salah karena mengasumsikan kenaikan atau penurunan monotonik (yang selalu naik atau selalu turun). Kecuali Anda rata-rata SEMUA data Anda, poin data Anda --- seperti yang Anda sampaikan - tidak bersifat nonlinier. Jika Anda benar-benar ingin menemukan nilai maksimum antara dua titik dalam waktu, maka iris array Anda dari tmin ke tmax dan temukan maks dari subarray itu. 2) Sekarang, konsep moving averages sangat sederhana: bayangkan bahwa saya memiliki daftar berikut: 1.4, 1.5, 1.4, 1.5, 1.5. Saya bisa menghaluskannya dengan mengambil rata-rata dua angka: 1.45, 1.45, 1.45, 1.5. Perhatikan bahwa angka pertama adalah rata-rata 1,5 dan 1,4 (angka kedua dan pertama) yang kedua (daftar baru) adalah rata-rata 1,4 dan 1,5 (daftar ketiga dan kedua) yang ketiga (daftar baru) rata-rata 1,5 dan 1,4 (Keempat dan ketiga), dan seterusnya. Saya bisa membuatnya periode tiga atau empat, atau n. Perhatikan bagaimana datanya jauh lebih mulus. Cara yang baik untuk melihat rata-rata bergerak di tempat kerja adalah pergi ke Google Finance, pilih saham (coba Tesla Motors cukup mudah menguap (TSLA)) dan klik pada teknikal di bagian bawah bagan. Pilih Moving Average dengan periode tertentu, dan moving average eksponensial untuk membandingkan perbedaannya. Rata-rata pergerakan eksponensial hanyalah penjabaran lain dari ini, namun bobot data yang lebih tua kurang dari data baru ini adalah cara untuk meratakan perataan ke arah belakang. Silahkan baca entri Wikipedia. Jadi, ini lebih merupakan komentar daripada sebuah jawaban, tapi kotak komentar kecil itu hanya untuk mungil. Semoga berhasil. Jika Anda mengalami masalah dengan matematika, Anda bisa pergi dengan rata-rata bergerak sederhana daripada eksponensial. Jadi output yang Anda dapatkan akan menjadi x terakhir yang dibagi dengan x. Pseudocode yang tidak teruji: Perhatikan bahwa Anda perlu menangani bagian awal dan akhir data karena dengan jelas Anda tidak dapat menghitung rata-rata 5 persyaratan saat Anda berada di data 2 Anda. Juga, ada cara yang lebih efisien untuk menghitung rata-rata bergerak ini (jumlah sum - tertua terbaru), namun ini adalah untuk mendapatkan konsep tentang apa yang terjadi. Jawab 8 Februari pukul 20: 41 Saya tahu ini bisa dicapai dengan dorongan sesuai: Tapi saya benar-benar ingin menghindari penggunaan dorongan. Saya telah googled dan tidak menemukan contoh yang sesuai atau mudah dibaca. Pada dasarnya saya ingin melacak rata-rata bergerak aliran arus dari sejumlah angka floating point dengan menggunakan 1000 nomor terbaru sebagai sampel data. Apa cara termudah untuk mencapainya? Saya bereksperimen dengan menggunakan array melingkar, moving average eksponensial dan moving average yang lebih sederhana dan menemukan bahwa hasil dari array melingkar sesuai dengan kebutuhan saya yang terbaik. Tanya 12 Jun 12 at 4:38 Jika kebutuhan Anda sederhana, Anda mungkin hanya mencoba menggunakan rata-rata bergerak eksponensial. Sederhananya, Anda membuat variabel akumulator, dan saat kode Anda melihat setiap sampel, kode akan memperbarui akumulator dengan nilai baru. Anda memilih alpha konstan yaitu antara 0 dan 1, dan hitung ini: Anda hanya perlu menemukan nilai alfa dimana efek sampel tertentu hanya bertahan sekitar 1000 sampel. Hmm, saya tidak yakin ini cocok untuk anda, sekarang saya sudah meletakkannya disini. Masalahnya adalah bahwa 1000 adalah jendela yang cukup panjang untuk rata-rata bergerak eksponensial Im tidak yakin ada alfa yang akan menyebar rata-rata selama 1000 nomor terakhir, tanpa arus dalam perhitungan floating point. Tapi jika Anda menginginkan rata-rata yang lebih kecil, seperti 30 angka atau lebih, ini adalah cara yang sangat mudah dan cepat untuk melakukannya. Jawab 12 Jun pukul 4:44 di posmu Rata-rata pergerakan eksponensial dapat memungkinkan alfa menjadi variabel. Jadi, ini memungkinkannya digunakan untuk menghitung rata-rata basis waktu (misalnya byte per detik). Jika waktu sejak update akumulator terakhir lebih dari 1 detik, Anda membiarkan alpha menjadi 1.0. Jika tidak, Anda bisa membiarkan alpha menjadi (usecs sejak update1000000 terakhir). Ndash jxh 12 Jun 12 at 6:21 Pada dasarnya saya ingin melacak rata-rata bergerak aliran arus dari sebuah angka floating point dengan menggunakan 1000 nomor terbaru sebagai sampel data. Perhatikan bahwa di bawah ini update total sebagai elemen sebagai tambahan yang ditambahkan, hindari tumpang tindih O (N) untuk menghitung jumlah yang dibutuhkan untuk rata-rata - sesuai permintaan. Total dibuat parameter yang berbeda dari T untuk mendukung mis. Menggunakan panjang yang panjang bila total 1000 s panjang, int untuk char s, atau double to total float s. Ini sedikit cacat pada numsamples yang bisa melewati INTMAX - jika Anda peduli Anda bisa menggunakan unsigned long long. Atau gunakan anggota data bool tambahan untuk merekam saat wadah pertama kali diisi saat bersepeda mendekati numamples di sekitar array (terbaik kemudian berganti nama menjadi sesuatu yang tidak berbahaya seperti pos). Dijawab 12 Jun 12 at 5:19 seseorang mengasumsikan bahwa operator quotvoid (T sample) quot sebenarnya adalah quotvoid operatorltlt (T sample) quot. Ndash oPless 8 Jun 14 jam 11:52 oPless ahhh. Baik terlihat Sebenarnya saya bermaksud untuk itu menjadi operator void () (sampel T) tapi tentu saja Anda bisa menggunakan notasi apa pun yang Anda sukai. Akan memperbaiki, terima kasih. Ndash Tony D 8 Jun pukul 14:27

No comments:

Post a Comment