Moving average algorithm c
É possível implementar uma média móvel em C sem a necessidade de uma janela de amostras Ive descobri que eu posso otimizar um pouco, escolhendo um tamanho de janela thats um poder de dois para permitir bit-shifting em vez de dividir, mas não necessitando Um buffer seria bom. Existe uma maneira de expressar um novo resultado da média móvel apenas como uma função do antigo resultado e da nova amostra Definir um exemplo de média móvel, através de uma janela de 4 amostras para ser: Adicionar nova amostra e: Uma média móvel pode ser implementada recursivamente , Mas para um cálculo exato da média móvel você deve se lembrar da amostra de entrada mais antiga na soma (ou seja, o a no seu exemplo). Para um comprimento N média móvel você calcula: onde yn é o sinal de saída e xn é o sinal de entrada. Eq. (1) pode ser escrito recursivamente como Então você sempre precisa lembrar a amostra xn-N para calcular (2). Como indicado por Conrad Turner, você pode usar uma janela exponencial (infinitamente longa), que permite calcular a saída somente da saída anterior e da entrada atual: mas esta não é uma média móvel padrão (não ponderada), mas uma média exponencial Ponderada média móvel, onde as amostras mais no passado obter um peso menor, mas (pelo menos em teoria) você nunca esquecer nada (os pesos apenas ficar menor e menor para amostras no passado). Inicialize total 0, count0 (cada vez que vê um novo valor) Então uma entrada (scanf), uma add totalnewValue, um incremento (count), uma divide average (total / count) Esta seria uma média móvel sobre todas as entradas Para calcular a média Sobre apenas as 4 últimas entradas, exigiria 4 variáveis de entrada, talvez copiando cada entrada para uma variável de entrada mais antiga, calculando a nova média móvel como a soma das 4 variáveis de entrada, dividida por 4 (desvio para a direita 2 seria bom se todas as entradas fossem Positivo para fazer o cálculo médio Estou tentando calcular a média móvel de um sinal. O valor do sinal (um duplo) é atualizado em tempos aleatórios. Eu estou procurando uma maneira eficiente para calcular a sua média ponderada em tempo sobre uma janela de tempo, em reais Eu poderia fazê-lo sozinho, mas é mais desafiador do que eu pensava. A maioria dos recursos que eu encontrei através da internet estão calculando média móvel de sinal periódico, mas atualizações de minas em tempo aleatório. Alguém sabe bons recursos para que o Truque é o seguinte: Você recebe atualizações em tempos aleatórios através de atualização vazia (tempo int, valor float). 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 na computação. Se isso acontecer em tempo real, você pode solicitar que o sistema operacional faça uma chamada para um método void dropoffoldestupdate (int time) para ser chamado no momento N Se esta é uma simulação, você não pode obter ajuda do sistema operacional e você precisa Faça-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 chamada de atualização e leitura, verifique se o argumento de tempo é maior que o cabeçalho da lista de alarmes. Embora seja maior você faz o processamento relacionado com o alarme (deixe cair a atualização mais antiga), remova a cabeça e verifique novamente até que todos os alarmes antes do tempo determinado sejam processados. Em seguida, faça a chamada de atualização. Até agora tenho assumido que é óbvio o que você faria para a computação real, mas vou elaborar apenas no caso. Eu suponho que você tem um método float read (tempo int) que você usa para ler os valores. O objetivo é tornar essa chamada o mais eficiente possível. Portanto, você não calcula a média móvel sempre 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 esse valor por um par de operações ponto flutuante para conta para a passagem do tempo desde a última atualização. (Isto é, um número constante de operações excepto para talvez processar uma lista de alarmes acumulados). Esperemos que isso seja claro - este deve ser um algoritmo bastante simples e bastante eficiente. 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á ineficaz na atualização incremental do valor para cada uma das atualizações que está caindo. Isso não é necessário, porque nós só nos preocupamos com a última atualização além da janela de tempo, então se houver uma maneira eficiente de deixar todas as atualizações antigas, isso ajudaria. Para fazer isso, podemos modificar o algoritmo para fazer uma busca binária de atualizações para encontrar a atualização mais recente antes da janela de tempo. Se houver relativamente poucas atualizações que precisam ser descartadas, então um pode atualizar incrementalmente o valor para cada atualização descartada. Mas se houver muitas atualizações que precisam ser descartadas, então um pode recalcular o valor do zero após deixar 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 explicar a passagem do tempo desde a última atualização. Cálculo inicial não incremental: então iterar sobre as atualizações relevantes por ordem crescente de tempo: movimentação (sum lastupdate timesincelastupdate) / windowlength. Agora, se exatamente uma atualização cair da janela, mas nenhuma nova atualização chegar, ajuste a soma como: (note que é priorupdate que tem seu timestamp modificado para iniciar o último início da janela). E se exatamente uma atualização entra na janela, mas nenhuma nova atualização cai, ajuste a soma como: Como deve ser óbvio, este é um esboço grosseiro, mas espero que ele mostra como você pode manter a média tal que é O (1) operações por atualização Sobre uma base amortizada. Mas observe otimização adicional no parágrafo anterior. Observe também as questões de estabilidade mencionadas em uma resposta mais antiga, o que significa que os erros de ponto flutuante podem se acumular em um grande número dessas operações incrementais, de modo que há uma divergência em relação ao resultado da computação completa que é significativa para a aplicação. Se uma aproximação é OK e há um tempo mínimo entre as amostras, você pode tentar super-amostragem. Tenha uma matriz que represente intervalos de tempo uniformemente espaçados que sejam mais curtos que o mínimo, e em cada período de tempo armazene a amostra mais recente que foi recebida. Quanto menor o intervalo, mais próxima será a média do valor real. O período não deve ser maior que a metade do mínimo ou há uma chance de faltar uma amostra. Respondeu Dec 15 11 at 18:12 respondeu Dec 15 11 at 22:38 Obrigado pela resposta. Uma melhoria que seria necessário para realmente quotcachequot o valor da média total para que don39t loop o tempo todo. Além disso, 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 correta. A inserção seria mais rápida do que no mapa. Ndash Arthur 16 dez às 8:55 Sim, você poderia armazenar em cache o valor de soma. Subtraia os valores das amostras que você apaga, adicione os valores das amostras inseridas. Além disso, sim, um dequeltpairltSample, Dategtgt pode ser mais eficiente. Eu escolhi o mapa para a legibilidade, ea facilidade de invocar map :: upperbound. Como sempre, escreva o código correto primeiro e, em seguida, perfile e mude as alterações incrementais. Ndash Rob Dec 16 11 at 15:00 Nota: Aparentemente esta não é a maneira de abordar isso. Deixando aqui para referência sobre o que está errado com esta abordagem. Verifique os comentários. UPDATED - com base no comentário Olis. Não tenho certeza sobre a instabilidade que ele está falando embora. Use um mapa ordenado de tempos de chegada contra valores. Na chegada de um valor adicione a hora de chegada ao mapa ordenado junto com seu valor e atualize a média móvel. Aviso este é pseudo-código: Lá. Não totalmente desenvolvido, mas você começa a idéia. Coisas a observar. Como eu disse o acima é pseudo código. Você precisará escolher um mapa apropriado. Não remova os pares à medida que você iterar através como você irá invalidar o iterador e terá que começar novamente. Veja Olis comentário abaixo também. Este trabalho não funciona: ele não leva em conta que proporção do comprimento da janela de cada valor existe para. Além disso, essa abordagem de adição e subtração é apenas estável para tipos inteiros, não para flutuadores. Ndash Oliver Charlesworth Dec 15 11 em 12:29 OliCharlesworth - desculpe eu perdi alguns pontos-chave na descrição (duplo e ponderada em tempo). Eu vou atualizar. Obrigado. Ndash Dennis Dec 15 11 at 12:33 A ponderação de tempo é ainda outro problema. Mas isso não é o que eu estou falando. Eu estava me 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é que um novo valor entre. MA Como um exemplo de SMA, considere um título com os seguintes preços de fechamento em 15 dias: Semana 1 (5 dias) 20, 22, 24, 25, 23 Semana 2 (5 dias) 26, 28, 26, 29, 27 Semana 3 (5 dias) 28, 30, 27, 29, 28 Uma MA de 10 dias seria a média dos preços de fechamento para os primeiros 10 dias como a primeira Ponto de dados. O ponto de dados seguinte iria cair o preço mais antigo, adicionar o preço no dia 11 e tomar a média, e assim por diante, como mostrado abaixo. Conforme mencionado anteriormente, MAs atraso ação preço atual, porque eles são baseados em preços passados quanto maior for o período de tempo para o MA, maior o atraso. Assim, um MA de 200 dias terá um grau muito maior de atraso do que um MA de 20 dias porque contém preços nos últimos 200 dias. A duração da MA a ser utilizada depende dos objetivos de negociação, com MAs mais curtos usados para negociação de curto prazo e MAs de longo prazo mais adequados para investidores de longo prazo. O MA de 200 dias é amplamente seguido por investidores e comerciantes, com quebras acima e abaixo desta média móvel considerada como sinais comerciais importantes. MAs também transmitir sinais comerciais importantes por conta própria, ou quando duas médias se cruzam. Um aumento MA indica que a segurança está em uma tendência de alta. Enquanto um declínio MA indica que ele está em uma tendência de baixa. Da mesma forma, o impulso ascendente é confirmado com um crossover de alta. Que ocorre quando um MA de curto prazo cruza acima de um MA de longo prazo. Um movimento descendente é confirmado com um crossover de baixa, que ocorre quando um MA de curto prazo cruza abaixo de um MA. A mais longo prazo. Olhar mais atento no algoritmo de média móvel avançado do CODAS A média móvel versátil no algoritmo CODAS avançado filtra o ruído da forma de onda, Elimina a deriva da linha de base. A média móvel é uma técnica matemática simples usada principalmente para eliminar aberrações e revelar a tendência real em uma coleção de pontos de dados. Você pode estar familiarizado com ele a partir da média de dados ruidosos em uma experiência de física de caloiro, ou de rastrear o valor de um investimento. Você pode não saber que a média móvel é também um protótipo do filtro de resposta de impulso finito, o tipo mais comum de filtro usado em instrumentação computadorizada. Nos casos em que uma dada forma de onda está cheia de ruído, onde uma média necessita de ser extraída de um sinal periódico, ou quando uma linha de base lentamente à deriva necessita de ser eliminada a partir de um sinal de frequência mais elevada, um filtro de média móvel pode ser aplicado para atingir o desejado resultado. O algoritmo de média móvel do Advanced CODAS oferece este tipo de desempenho de filtragem de forma de onda. Advanced CODAS é um pacote de software de análise que opera em arquivos de dados de forma de onda existentes criados pela primeira geração de pacotes de aquisição de dados WinDaq ou de segunda geração do WinDaq. Além do algoritmo de média móvel, o Advanced CODAS também inclui um utilitário de geração de relatórios e rotinas de software para integração de formas de onda, diferenciação, captação de pico e vale, rectificação e operações aritméticas. Teoria do Filtro de Movimentação Média O algoritmo de média móvel DATAQ Instruments permite uma grande flexibilidade nas aplicações de filtragem de formas de onda. Ele pode ser usado como um filtro passa-baixa para atenuar o ruído inerente em muitos tipos de formas de onda, ou como um filtro passa-alta para eliminar uma linha de base derivada de um sinal de freqüência mais alta. O procedimento usado pelo algoritmo para determinar a quantidade de filtragem envolve o uso de um fator de suavização. Este fator de suavização, controlado por você através do software, pode ser aumentado ou diminuído para especificar o número de pontos de dados de forma de onda real ou amostras que a média móvel se espalhará. Qualquer forma de onda periódica pode ser pensada como uma seqüência longa ou coleção de pontos de dados. O algoritmo realiza uma média móvel tomando dois ou mais desses pontos de dados da forma de onda adquirida, somando-os, dividindo sua soma pelo número total de pontos de dados adicionados, substituindo o primeiro ponto de dados da forma de onda pela média apenas calculada e Repetindo as etapas com o segundo, terceiro e assim por diante pontos de dados até o final dos dados é alcançado. O resultado é uma segunda forma de onda gerada, constituída pelos dados médios e com o mesmo número de pontos que a forma de onda original. Figura 1 8212 Qualquer forma de onda periódica pode ser considerada como uma seqüência longa ou coleção de pontos de dados. Na ilustração acima, pontos de dados de forma de onda consecutivos são representados por quotyquot para ilustrar como a média móvel é calculada. Neste caso, um fator de suavização de três foi aplicado, o que significa que três pontos de dados consecutivos da forma de onda original são adicionados, sua soma dividida por três, e então este quociente é plotado como o primeiro ponto de dados de uma forma de onda gerada. O processo se repete com o segundo, terceiro e assim por diante pontos de dados da forma de onda original até o final dos dados é atingido. Uma técnica de quotfeatheringquot especial faz a média dos pontos de dados iniciais e finais da forma de onda original para garantir que a forma de onda gerada contenha o mesmo número de pontos de dados que o original. A Figura 1 ilustra como o algoritmo de média móvel é aplicado a pontos de dados de forma de onda (que são representados por y). A ilustração apresenta um fator de suavização de 3, o que significa que o valor médio (representado por a) será calculado sobre 3 valores de dados de forma de onda consecutivos. Observe a sobreposição que existe nos cálculos da média móvel. É essa técnica de sobreposição, juntamente com um tratamento especial de ponto inicial e final que gera o mesmo número de pontos de dados na forma de onda média como existia no original. A forma como o algoritmo calcula uma média móvel merece um olhar mais atento e pode ser ilustrado com um exemplo. Digamos que temos sido em uma dieta de duas semanas e queremos calcular o nosso peso médio nos últimos 7 dias. Nós somamos nosso peso no dia 7 com nosso peso nos dias 8, 9, 10, 11, 12 e 13 e depois multiplicamos por 1/7. Para formalizar o processo, isto pode ser expresso como: a (7) 1/7 (y (7) y (8) y (9) y (13)) Esta equação pode ser mais generalizada. A média móvel de uma forma de onda pode ser calculada por: Onde: um valor médio n posição de ponto de dados fator de suavização y valor de ponto de dados real Figura 2 8212 A forma de onda de saída da célula de carga mostrada original e não filtrada no canal superior e como um ponto 11 Movendo a forma de onda média no canal inferior. O ruído que aparece na forma de onda original foi devido às intensas vibrações criadas pela prensa durante a operação de embalagem. A chave para esta flexibilidade de algoritmos é a sua ampla gama de fatores de suavização selecionáveis (de 2 - 1.000). O factor de suavização determina quantos pontos de dados ou amostras reais serão calculados. Especificar qualquer fator de suavização positivo simula um filtro passa-baixa enquanto especifica um fator de suavização negativo simula um filtro passa-alta. Dado o valor absoluto do fator de suavização, valores maiores aplicam maiores restrições de suavização na forma de onda resultante e, inversamente, valores menores aplicam menos suavização. Com a aplicação do fator de suavização apropriado, o algoritmo também pode ser usado para extrair o valor médio de uma dada forma de onda periódica. Um fator de alisamento positivo mais alto é tipicamente aplicado para gerar valores de forma de onda média. Aplicando o Algoritmo de Média Móvel Uma característica saliente do algoritmo de média móvel é que ele pode ser aplicado muitas vezes à mesma forma de onda se necessário para obter o resultado de filtragem desejado. Filtragem de forma de onda é um exercício muito subjetivo. O que pode ser uma forma de onda devidamente filtrada para um usuário pode ser inaceitavelmente ruidoso para outro. Só você pode avaliar se o número de pontos médios selecionados foi muito alto, muito baixo ou apenas correto. A flexibilidade do algoritmo permite ajustar o fator de suavização e fazer outra passagem através do algoritmo quando resultados satisfatórios não são alcançados com a tentativa inicial. A aplicação e as capacidades do algoritmo de média móvel podem ser melhor ilustradas pelos exemplos seguintes. Figura 3 8212 A forma de onda ECG mostrada original e não filtrada no canal superior e como uma forma de onda média movimentada de 97 pontos no canal inferior. Observe a ausência de deriva de linha de base no canal inferior. Ambas as formas de onda são mostradas em uma condição comprimida para fins de apresentação. Uma Aplicação de Redução de Ruído Nos casos em que uma dada forma de onda está cheia de ruído, o filtro de média móvel pode ser aplicado para suprimir o ruído e produzir uma imagem mais clara da forma de onda. Por exemplo, um cliente CODAS avançado estava usando uma prensa e uma célula de carga em uma operação de empacotamento. O seu produto era para ser comprimido até um nível predeterminado (monitorizado pela célula de carga) para reduzir o tamanho da embalagem necessária para conter o produto. Por razões de controle de qualidade, eles decidiram monitorar a operação da prensa com instrumentação. Um problema inesperado apareceu quando começaram a ver a saída de células de carga em tempo real. Uma vez que a máquina de prensa vibrou consideravelmente durante a operação, a forma de onda de saída das células de carga era difícil de discernir porque continha uma grande quantidade de ruído devido à vibração como mostrado no canal superior da Figura 2. Este ruído foi eliminado gerando um canal com média de movimento de 11 pontos como mostrado no canal inferior da Figura 2. O resultado foi uma imagem muito mais clara da saída das células de carga. Uma aplicação para eliminar a deriva da linha de base Nos casos em que uma linha de base lentamente derivada precisa ser removida de um sinal de freqüência mais alta, o filtro de média móvel pode ser aplicado para eliminar a linha de base da derivação. Por exemplo, uma forma de onda ECG exibe tipicamente algum grau de desvio de linha de base tal como pode ser visto no canal superior da Figura 3. Esta deriva de linha de base pode ser eliminada sem alterar ou perturbar as características da forma de onda como mostrado no canal inferior da Figura 3. Isto é conseguido aplicando um factor de suavização de valor negativo apropriado durante o cálculo da média móvel. O fator de suavização apropriado é determinado dividindo um período de forma de onda (em segundos) pelo intervalo de amostra de canais. O intervalo de amostra de canais é simplesmente o recíproco da taxa de amostragem de canais e é exibido convenientemente no menu de utilitário de média móvel. O período de forma de onda é facilmente determinado a partir da tela de exibição, posicionando o cursor em um ponto conveniente na forma de onda, definindo um marcador de tempo e, em seguida, movendo o cursor um ciclo completo longe do marcador de tempo exibido. A diferença de tempo entre cursor e marcador de tempo é um período de forma de onda e é exibido na parte inferior da tela em segundos. Em nosso exemplo de ECG, a forma de onda possuía um intervalo de amostra de canal de 0,004 segundos (obtido a partir do menu de utilidade de média móvel) e um período de forma de onda foi medido para espaçar 0,388 segundos. Dividindo o período de forma de onda pelo intervalo de amostra de canais nos deu um fator de suavização de 97. Como é a deriva de linha de base que estamos interessados em eliminar, aplicamos um fator de suavização negativo (-97) ao algoritmo de média móvel. Isto, com efeito, subtraiu o resultado médio móvel do sinal original da forma de onda, que eliminou a deriva da linha de base sem alterar a informação da forma de onda. Quaisquer que sejam as aplicações, a razão universal para a aplicação de um filtro de média móvel é quotsmooth outquot as aberrações altas e baixas e revelam um valor de forma de onda intermediário mais representativo. Ao fazer isso, o software não deve comprometer outros recursos da forma de onda original no processo de geração de uma forma de onda média movimentada. Por exemplo, o software deve ajustar automaticamente as informações de calibração associadas ao arquivo de dados original, de modo que a forma de onda média móvel esteja nas unidades de engenharia apropriadas quando geradas. Todas as leituras nas figuras foram feitas usando o software WinDaq Data AcquisitionMoving Average Este exemplo ensina como calcular a média móvel de uma série temporal no Excel. Um avanço em movimento é usado para suavizar irregularidades (picos e vales) para reconhecer facilmente as tendências. 1. Primeiro, vamos dar uma olhada em nossa série de tempo. 2. No separador Dados, clique em Análise de dados. Observação: não é possível encontrar o botão Análise de dados Clique aqui para carregar o suplemento do Analysis ToolPak. 3. Selecione Média móvel e clique em OK. 4. Clique na caixa Input Range e selecione o intervalo B2: M2. 5. Clique na caixa Intervalo e escreva 6. 6. Clique na caixa Output Range e seleccione a célula B3. 8. Faça um gráfico destes valores. Explicação: porque definimos o intervalo como 6, a média móvel é a média dos 5 pontos de dados anteriores eo ponto de dados atual. Como resultado, os picos e vales são suavizados. O gráfico mostra uma tendência crescente. O Excel não consegue calcular a média móvel para os primeiros 5 pontos de dados porque não existem pontos de dados anteriores suficientes. 9. Repita os passos 2 a 8 para intervalo 2 e intervalo 4. Conclusão: Quanto maior o intervalo, mais os picos e vales são suavizados. Quanto menor o intervalo, mais próximas as médias móveis são para os pontos de dados reais. Gosta deste site gratuito Por favor, partilhe esta página no Google
Comments
Post a Comment