Friday 24 February 2017

Moving Average Filter Cpp

Im codage quelque chose au moment où Im prendre un tas de valeurs au fil du temps d'une boussole matérielle. Cette boussole est très précise et mise à jour très souvent, avec le résultat que si elle jiggles légèrement, je me retrouve avec la valeur étrange qui est sauvagement incompatible avec ses voisins. Je veux lisser ces valeurs. Après avoir fait quelques lectures, il semblerait que ce que je veux est un filtre passe-haut, un filtre passe-bas ou une moyenne mobile. Moyenne mobile je peux descendre avec, il suffit de garder un historique des dernières 5 valeurs ou autre, et d'utiliser la moyenne de ces valeurs en aval dans mon code où j'ai été une fois juste en utilisant la valeur la plus récente. Cela devrait, je pense, lisser ces jiggles joliment, mais il me semble que son probablement tout à fait inefficace, et c'est probablement l'un de ces problèmes connus aux programmeurs appropriés à qui theres une solution vraiment ordonnée Clever Math. Je suis, cependant, l'un de ces programmeurs autodidactes horribles sans un morceau de l'éducation formelle dans quelque chose même vaguement liés à CompSci ou Math. La lecture autour d'un peu suggère que cela peut être un filtre passe-haut ou bas, mais je ne peux pas trouver quoi que ce soit qui explique en termes compréhensibles à un hack comme moi ce que l'effet de ces algorithmes serait sur un tableau de valeurs, travaux. La réponse donnée ici. Par exemple, techniquement répond à ma question, mais seulement en termes compréhensibles à ceux qui seraient probablement déjà savoir comment résoudre le problème. Ce serait une personne très belle et intelligente en effet qui pourrait expliquer le genre de problème, c'est, et comment les solutions de travail, en termes compréhensibles pour un diplômé Arts. Si votre moyenne mobile doit être longue afin d'obtenir le lissage requis, et que vous n'avez pas vraiment besoin d'une forme particulière de noyau, alors vous êtes mieux si vous utilisez une moyenne mobile exponentiellement en décomposition: où vous Choisissez minuscule pour être une constante appropriée (par exemple, si vous choisissez le minuscule 1- 1N, il aura la même quantité de moyenne que la fenêtre de taille N, mais différemment différemment sur les points plus anciens). Quoi qu'il en soit, puisque la prochaine valeur de la moyenne mobile ne dépend que de la précédente et vos données, vous n'avez pas à garder une file d'attente ou quoi que ce soit. Et vous pouvez penser à cela comme faire quelque chose comme, Eh bien, Ive a obtenu un nouveau point, mais je ne fais pas vraiment confiance, donc Im va garder 80 de ma vieille estimation de la mesure, et ne font confiance à ce nouveau point de données 20. Thats À peu près la même chose que de dire, Eh bien, je ne fais confiance à ce nouveau point 20, et Ill utiliser 4 autres points que je fais confiance à la même quantité, sauf que, au lieu de prendre explicitement les 4 autres points, vous êtes en supposant que la moyenne que vous avez fait la dernière fois Était raisonnable, donc vous pouvez utiliser votre travail précédent. Répondre Sep 21 10 at 14:27 Hey, je sais que c'est 5 ans de retard, mais merci pour une réponse géniale. I39m travaillant sur un jeu où le son change en fonction de votre vitesse, mais en raison de l'exécution du jeu sur un ordinateur slow-ass, la vitesse fluctuerait sauvagement, ce qui était bien pour la direction, mais super ennuyeux en termes de son. C'était une solution vraiment simple et bon marché pour quelque chose que je pensais être un problème vraiment complexe. Ndash Adam Mar 16 15 at 20:20 Si vous essayez de supprimer la valeur impair occasionnelle, un filtre passe-bas est le meilleur des trois options que vous avez identifié. Les filtres passe-bas permettent des changements à faible vitesse tels que ceux causés par la rotation d'une boussole à la main, tout en rejetant des changements à grande vitesse tels que ceux provoqués par des bosses sur la route, par exemple. Une moyenne mobile ne sera probablement pas suffisante, car les effets d'un seul flip dans vos données affecteront plusieurs valeurs ultérieures, selon la taille de votre fenêtre de moyenne mobile. Si les valeurs impaires sont facilement détectées, vous pouvez même être mieux avec un algorithme de suppression de glitch qui les ignore complètement: Voici un graphique guick à illustrer: Le premier graphe est le signal d'entrée, avec un glitch désagréable. Le deuxième graphique montre l'effet d'une moyenne mobile de 10 échantillons. Le graphe final est une combinaison de la moyenne de 10 échantillons et de l'algorithme de détection de glitch simple représenté ci-dessus. Lorsque le glitch est détecté, la moyenne de 10 échantillons est utilisée au lieu de la valeur réelle. Moyenne mobile, je peux descendre avec. Mais il me semble que son probablement tout à fait inefficace. Theres vraiment aucune raison qu'une moyenne mobile devrait être inefficace. Vous conservez le nombre de points de données que vous voulez dans un tampon (comme une file d'attente circulaire). Sur chaque nouveau point de données, vous générez la valeur la plus ancienne et soustrayez-la d'une somme, puis appuyez sur la plus récente et ajoutez-la à la somme. Donc, chaque nouveau point de données implique vraiment seulement un poppush, un ajout et une soustraction. Votre moyenne mobile est toujours cette somme décalage divisée par le nombre de valeurs dans votre tampon. Il devient un peu plus délicat si vous recevez des données simultanément à partir de plusieurs threads, mais puisque vos données proviennent d'un périphérique matériel qui semble très douteux pour moi. Oh et aussi: horribles programmeurs autodidactes se réunissent) La moyenne mobile semblait inefficace pour moi parce que vous devez stocker un tampon de valeurs - mieux faire juste quelques Clever Maths avec votre valeur d'entrée et la valeur de travail courante Je pense que la moyenne mobile exponentielle travaux. Une optimisation que j'observe pour ce type de moyenne mobile implique l'utilisation d'un ampli de files d'attente de longueur fixe, un pointeur vers l'endroit où vous vous trouvez dans cette file d'attente, et juste d'envelopper le pointeur autour (avec ou un if). Voila Pas cher pushpop. Puissance pour les amateurs, le frère ndash Henry: Pour une moyenne mobile straight-up vous avez besoin de la mémoire tampon simplement pour que vous sachiez ce que la valeur se fait sauter lorsque la prochaine valeur obtenir poussé. Cela dit, l'ampli de queue de longueur fixe, un pointeur que vous décrivez est exactement ce que je voulais dire par file d'attente quotcirculaire. C'est pourquoi je disais que ce n'est pas efficace. Qu'est-ce que vous pensez que je voulais dire Et si votre réponse est quotan tableau qui décale ses valeurs sur chaque suppression indexée (comme std :: vector en C). Je ne sais pas sur AS3, mais un programmeur Java a obtenu des collections comme CircularQueue à son disposition (I39m pas un Java développeur donc I39m sûr il ya de meilleurs exemples là-bas that39s juste ce que j'ai trouvé à partir d'une recherche rapide Google), qui implémente précisément la fonctionnalité we39re parler. I39m assez confiant la majorité des langues de moyenne et de basse-niveau avec les bibliothèques standard ont quelque chose de semblable (par exemple, dans. NET QueuxTTGt). Quoi qu'il en soit, j'étais moi-même la philosophie. tout est pardonné. Ndash Dan Tao Sep 22 10 at 12:44 Une moyenne mobile exponentiellement en décomposition peut être calculée à la main avec seulement la tendance si vous utilisez les valeurs appropriées. Voir fourmilab. chhackdiete4 pour une idée sur la façon de le faire rapidement avec un stylo et du papier si vous cherchez exponentiellement lissée moyenne mobile avec 10 lissage. Mais puisque vous avez un ordinateur, vous voulez probablement faire le décalage binaire plutôt que le décalage décimal) De cette façon, tout ce dont vous avez besoin est une variable pour votre valeur actuelle et une pour la moyenne. La moyenne suivante peut alors être calculée à partir de cela. Il ya une technique appelée une porte de gamme qui fonctionne bien avec des échantillons parasites faible occurrence. En supposant l'utilisation de l'une des techniques de filtrage mentionnées ci-dessus (moyenne mobile, exponentielle), une fois que vous avez suffisamment d'historique (une constante de temps), vous pouvez tester le nouvel échantillon de données entrantes pour le caractère raisonnable avant d'être ajouté au calcul. Une certaine connaissance du taux de changement de signal maximal raisonnable est nécessaire. L'échantillon brut est comparé à la valeur lissée la plus récente et si la valeur absolue de cette différence est supérieure à la plage permise, cet échantillon est rejeté (ou remplacé par une certaine heuristique, par exemple une prédiction basée sur la différence de pente ou la tendance La valeur de prédiction à partir du double lissage exponentiel) a répondu Apr 30 16 à 6: 56 Est-il possible d'implémenter une moyenne mobile en C sans la nécessité d'une fenêtre d'échantillons Ive trouvé que je peux optimiser un peu, en choisissant une taille de fenêtre thats une puissance de Deux pour permettre le décalage bit au lieu de diviser, mais ne nécessitant pas un tampon serait bien. Existe-t-il un moyen d'exprimer un nouveau résultat de la moyenne mobile uniquement en fonction de l'ancien résultat et du nouvel échantillon Définir un exemple de moyenne mobile, à travers une fenêtre de 4 échantillons pour être: Ajouter un nouvel échantillon e: Une moyenne mobile peut être implémentée récursivement , Mais pour un calcul exact de la moyenne mobile, vous devez vous souvenir de l'échantillon d'entrée le plus ancien dans la somme (c'est-à-dire l'a dans votre exemple). Pour une longueur N moyenne mobile que vous calculez: où yn est le signal de sortie et xn est le signal d'entrée. Eq. (1) peut être écrit récursivement comme So Il faut toujours se souvenir de l'échantillon xn-N pour calculer (2). Comme l'a souligné Conrad Turner, vous pouvez utiliser une fenêtre exponentielle (infiniment longue) qui permet de calculer la sortie uniquement à partir de la sortie passée et de l'entrée courante: mais ce n'est pas une moyenne mobile standard (non pondérée), mais une valeur exponentielle (Au moins en théorie) vous n'oubliez jamais rien (les poids sont de plus en plus petits pour les échantillons loin dans le passé). J'ai mis en œuvre une moyenne mobile sans mémoire élément individuel pour un programme de suivi GPS que j'ai écrit. Je commence par 1 échantillon et diviser par 1 pour obtenir le courant avg. J'ajoute ensuite un autre échantillon et divise par 2 la valeur actuelle. Cela continue jusqu'à ce que j'arrive à la longueur de la moyenne. Chaque fois par la suite, j'ajoute dans le nouvel échantillon, obtenez la moyenne et retirez cette moyenne du total. Je ne suis pas un mathématicien, mais cela semblait être une bonne façon de le faire. J'ai pensé que cela transformerait l'estomac d'un vrai mec de maths, mais il s'avère que c'est l'un des moyens acceptés de le faire. Et ça marche bien. Rappelez-vous juste que plus votre longueur est plus lente, il suit ce que vous voulez suivre. Cela peut ne pas importe la plupart du temps, mais en suivant les satellites, si vous êtes lent, le sentier pourrait être loin de la position réelle et il sera mauvais. Vous pourriez avoir un écart entre le sat et les points de fuite. J'ai choisi une longueur de 15 mise à jour 6 fois par minute pour obtenir un lissage adéquat et ne pas trop loin de la position réelle sat avec les points de sentier lissée. Répondu 16 nov 16 à 23:03 initialiser total 0, count0 (chaque fois que vous voyez une nouvelle valeur Puis une entrée (scanf), un add totalValeur, un incrément (comptage), une moyenne de division (totalcount) Toutes les entrées Pour calculer la moyenne sur les seules 4 dernières entrées, il faudrait 4 variables d'entrée, peut-être copier chaque entrée à une variable d'entrée plus ancienne, puis calculer la nouvelle moyenne mobile comme somme des 4 variables d'entrée, divisée par 4 Bon si toutes les entrées étaient positives pour rendre le calcul moyen répondu Feb 3 15 à 4:06 Cela va effectivement calculer la moyenne totale et PAS la moyenne mobile. 3 15 at 13:53 Votre réponse 2017 Stack Exchange, Inc Je sais que cela est réalisable avec boost comme par: Mais je voudrais vraiment éviter d'utiliser boost. Je suis googlé et ne trouve pas d'exemples appropriés ou lisibles. Moyenne mobile d'un flux continu d'un flux de nombres à virgule flottante en utilisant les plus récents numéros 1000 comme échantillon de données. Quel est le moyen le plus simple pour atteindre ce que j'ai expérimenté avec l'aide d'un tableau circulaire, moyenne mobile exponentielle et une moyenne mobile plus simple et a constaté que les résultats de la matrice circulaire convenait mieux à mes besoins. Si vos besoins sont simples, vous pouvez simplement essayer d'utiliser une moyenne mobile exponentielle. Autrement dit, vous créez une variable d'accumulateur, et comme votre code regarde chaque échantillon, le code met à jour l'accumulateur avec la nouvelle valeur. Vous choisissez un alpha constant qui se situe entre 0 et 1, et calculez ceci: Il vous suffit de trouver une valeur de alpha où l'effet d'un échantillon donné ne dure que pour environ 1000 échantillons. Hmm, je ne suis pas sûr que ce soit approprié pour vous, maintenant que Ive mis ici. Le problème est que 1000 est une fenêtre assez longue pour une moyenne mobile exponentielle Im pas sûr il ya un alpha qui serait la propagation de la moyenne sur les 1000 derniers chiffres, sans underflow dans le calcul en virgule flottante. Mais si vous voulez une moyenne plus petite, comme 30 nombres ou ainsi, c'est une manière très facile et rapide de le faire. A répondu 12 juin à 4:44 1 sur votre poste. La moyenne mobile exponentielle peut permettre à l'alpha d'être variable. Ainsi, cela permet de calculer des moyennes de base de temps (par exemple, des octets par seconde). Si le temps écoulé depuis la dernière mise à jour de l'accumulateur est supérieur à 1 seconde, laissez alpha be 1.0. Sinon, vous pouvez laisser alpha be (usecs depuis la dernière mise à jour1000000). Ndash jxh 12 juin à 6:21 Je veux essentiellement suivre la moyenne mobile d'un flux continu d'un flux de nombres à virgule flottante en utilisant les plus récents numéros 1000 comme un échantillon de données. Notez que la mise à jour ci-dessous le total en tant qu'éléments comme addedreplaced, en évitant coûteux O (N) traversal pour calculer la somme - nécessaire pour la moyenne - sur demande. Le total est fait d'un paramètre différent de T par rapport au support, par ex. En utilisant un long long pour un total de 1000 s longs, un int pour char s, ou un flottant double au total. C'est un peu vicié en ce que les numsamples pourraient dépasser INTMAX - si vous vous inquiétez vous pourriez employer un unsigned long long. Ou utiliser un membre de données bool supplémentaire pour enregistrer quand le conteneur est rempli tout en cyclant numsamples autour du tableau (mieux renommé quelque chose d'inoffensif comme pos). Répondue 12 juin à 5:19 on suppose que l'opérateur quotvoid (échantillon T) est effectivement opérateur quotvoid (T échantillon) quot. Ndash oPless Jun 8 14 at 11:52 oPless ahhh. Bien repéré. En fait, je voulais qu'il soit vide opérateur () (T échantillon), mais bien sûr, vous pouvez utiliser n'importe quelle note que vous avez aimé. Correction, merci. Ndash Tony D Jun 8 14 à 14:27


No comments:

Post a Comment