Sunday 27 August 2017

Rata rata tertimbang filter c ++


Mungkinkah menerapkan rata-rata bergerak di C tanpa memerlukan jendela sampel, saya telah menemukan bahwa saya dapat mengoptimalkan sedikit, dengan memilih ukuran jendela, itulah kekuatan dua untuk memungkinkan perpindahan bit daripada membagi, tapi tidak memerlukannya. Penyangga akan menyenangkan Apakah ada cara untuk mengungkapkan hasil rata-rata bergerak baru hanya sebagai fungsi dari hasil lama dan sampel baru Tentukan contoh rata-rata bergerak, di atas jendela 4 sampel menjadi: Tambahkan sampel baru e: Rata-rata bergerak dapat diimplementasikan secara rekursif. , Tapi untuk kalkulasi rata-rata bergerak yang tepat, Anda harus mengingat sampel masukan tertua dalam jumlah (misalnya huruf a pada contoh Anda). Untuk panjang N rata-rata bergerak yang Anda hitung: di mana yn adalah sinyal output dan xn adalah sinyal input. Pers. (1) dapat ditulis secara rekursif. Jadi Anda harus selalu mengingat sampel xn-N untuk menghitung (2). Seperti yang ditunjukkan oleh Conrad Turner, Anda dapat menggunakan jendela eksponensial (jauh lebih panjang), yang memungkinkan Anda menghitung keluaran hanya dari keluaran lalu dan masukan saat ini: namun ini bukan standar pergerakan rata-rata (tanpa bobot) namun secara eksponensial Rata bergerak tertimbang, di mana sampel lebih jauh di masa lalu mendapatkan bobot yang lebih kecil, tapi (setidaknya secara teori) Anda tidak akan pernah melupakan apapun (bobotnya semakin kecil dan kecil untuk sampel jauh di masa lalu). Saya menerapkan rata-rata bergerak tanpa memori item individual untuk program pelacakan GPS yang saya tulis. Saya mulai dengan 1 sampel dan bagi 1 untuk mendapatkan nilai rata-rata saat ini. Saya kemudian menambahkan sampel anothe dan membagi dengan 2 ke avg saat ini. Ini berlanjut sampai saya mencapai panjang rata-rata. Setiap saat setelah itu, saya menambahkan sampel baru, mendapatkan rata-rata dan menghapus rata-rata dari total. Saya bukan seorang matematikawan tapi ini sepertinya cara yang bagus untuk melakukannya. Kupikir itu akan mengubah perut orang matematika sejati tapi, ternyata itu adalah salah satu cara yang bisa diterima untuk melakukannya. Dan hasilnya bagus. Ingatlah bahwa semakin tinggi panjangnya semakin lambat maka mengikuti apa yang ingin Anda ikuti. Itu mungkin tidak masalah sebagian besar waktu tapi ketika mengikuti satelit, jika Anda lamban, jejaknya bisa jauh dari posisi sebenarnya dan akan terlihat buruk. Anda bisa memiliki jarak antara tempat duduk dan titik-titik trailing. Saya memilih panjang 15 update 6 kali per menit untuk mendapatkan smoothing yang memadai dan tidak terlalu jauh dari posisi duduk sebenarnya dengan titik jepret yang merapikan. Jawab 16 16 16 di 23:03 menginisialisasi total 0, count0 (setiap kali melihat nilai baru Kemudian satu masukan (scanf), satu menambahkan totalnewValue, satu kenaikan (hitungan), satu rata-rata pembagian (jumlah total) Ini akan menjadi rata-rata bergerak di atas Semua input Untuk menghitung rata-rata hanya di atas 4 masukan terakhir, akan memerlukan 4 variabel input, mungkin menyalin setiap masukan ke inputvariable yang lebih tua, kemudian menghitung rata-rata pergerakan baru. Sebagai jumlah dari 4 variabel input, dibagi dengan 4 (pergeseran kanan 2 akan menjadi Baik jika semua input positif membuat perhitungan rata-rata dijawab 3 Feb 15 at 4:06 Itu benar-benar akan menghitung rata-rata total dan TIDAK rata-rata bergerak. Seiring bertambahnya dampak, setiap sampel masukan baru menjadi sangat kecil ndash Hilmar Feb 3 15 at 13:53 Jawaban Anda 2017 Stack Exchange, Inc Saya mencoba untuk menghitung rata-rata pergerakan sebuah sinyal. Nilai sinyal (ganda) diperbarui pada waktu-waktu acak. Saya mencari cara yang efisien untuk menghitung rata-rata tertimbang waktunya. Ove R jendela waktu, secara real time. Saya bisa melakukannya sendiri, tapi ini lebih menantang dari yang saya duga. Sebagian besar sumber yang saya temukan di internet menghitung rata-rata sinyal periodik bergerak, namun pembaruan ranjau pada waktu acak. Apakah ada yang tahu sumber daya yang baik untuk itu Caranya adalah sebagai berikut: Anda mendapatkan update secara acak melalui void update (int time, float value). Namun Anda juga perlu juga melacak saat update jatuh dari jendela waktu, jadi Anda mengatur alarm yang memanggil pada waktu N yang menghapus pembaruan sebelumnya dari yang pernah dipertimbangkan lagi dalam perhitungan. Jika ini terjadi secara real-time Anda dapat meminta sistem operasi untuk melakukan panggilan ke metode void dropoffoldestupdate (int time) untuk dipanggil pada saat N Jika ini adalah simulasi, Anda tidak dapat memperoleh bantuan dari sistem operasi dan Anda perlu Lakukan secara manual Dalam simulasi Anda akan memanggil metode dengan waktu yang diberikan sebagai argumen (yang tidak berkorelasi dengan real time). Namun, asumsi yang masuk akal adalah bahwa panggilan dijamin sedemikian rupa sehingga argumen waktu meningkat. Dalam kasus ini, Anda perlu mengatur daftar nilai waktu alarm yang diurutkan, dan untuk setiap pembaruan dan baca panggilan, Anda harus memeriksa apakah argumen waktu lebih besar daripada daftar alarm. Meskipun lebih besar Anda melakukan pemrosesan terkait alarm (nonaktifkan pembaruan yang paling lama), lepaskan kepala dan periksa lagi sampai semua alarm sebelum waktu tertentu diproses. Lalu lakukan update call. Sejauh ini aku menduga sudah jelas apa yang akan Anda lakukan untuk perhitungan sebenarnya, tapi saya akan menjelaskannya untuk berjaga-jaga. Saya asumsikan Anda memiliki metode float read (int time) yang Anda gunakan untuk membaca nilainya. Tujuannya agar panggilan ini seefisien mungkin. Jadi, Anda tidak menghitung rata-rata bergerak setiap kali metode baca dipanggil. Sebagai gantinya Anda melakukan precompute nilai pada update terakhir atau alarm terakhir, dan tweak nilai ini oleh beberapa operasi floating point untuk memperhitungkan berlalunya waktu sejak update terakhir. (I. sejumlah operasi konstan kecuali mungkin memproses daftar alarm yang tertumpuk). Semoga ini jelas - ini harus menjadi algoritma yang cukup sederhana dan cukup efisien. Optimalisasi lebih lanjut. Salah satu masalah yang tersisa adalah jika sejumlah besar pembaruan terjadi di jendela waktu, maka ada waktu yang lama dimana tidak ada pembacaan atau pembaruan, dan kemudian pembacaan atau pembaruan muncul. Dalam kasus ini, algoritma di atas akan tidak efisien secara bertahap memperbarui nilai untuk setiap pembaruan yang jatuh. Ini tidak perlu karena kami hanya peduli dengan pembaruan terakhir di luar jendela waktu sehingga jika ada cara untuk secara efisien menurunkan semua pembaruan yang lebih lama, ini akan membantu. Untuk melakukan ini, kita dapat memodifikasi algoritma untuk melakukan pencarian biner dari update untuk menemukan update terbaru sebelum jendela waktu. Jika ada sedikit pembaruan yang perlu dijatuhkan maka seseorang dapat secara bertahap memperbarui nilainya untuk setiap pembaruan yang terjatuh. Tapi jika ada banyak update yang perlu dijatuhkan maka seseorang bisa menghitung ulang nilainya dari nol setelah mengundurkan diri dari update lama. Lampiran pada Perhitungan Incremental: Saya harus menjelaskan apa yang saya maksud dengan perhitungan tambahan di atas dalam kalimat yang men-tweak nilai ini oleh beberapa operasi floating point untuk memperhitungkan berlalunya waktu sejak update terakhir. Perhitungan awal non-inkremental: kemudian iterate over relevantupdates dalam rangka peningkatan waktu: movingaverage (sum lastupdate timesincelastupdate) windowlength. Sekarang jika tepat satu update jatuh dari jendela tapi tidak ada update baru tiba, sesuaikan jumlah sebagai: (perhatikan itu adalah priorupdate yang memiliki cap waktu dimodifikasi untuk memulai jendela terakhir dimulai). Dan jika tepat satu update masuk ke jendela tapi tidak ada update baru yang jatuh, sesuaikan jumlah sebagai: Seperti yang seharusnya jelas, ini adalah sketsa kasar tapi mudah-mudahan ini menunjukkan bagaimana Anda dapat mempertahankan rata-rata operasi O (1) per update. Atas dasar amortisasi. Tapi perhatikan optimasi lebih lanjut di paragraf sebelumnya. Perhatikan juga masalah stabilitas yang disinggung dalam jawaban yang lebih tua, yang berarti bahwa kesalahan floating point dapat menumpuk lebih dari sejumlah besar operasi inkremental semacam itu sehingga ada perbedaan dari hasil komputasi penuh yang signifikan terhadap aplikasi. Jika perkiraannya baik-baik saja dan ada waktu minimum di antara sampel, Anda bisa mencoba super-sampling. Miliki sebuah array yang mewakili interval waktu jarak merata yang lebih pendek dari minimum, dan setiap periode menyimpan sampel terbaru yang diterima. Semakin pendek jeda, semakin mendekati rata-rata nilai sebenarnya. Periode seharusnya tidak lebih dari setengah minimum atau ada kemungkinan kehilangan sampel. Jawab 15 Des 11 18:12 Terima kasih atas jawabannya. Salah satu perbaikan yang akan dibutuhkan untuk benar-benar mengutip nilai rata-rata dari total rata-rata jadi kami tidak melingkar sepanjang waktu. Juga, ini mungkin titik kecil, tapi tidakkah lebih efisien menggunakan deque atau daftar untuk menyimpan nilainya, karena kita berasumsi bahwa update akan sesuai dengan urutan yang benar. Penyisipan akan lebih cepat dari pada peta. Ndash Arthur 16 Des 11 at 8:55 Ya, Anda bisa menyimpan nilai penjumlahan. Kurangi nilai sampel yang Anda hapus, tambahkan nilai sampel yang Anda sisipkan. Juga, ya, contoh dequeltpairltample, Dategtgt mungkin lebih efisien. Saya memilih peta untuk mudah dibaca, dan kemudahan memohon peta :: upperbound. Seperti biasa, tulis kode yang benar dulu, lalu profil dan ukur perubahan inkremental. Ndash Rob 16 Desember 11 pukul 15:00 Catatan: Rupanya ini bukan cara untuk mendekati ini. Meninggalkannya di sini untuk referensi tentang apa yang salah dengan pendekatan ini. Periksa komentarnya. UPDATED - berdasarkan komentar Olis. Tidak yakin tentang ketidakstabilan yang dia bicarakan sekalipun. Gunakan peta waktu kedatangan yang ditentukan terhadap nilai. Saat kedatangan sebuah nilai menambahkan waktu kedatangan ke peta yang diurutkan beserta nilainya dan memperbarui moving average. Peringatan ini pseudo-code: disana. Tidak sepenuhnya fleshed keluar tapi Anda mendapatkan ide. Hal yang perlu diperhatikan. Seperti yang saya katakan di atas adalah kode pseudo. Anda harus memilih peta yang sesuai. Jangan menghapus pasangan saat Anda melakukan iterasi karena Anda akan membuat iterator tidak valid dan harus dimulai lagi. Lihat komentar Olis di bawah ini juga. Menjawab 15 Des 11 jam 12:22 Pekerjaan ini tidak berhasil: tidak memperhitungkan berapa proporsi panjang jendela setiap nilai. Selain itu, pendekatan penambahan dan penguraian ini hanya stabil untuk tipe integer, bukan pelampung. Ndash Oliver Charlesworth 15 Des 12 12 OliCharlesworth - maaf saya melewatkan beberapa poin penting dalam deskripsi (double and time-weighted). Saya akan update Terima kasih. Ndash Dennis Dec 15 11 at 12:33 Waktu-bobot adalah masalah lain. Tapi bukan itu yang saya bicarakan. Saya mengacu pada fakta bahwa ketika nilai baru pertama kali memasuki jendela waktu, kontribusinya terhadap rata-rata sangat minim. Kontribusinya terus meningkat sampai nilai baru masuk. Ndash Oliver Charlesworth 15 Des 11 di 12:35 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 sebuah 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 rata-rata bergerak 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 1 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, hindarkan O (N) yang mahal untuk menghitung jumlah yang dibutuhkan untuk rata-rata - sesuai permintaan. Total dibuat parameter yang berbeda dari T untuk mendukung mis. Menggunakan panjang 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 dicatat 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 jam 14:27

No comments:

Post a Comment