Monday 24 July 2017

Média Ponderada Em Movimento C ++


Estou tentando calcular a média móvel de um sinal O valor do sinal de um duplo é atualizado em tempos aleatórios Eu estou procurando uma forma eficiente de calcular a média ponderada tempo s sobre uma janela de tempo, em tempo real eu poderia fazê-lo meu auto, Mas é mais desafiador do que eu pensei. A maioria dos recursos que eu encontrei na internet estão calculando média móvel de sinal periódico, mas as atualizações de minas em tempo aleatório. Do alguém sabe bons recursos para o truque that. The é o seguinte Você começa atualizações Em tempos aleatórios através de void update int time, float value No entanto, você também precisa acompanhar quando uma atualização cai fora da janela de tempo, então você define um alarme que chamado no tempo N que remove a atualização anterior de ser sempre considerado novamente no cálculo. Se isso acontece em tempo real, você pode solicitar ao sistema operacional para fazer uma chamada para um método void dropoffoldestupdate int tempo para ser chamado no momento N. Se esta é uma simulação, você não pode obter ajuda do sistema operacional e você precisa D O manualmente Em uma simulação você chamaria métodos com o tempo fornecido como um argumento que não se correlaciona com o tempo real No entanto, uma suposição razoável é que as chamadas são garantidas de tal forma que os argumentos de tempo estão aumentando Neste caso, você precisa Manter uma lista ordenada de valores de tempo de alarme, e para cada atualização e ler chamar você verificar se o argumento de tempo é maior do que o chefe da lista de alarme Enquanto é maior você faz o processamento de alarme relacionados cair a atualização mais antiga, E verifique novamente até que todos os alarmes antes do tempo determinado são processados ​​Então faça a atualização call. I tem até agora assumiu que é óbvio o que você faria para a computação real, mas vou elaborar apenas no caso de eu assumir que você tem um método float Ler int tempo que você usa para ler os valores O objetivo é fazer essa chamada tão eficiente quanto possível Portanto, você não calcular a média móvel cada vez que o método de leitura é chamado Em vez disso você precompute o valor a partir da última atualização Ou o último alarme, e ajustar este valor por um par de operações de ponto flutuante para explicar a passagem do tempo desde a última atualização ie um número constante de operações, exceto para talvez o processamento de uma lista de alarmes empilhados up. Hopefully isso é claro - Este deve ser um algoritmo bastante simples e bastante eficiente. Uma otimização adicional um dos problemas restantes é se um grande número de atualizações acontecer dentro da janela de tempo, então há um longo tempo para que não há nem lê nem atualizações e, em seguida, uma leitura Ou atualização vem junto Neste caso, o algoritmo acima será ineficiente na atualização incremental do valor para cada uma das atualizações que está caindo Isso não é necessário porque só nos preocupamos com a última atualização além da janela de tempo assim se houver uma maneira Para lançar eficientemente todas as atualizações mais antigas, seria útil. Para fazer isso, podemos modificar o algoritmo para fazer uma pesquisa binária de atualizações para encontrar a atualização mais recente antes da janela de tempo Se houver relativamente poucos As atualizações que precisa ser descartado, então, um pode atualizar incrementalmente o valor para cada queda de atualização. Mas se houver muitas atualizações que precisam ser descartados, então um pode recomputer o valor do zero após deixar cair fora as atualizações antigas. Apêndice sobre Computação Incremental Eu deveria esclarecer O que eu quero dizer por computação incremental acima na sentença tweak este valor por um par de operações de ponto flutuante para contabilizar a passagem de tempo desde a última atualização inicial não incremental computation. then iterar sobre relevantesupdates em ordem crescente time. movingaverage sum lastupdate Timesincelastupdate windowlength. Now se exatamente uma atualização cai fora da janela, mas não novas atualizações chegar, ajustar a soma como. Note que é priorupdate que tem o seu timestamp modificado para iniciar o início da última janela E se exatamente uma atualização entra na janela, mas não novas atualizações cair, ajustar soma as. As deve ser óbvio, este é um esboço, mas espero que mostre como você Pode manter a média de tal forma que é O 1 operações por atualização em uma base amortizada Mas note otimização adicional no parágrafo anterior Observe também as questões de estabilidade aludidas em uma resposta mais antiga, o que significa que os erros de ponto flutuante podem acumular sobre um grande número de tais incremental Operações tais que há uma divergência do resultado do cálculo completo que é significativo para o aplicativo. Se uma aproximação é OK e há um mínimo de tempo entre as amostras, você poderia tentar super-amostragem tem uma matriz que representa intervalos de tempo uniformemente espaçados que São mais curtos do que o mínimo, e em cada período de tempo armazenar a última amostra que foi recebida Quanto mais curto o intervalo, mais próxima a média será para o verdadeiro valor E O período não deve ser maior do que a metade do mínimo ou há uma chance de faltar uma amostra. Respondido Dec 15 11 at 18 12.resposta Dec 15 11 at 22 38.Thanks para a resposta Uma melhoria que seria necessário para realmente Armazenar em cache o valor da média total assim que nós don t loop o tempo todo Também, pode ser um ponto menor, mas não seria mais eficiente usar um deque ou uma lista para armazenar o valor, uma vez que assumimos que a atualização virá Na ordem certa Inserção seria mais rápida do que no mapa Arthur Dec 16 11 at 8 55. Sim, você poderia armazenar em cache o valor da soma Subtrair os valores das amostras que você apagar, adicione os valores das amostras que você inserir Também, sim, Um par deque Exemplo, Data pode ser mais eficiente Eu escolhi o mapa para a legibilidade, ea facilidade de invocar o mapa upperbound Como sempre, escreva o código correto primeiro, então perfil e medida mudanças incrementais Rob Dec 16 11 at 15 00.Note Aparentemente isto não é A maneira de abordar esta Deixando-o aqui para referência sobre o que está errado com esta ap Proach Verifique os comentários. UPDATED - com base no comentário Oli s não tenho certeza sobre a instabilidade de que ele está falando though. Use um mapa ordenado de tempos de chegada contra valores Após a chegada de um valor adicionar a hora de chegada para o mapa ordenado junto com it s Valor e atualizar o average. warning em movimento isso é pseudo-code. There Não totalmente expandida, mas você começa a idéia. Coisas a nota Como eu disse o acima é pseudo código Você ll precisa escolher um mapa apropriado Don t remover os pares como Você iterar através de como você vai invalidar o iterador e terá que começar de novo Veja Oli comentário s abaixo também. Respondido 15 de dezembro 11 em 12 22. Isso doesn t trabalho não leva em conta que proporção do comprimento da janela de cada valor existe Para Além disso, esta abordagem de adição e subtração é apenas estável para tipos inteiros, não flutuadores Oliver Charlesworth 15 de dezembro de 11 em 12 29. OliCharlesworth - desculpe eu perdi alguns pontos-chave na descrição dupla e ponderada no tempo vou atualizar Thanks Dennis Dec 15 11 at 12 33. A ponderação de tempo é mais um problema Mas isso não é o que eu estou falando Eu estava se referindo ao fato de que quando um novo valor entra pela primeira vez na janela de tempo, sua contribuição para a média é mínima Sua contribuição continua a aumentar até um Novo valor entra Oliver Charlesworth 15 de dezembro de 11 em 12 35.Eu sei que isso é possível com impulso como per. But eu realmente gostaria de evitar usar impulso eu tenho googled e não encontrei qualquer exemplos adequados ou legível. Basicamente eu quero acompanhar o movimento Média de um fluxo contínuo de um fluxo de números de ponto flutuante usando os números mais recentes de 1000 como uma amostra de dados. Qual é a maneira mais fácil de conseguir isso. Eu experimentei usando uma matriz circular, média móvel exponencial e uma média móvel mais simples e Descobriu que os resultados da matriz circular adequado às minhas necessidades best. asked 12 de junho 12 às 4 38.If suas necessidades são simples, você pode apenas tentar usar uma média móvel exponencial. Put simplesmente, você faz uma variável de acumulador, e como o seu bacalhau E olha para cada amostra, o código atualiza o acumulador com o novo valor Você escolhe uma alfa constante que está entre 0 e 1, e calcula isso. Você só precisa encontrar um valor de alfa onde o efeito de uma determinada amostra só dura Cerca de 1000 amostras. Hmm, eu realmente não tenho certeza que isso é adequado para você, agora que eu colocá-lo aqui O problema é que 1000 é uma janela muito longa para uma média móvel exponencial Eu não tenho certeza se há um alfa que se espalharia A média dos últimos 1000 números, sem underflow no cálculo do ponto flutuante Mas se você queria uma média menor, como 30 números ou assim, esta é uma maneira muito fácil e rápida de fazê-lo. Em sua postagem A média móvel exponencial pode permitir que o alfa seja variável Então isso permite que ele seja usado para calcular médias de base de tempo, por exemplo, bytes por segundo Se o tempo desde a última atualização do acumulador for superior a 1 segundo, , Você pode deixar o alfa ser usecs desde a última atualização 1000000 jxh Jun 12 12 at 6 21.Basicamente eu quero acompanhar a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os mais recentes números 1000 como uma amostra de dados. Note que o abaixo atualiza o total como elementos substituídos, Evitando costoso ON traversal para calcular a soma - necessária para a média - on demand. Total é feito um parâmetro diferente de T para apoiar, por exemplo, usando um longo longo quando totalizando 1000 long s, um int para char s, ou um duplo para total float S. This é um pouco falho em que numsamples poderia passar INTMAX - se você se importa que você poderia usar um unsigned long long ou usar um extra bool membro de dados para gravar quando o recipiente é preenchido primeiro enquanto ciclismo numsamples em torno da matriz melhor então renomeado algo Inócuo como pos. answered 12 de junho 12 em 5 19.um pressupõe que o operador vazio T amostra é, na verdade, o operador vazio T amostra oPless junho 8 14 em 11 52. oPless ahhh bem manchado na verdade eu quis dizer para ser void operador T amostra, mas de Claro que você poderia usar whate Ver a notação que você gostou Will fix, graças Tony D Jun 8 14 em 14 27.É possível implementar uma média móvel em C sem a necessidade de uma janela de samples. I ve encontrei que eu posso otimizar um pouco, escolhendo uma janela Tamanho que sa potência de dois para permitir bit-shifting em vez de dividir, mas não precisando de um buffer seria bom Existe uma maneira de expressar um novo média móvel resultado apenas como uma função do antigo resultado e da nova amostra. Define um Exemplo de média móvel, através de uma janela de 4 amostras para ser. Add nova amostra eA média móvel pode ser implementada recursivamente, mas para um cálculo exato da média móvel você tem que lembrar a mais antiga amostra de entrada na soma, ou seja, o a no seu exemplo Para um comprimento N média móvel você computa. where yn é o sinal de saída e xn é o sinal de entrada Eq 1 pode ser escrito recursivamente as. So você sempre precisa lembrar a amostra x nN para calcular 2.As apontado por Conrad Turner, você pode usar uma janela exponencial infinitamente longa , O que permite calcular a saída somente da saída anterior e da entrada atual. Mas isso não é uma média móvel não ponderada padrão, mas uma média móvel ponderada exponencialmente, onde as amostras no passado têm um peso menor, mas pelo menos em Teoria que você nunca esquece nada os pesos apenas ficam menores e menores para amostras longe no passado. Eu implementei uma média móvel sem memória item individual para um programa de rastreamento GPS que eu escrevi. Começo com 1 amostra e dividir por 1 para obter o avg atual. Em seguida, adicionar outra amostra e dividir por 2 para o atual avg. This continua até chegar ao comprimento da média. Cada vez depois, eu adicionar na nova amostra, obter a média e remover essa média do total. Eu não sou um matemático, mas isso parecia ser uma boa maneira de fazê-lo eu pensei que iria transformar o estômago de um cara de matemática real, mas ele se torna é uma das formas aceitas de fazê-lo E funciona bem Basta lembrar que o Mais alto seu comprimento o mais lento ele Está seguindo o que você quer seguir Isso pode não importar a maior parte do tempo, mas quando os satélites seguintes, se você é lento, a trilha poderia estar longe da posição real e ficará ruim Você poderia ter uma lacuna entre o sat eo trailing Dots Eu escolhi um comprimento de 15 atualizado 6 vezes por minuto para obter suavização adequada e não ficar muito longe da posição real sentado com a trilha alisada dots. answered 16 de novembro de 16 às 23 03.initialize total 0, contagem de 0 cada vez vendo um Novo valor. Then um scanf de entrada, um add newValue total, uma contagem de incremento, uma contagem total média de divisão. Esta seria uma média móvel sobre todas as entradas. Para calcular a média apenas sobre as últimas 4 entradas, exigiria 4 variáveis ​​de entrada, talvez Copiando cada entrada para uma variável de entrada mais antiga, então calculando a nova média móvel como a soma das 4 variáveis ​​de entrada, dividida por 4 a direita 2 seria bom se todas as entradas fossem positivas para fazer o cálculo médio. Isso vai realmente ca Lculate a média total e não a média móvel Como contagem fica maior o impacto de qualquer nova amostra de entrada torna-se muito pequeno Hilmar fevereiro 3 15 em 13 53.Your Answer.2017 Stack Exchange, Inc.

No comments:

Post a Comment