Monday 17 July 2017

Embutido C Mover Média


É possível implementar uma média móvel em C sem a necessidade de uma janela de amostras. Achei que posso otimizar um pouco, escolhendo um tamanho de janela que seja um poder de dois para permitir a mudança de bits em vez de dividir, mas não precisar Um buffer seria bom. Existe uma maneira de expressar um novo resultado de média móvel apenas como função do resultado antigo e da nova amostra. Definir um exemplo de média móvel, em uma janela de 4 amostras para ser: Adicionar nova amostra e: Uma média móvel pode ser implementada de forma recursiva , Mas para uma computação exata da média móvel você deve lembrar a amostra de entrada mais antiga na soma (ou seja, 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 de forma recursiva, então você sempre precisa se lembrar da amostra xn-N para calcular (2). Conforme indicado por Conrad Turner, você pode usar uma janela exponencial (infinitamente longa) em vez disso, o que permite calcular a saída apenas da saída passada e da entrada atual: mas esta não é uma média móvel padrão (não ponderada), mas exponencialmente Média móvel ponderada, onde as amostras no passado obtêm um peso menor, mas (pelo menos em teoria) você nunca esquece nada (os pesos ficam menores e menores para amostras no passado). Eu implementei uma média móvel sem memória de item individual para um programa de rastreamento de GPS que escrevi. Comece com 1 amostra e divida em 1 para obter o valor médio atual. Em seguida, adicione uma amostra e divida em 2 para a média atual. Isso continua até chegar ao comprimento da média. Cada vez, adiciono na nova amostra, obtenho a média e retire essa média do total. Eu não sou um matemático, mas isso pareceu uma boa maneira de fazê-lo. Achei que isso tornaria o estômago de um verdadeiro matemático, mas, parece ser uma das formas aceitas de fazê-lo. E funciona bem. Basta lembrar que, quanto mais alto for seu comprimento, mais lento seguirá o que deseja seguir. Isso pode não ser importante na maioria das vezes, mas ao seguir os satélites, se você estiver lento, a trilha pode estar longe da posição atual e parecerá ruim. Você poderia ter uma lacuna entre o Sáb e os pontos de fuga. Eu escolhi um comprimento de 15 atualizado 6 vezes por minuto para obter um alisamento adequado e não chegar muito longe da posição real de SAT com os pontos de trilhos alisados. Respondeu 16 de novembro 16 às 23:03 inicialize o total 0, count0 (cada vez que vê um novo valor) Então uma entrada (scanf), um add totalnewValue, um incremento (contagem), uma média de divisão (quantidade total) Esta seria uma média móvel em relação a Todas as entradas Para calcular a média apenas nas últimas 4 entradas, seria necessário 4 variáveis ​​de entrada, talvez copiando cada entrada para uma variável de entrada mais antiga e, em seguida, calculando a nova média móvel. Como soma das 4 variáveis ​​de entrada, divididas por 4 (o turno direito 2 seria Bom, se todas as entradas fossem positivas para que o cálculo médio fosse respondido em 3 de fevereiro de 15 às 4:06 Isso realmente calculará a média total e NÃO a média móvel. À medida que a contagem aumenta, o impacto de qualquer nova amostra de entrada se torna ndash extremamente lento Hilmar Feb 3 15 às 13:53 Sua resposta 2017 Stack Exchange, Inc Eu sei que isso é realizável com o aumento de acordo com: Mas eu realmente gostaria de evitar o uso de boost. Eu procurei e não encontrei nenhum exemplo adequado ou legível. Basicamente eu quero acompanhar o Em movimento Média de um fluxo contínuo de um fluxo de números de ponto flutuante usando os 1000 números mais recentes como amostra de dados. Qual é a maneira mais fácil de conseguir isso, experimentei usar uma matriz circular, uma média móvel exponencial e uma média móvel mais simples e descobriu que os resultados da matriz circular correspondiam melhor às minhas necessidades. 12 de junho 12 às 4:38 Se suas necessidades são simples, você pode tentar usar uma média móvel exponencial. Simplificando, você faz uma variável de acumulador e, conforme seu código examina cada amostra, o código atualiza o acumulador com o novo valor. Você escolhe um 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 dura apenas cerca de 1000 amostras. Hmmm, na verdade, não tenho certeza de que isso é adequado para você, agora que eu coloquei aqui. O problema é que 1000 é uma janela bastante longa para uma média móvel exponencial. Não tenho certeza se houver um alfa que espalhe a média nos últimos 1000 números, sem fluxo inferior no cálculo do ponto flutuante. Mas se você quisesse uma média menor, como 30 números ou mais, esta é uma maneira muito fácil e rápida de fazê-lo. Respondeu 12 de junho 12 às 4:44 1 na 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 base de tempo (por exemplo, bytes por segundo). Se o tempo decorrido desde a última atualização do acumulador for superior a 1 segundo, você deixa alfa ser 1.0. Caso contrário, você pode deixar o alfa ser (usecs desde a última atualização1000000). Ndash jxh 12 de junho 12 às 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 1000 números mais recentes como amostra de dados. Observe que as atualizações abaixo atualizam o total como elementos como adicionados substituídos, evitando a passagem O (N) dispendiosa para calcular a soma - necessária para a demanda média. Total é feito um parâmetro diferente de T para suportar, e. Usando um longo tempo quando totalizando 1000 long s, um int para char s, ou um duplo para float total s. Isso é um pouco falho em que numsamples poderia ultrapassar o INTMAX - se você se importar, você poderia usar um sinal não assinado por muito tempo. Ou use um membro adicional de dados do bool para gravar quando o recipiente é preenchido pela primeira vez ao andar de bicicleta numsamples em torno da matriz (o melhor que renomeou algo inócuo como pos). Respondeu 12 de junho 12 às 5:19 um assume que quotvoid operator (T sample) quot é realmente quotvoid operatorltlt (T sample) quot. Ndash oPless Jun 8 14 às 11:52 oPless ahhh. Bem visto. Na verdade, eu quis dizer que ele seria um operador vazio () (amostra T), mas é claro que você poderia usar qualquer notação que você gostasse. Vou consertar, obrigado. Ndash Tony D 8 de junho 14 às 14: 27Como outros já mencionaram, você deve considerar um filtro IIR (resposta de impulso infinito) em vez do filtro FIR (filtro de resposta finito) que você está usando agora. Há mais, mas à primeira vista os filtros FIR são implementados como convoluções explícitas e filtros IIR com equações. O filtro IIR particular que eu uso muito em microcontroladores é um filtro passa-baixa de um único pólo. Este é o equivalente digital de um simples filtro analógico R-C. Para a maioria dos aplicativos, estes terão melhores características do que o filtro de caixa que você está usando. A maioria dos usos de um filtro de caixa que eu encontrei são resultado de alguém que não presta atenção na classe de processamento de sinal digital, não como resultado de precisar de suas características particulares. Se você quiser apenas atenuar as altas freqüências que você conhece são ruim, um filtro passa-baixa de um único pólo é melhor. A melhor maneira de implementar um digitalmente em um microcontrolador é geralmente: FILT lt-- FILT FF (NEW-FILT) FILT é um pedaço de estado persistente. Esta é a única variável persistente que você precisa para calcular esse filtro. NOVO é o novo valor que o filtro está sendo atualizado com esta iteração. FF é a fração do filtro. Que ajusta o peso do filtro. Olhe para este algoritmo e veja que para FF 0 o filtro é infinitamente pesado, já que a saída nunca muda. Para FF 1, realmente não há nenhum filtro, já que a saída apenas segue a entrada. Os valores úteis estão no meio. Em pequenos sistemas, você escolhe FF para ser 12 N, de modo que o multiplica por FF possa ser realizado como uma mudança direta por N bits. Por exemplo, FF pode ser 116 e multiplicar por FF, portanto, um deslocamento direito de 4 bits. Caso contrário, este filtro precisa apenas de uma subtração e de um som, embora os números geralmente precisem ser maiores do que o valor de entrada (mais na precisão numérica em uma seção separada abaixo). Normalmente, tomo as leituras de AD significativamente mais rápido do que elas são necessárias e aplique dois desses filtros em cascata. Este é o equivalente digital de dois filtros R-C em série e atenua 12 dBoctave acima da frequência de rolagem. No entanto, para as leituras de AD, geralmente é mais relevante olhar para o filtro no domínio do tempo, considerando sua resposta passo a passo. Isso indica o quão rápido o sistema verá uma mudança quando a coisa que você está medindo muda. Para facilitar a concepção desses filtros (o que significa apenas escolher FF e decidir quantos deles entrar em cascata), uso meu programa FILTBITS. Você especifica o número de bits de mudança para cada FF na série de filtros em cascata, e ele calcula a resposta de passo e outros valores. Na verdade, eu costumo executar isso através do meu script wrapper PLOTFILT. Isso executa FILTBITS, que faz um arquivo CSV, e enche o arquivo CSV. Por exemplo, aqui é o resultado do PLOTFILT 4 4: Os dois parâmetros para PLOTFILT significam que haverá dois filtros em cascata do tipo descrito acima. Os valores de 4 indicam o número de bits de mudança para realizar o multiplicar pelo FF. Os dois valores FF são, portanto, 116 neste caso. O traço vermelho é a resposta do passo da unidade, e é o principal aspecto a ser observado. Por exemplo, isso indica que, se a entrada muda instantaneamente, a saída do filtro combinado será fixada em 90 do novo valor em 60 iterações. Se você se preocupa com 95 horas de colonização, então você precisa esperar cerca de 73 iterações e por 50 horas de assentamento apenas 26 iterações. O traço verde mostra a saída de um único pico de amplitude total. Isso dá uma idéia da supressão de ruído aleatória. Parece que nenhuma amostra única causará mais do que uma mudança de 2.5 na saída. O traço azul é dar uma sensação subjetiva do que este filtro faz com o ruído branco. Este não é um teste rigoroso, uma vez que não há garantia de que exatamente o conteúdo era dos números aleatórios escolhidos como a entrada de ruído branco para esta corrida de PLOTFILT. É só dar-lhe uma sensação áspera de quanto será esmagado e quão suave é. PLOTFILT, talvez FILTBITS, e muitas outras coisas úteis, especialmente para o desenvolvimento de firmware PIC, estão disponíveis na versão do software PIC Development Tools na minha página de downloads de software. Adicionado sobre a precisão numérica que vejo a partir dos comentários e agora uma nova resposta que tem interesse em discutir o número de bits necessários para implementar este filtro. Observe que o multiplicar pelo FF criará novos bits do Log 2 (FF) abaixo do ponto binário. Em sistemas pequenos, o FF é geralmente escolhido para ser 12 N, de modo que esse multiplicação seja efetivamente realizado por uma mudança direta de N bits. FILT é, portanto, geralmente um número inteiro de ponto fixo. Observe que isso não altera nenhuma das matemáticas do ponto de vista dos processadores. Por exemplo, se você estiver filtrando as leituras AD de 10 bit e N 4 (FF 116), então você precisa de 4 bits de fração abaixo das leituras AD inteiras de 10 bits. Na maioria dos processadores, você estará fazendo operações inteiras de 16 bits devido às leituras AD de 10 bits. Nesse caso, você ainda pode fazer exatamente as mesmas operações de inteiro de 16 bits, mas comece com as leituras AD esquerda deslocadas em 4 bits. O processador não conhece a diferença e não precisa. Fazer matemática em inteiros inteiros de 16 bits funciona se você considera que eles são 12.4 pontos fixos ou verdadeiros inteiros de 16 bits (16.0 ponto fixo). Em geral, você precisa adicionar N bits a cada pólo de filtro se você não deseja adicionar ruído devido à representação numérica. No exemplo acima, o segundo filtro de dois teria que ter 1044 18 bits para não perder informações. Na prática, em uma máquina de 8 bits que significa que você use valores de 24 bits. Tecnicamente, apenas o segundo pólo de dois precisaria do valor mais amplo, mas, para a simplicidade do firmware, costumo usar a mesma representação e, assim, o mesmo código, para todos os pólos de um filtro. Normalmente, eu escrevo uma sub-rotina ou macro para executar uma operação de pólo de filtro e, em seguida, aplique isso para cada pólo. Se uma sub-rotina ou macro depende se os ciclos ou a memória do programa são mais importantes nesse projeto particular. De qualquer forma, eu uso algum estado de rascunho para passar NOVO no subroutinemacro, que atualiza FILT, mas também carrega isso no mesmo estado de rascunho NOVO estava dentro. Isso facilita a aplicação de vários pólos desde que o FILT atualizado de um pólo é o NOVO Do próximo. Quando uma sub-rotina, é útil ter um ponteiro apontar para FILT no caminho, que é atualizado logo após FILT no caminho de saída. Dessa forma, a sub-rotina atua automaticamente em filtros consecutivos na memória se for chamado várias vezes. Com uma macro, você não precisa de um ponteiro, pois você passa no endereço para operar em cada iteração. Exemplos de código Aqui está um exemplo de uma macro como descrito acima para um PIC 18: E aqui está uma macro semelhante para um PIC 24 ou dsPIC 30 ou 33: Ambos os exemplos são implementados como macros usando o meu pré-processador PIC assembler. Que é mais capaz do que qualquer uma das instalações de macro incorporadas. Clabacchio: Outro problema que eu deveria ter mencionado é a implementação do firmware. Você pode escrever uma sub-rotina de filtro passa-baixa de um único pó uma vez, e depois aplicá-la várias vezes. Na verdade, costumo escrever uma sub-rotina para levar um ponteiro na memória para o estado do filtro, então faça avançar o ponteiro para que possa ser chamado sucessivamente de forma fácil para realizar filtros multipolar. Ndash Olin Lathrop 20 de abril 12 às 15:03 1. Muito obrigado por suas respostas - todos eles. Eu decidi usar este Filtro IIR, mas este Filtro não é usado como um Filtro LowPass Padrão, pois eu preciso usar os Valores de Contador médios e compará-los para detectar Mudanças em um determinado intervalo. Uma vez que estes valores são de dimensões muito diferentes dependendo do hardware que eu queria tomar uma média para poder reagir automaticamente a essas mudanças específicas de hardware. Ndash sensslen 21 de maio 12 às 12:06 Se você pode viver com a restrição de um poder de dois itens a média (ou seja, 2,4,8,16,32 etc.), então a divisão pode ser feita com facilidade e eficiência em um Micro de baixo desempenho sem nenhuma divisão dedicada porque pode ser feito como uma mudança de bit. Cada turno para a direita é um poder de dois, por exemplo: O OP pensou que ele tinha dois problemas, dividindo-se em um PIC16 e memória para o buffer de anel. Esta resposta mostra que a divisão não é difícil. É certo que não aborda o problema de memória, mas o sistema SE permite respostas parciais, e os usuários podem tirar algo de cada resposta por si mesmos, ou mesmo editar e combinar as respostas de outros. Uma vez que algumas das outras respostas exigem uma operação de divisão, elas são igualmente incompletas, uma vez que não mostram como conseguir isso eficientemente em um PIC16. Ndash Martin 20 de abril 12 às 13:01 Há uma resposta para um verdadeiro filtro de média móvel (aka filtro de caixa) com menos requisitos de memória, se você não se importa com o downsampling. É chamado de filtro integrador-pente em cascata (CIC). A idéia é que você tenha um integrador que você tome diferenças em um período de tempo, e o dispositivo chave de economia de memória é que, por downsampling, você não precisa armazenar todos os valores do integrador. Ele pode ser implementado usando o seguinte pseudocódigo: Seu comprimento efetivo da média móvel é decimationFactorstatesize, mas você só precisa manter em torno de amostras estadisticas. Obviamente, você pode obter um melhor desempenho se o seu Stateization e decimationFactor forem poderes de 2, de modo que os operadores de divisão e restante sejam substituídos por turnos e máscaras-ands. Postscript: eu concordo com a Olin que você sempre deve considerar filtros IIR simples antes de um filtro de média móvel. Se você não precisa da freqüência-nulo de um filtro de caixa, um filtro passa-baixa de 1 pólo ou 2 pólos provavelmente funcionará bem. Por outro lado, se você estiver filtrando para fins de decimação (tomando uma entrada de alta taxa de amostragem e avaliando-a para uso por um processo de baixa taxa), então um filtro CIC pode ser exatamente o que você está procurando. (Especialmente se você puder usar statesize1 e evitar a compatibilidade do ringbuffer com apenas um único valor de integrador anterior) Há uma análise aprofundada da matemática por trás do uso do filtro IIR de primeira ordem que Olin Lathrop já descreveu na troca de pilha de processamento de sinal digital (Inclui muitas imagens bonitas.) A equação para este filtro IIR é: Isto pode ser implementado usando apenas números inteiros e sem divisão usando o seguinte código (pode precisar de alguma depuração como eu estava digitando de memória.) Este filtro se aproxima de uma média móvel de As últimas K amostras, definindo o valor de alfa para 1K. Faça isso no código anterior, definindo BITS para LOG2 (K), ou seja, para K 16, defina BITS para 4, para K 4, defina BITS para 2, etc. (Verifique o código listado aqui assim que recebo uma alteração e Edite esta resposta, se necessário.) Respondeu 23 de junho 12 às 4:04 Heres um filtro passa-baixa de um único polo (média móvel, com freqüência de corte CutoffFrequency). Muito simples, muito rápido, funciona muito bem, e quase sem memória extra. Nota: Todas as variáveis ​​têm um alcance além da função de filtro, exceto o passado em newInput Note: Este é um filtro de estágio único. Múltiplos estágios podem ser conectados em cascata para aumentar a nitidez do filtro. Se você usar mais de um estágio, você terá que ajustar DecayFactor (como se relaciona com a frequência de corte) para compensar. E, obviamente, tudo que você precisa é aquelas duas linhas colocadas em qualquer lugar, elas não precisam de sua própria função. Este filtro possui um tempo de aceleração antes que a média móvel represente a do sinal de entrada. Se você precisar ignorar esse tempo de aceleração, você pode inicializar MovingAverage para o primeiro valor de newInput em vez de 0 e espero que o primeiro newInput não seja um outlier. (CutoffFrequencySampleRate) tem uma faixa entre 0 e 0,5. DecayFactor é um valor entre 0 e 1, geralmente perto de 1. Os carros de precisão única são bons o suficiente para a maioria das coisas, eu apenas prefiro duplas. Se você precisa ficar com números inteiros, você pode converter DecayFactor e Factor de amplitude em números inteiros fracionários, nos quais o numerador é armazenado como o inteiro e o denominador é um poder inteiro de 2 (para que você possa mudar de bit para a direita como o Denominador em vez de ter que dividir durante o loop do filtro). Por exemplo, se DecayFactor 0.99 e você deseja usar números inteiros, você pode definir o DecayFactor 0.99 65536 64881. E então, quando você se multiplicar pelo DecayFactor no loop do filtro, basta mudar o resultado 16. Para obter mais informações sobre isso, um excelente livro é esse Online, capítulo 19 em filtros recursivos: dspguidech19.htm PS Para o paradigma da Média em Movimento, uma abordagem diferente para definir DecayFactor e AmplitudeFactor que pode ser mais relevante para suas necessidades, digamos que você quer o anterior, cerca de 6 itens em média, fazendo isso discretamente, você adicionará 6 itens e dividirá por 6, então Você pode configurar o AmplitudeFactor para 16, e DecayFactor para (1.0 - AmplitudeFactor). Respondeu 12 de maio 12 às 22:55 Todos os outros comentaram completamente sobre a utilidade do IIR vs. FIR e sobre a divisão de poder de dois. Eu gostaria de dar alguns detalhes de implementação. O abaixo funciona bem em pequenos microcontroladores sem FPU. Não há multiplicação, e se você mantém N um poder de dois, toda a divisão é de mudança de bit de ciclo único. Tampão de anel FIR básico: mantenha um buffer de execução dos últimos valores de N e uma SOM em execução de todos os valores no buffer. Cada vez que uma nova amostra vem, subtrair o valor mais antigo no buffer de SUM, substituí-lo pela nova amostra, adicionar a nova amostra a SUM e saída SUMN. Tampão de anel IIR modificado: mantenha uma SOM executória dos últimos valores de N. Cada vez que uma nova amostra vem, SUM - SUMN, adicione a nova amostra e saia SUMN. Respondeu 28 de agosto às 13:45 Se eu já lendo você direito, você está descrevendo um filtro IIR de primeiro ordem, o valor que você está subtraindo não é o valor mais antigo que está caindo, mas é a média dos valores anteriores. Os filtros IIR de primeiro ordem certamente podem ser úteis, mas eu não tenho certeza do que você quer dizer quando você sugere que a saída seja a mesma para todos os sinais periódicos. A uma taxa de amostragem de 10KHz, a alimentação de uma onda quadrada de 100Hz em um filtro de caixa de 20 estágios produzirá um sinal que sobe uniformemente para 20 amostras, fica alto para 30, cai uniformemente para 20 amostras e fica com baixo para 30. Uma ordem de primeira ordem Filtro IIR. Ndash supercat 28 de agosto 13 às 15:31 renderá uma onda que começa a subir bruscamente e gradualmente se nivela perto (mas não em) o máximo de entrada, então começa a cai e gradualmente nivela perto (mas não em) o mínimo de entrada. Comportamento muito diferente. Ndash supercat 28 de agosto 13 às 15:32 Uma questão é que uma média móvel simples pode ou não ser útil. Com um filtro IIR, você pode obter um bom filtro com relativamente poucos calcs. O FIR que você descreve só pode dar-lhe um retângulo no tempo - um sinc na freq - e você pode gerenciar os lobos laterais. Pode valer a pena lançar alguns números inteiros para tornar uma boa FIR sintonizada simétrica se você pode poupar os tiques do relógio. Ndash Scott Seidman 29 de agosto 13 às 13:50 ScottSeidman: Não há necessidade de se multiplicar se alguém simplesmente tiver cada estágio da FIR, quer a saída da média da entrada para esse estágio e seu valor armazenado anterior, e depois armazene a entrada (se tiver O intervalo numérico, pode-se usar a soma em vez da média). Se isso é melhor do que um filtro de caixa depende da aplicação (a resposta de passo de um filtro de caixa com um atraso total de 1 ms, por exemplo, terá um pico d2dt desagradável quando a entrada muda e, novamente, 1 ms depois, mas terá o mínimo Possível ddt para um filtro com um atraso total de 1ms). Ndash supercat 29 de agosto 13 às 15:25 Como mikeselectricstuff disse, se você realmente precisa reduzir suas necessidades de memória e você não se importa que sua resposta de impulso seja exponencial (em vez de um pulso retangular), eu iria por um filtro exponencial de média móvel . Eu os uso extensivamente. Com esse tipo de filtro, você não precisa de nenhum buffer. Você não precisa armazenar N amostras passadas. Apenas um. Então, seus requisitos de memória são reduzidos por um fator de N. Além disso, você não precisa de nenhuma divisão para isso. Somente multiplicações. Se você tiver acesso à aritmética de ponto flutuante, use as multiplicações de ponto flutuante. Caso contrário, faça multiplicações inteiras e mude para a direita. No entanto, estamos em 2012, e eu recomendaria que você usasse compiladores (e MCUs) que permitem que você trabalhe com números de ponto flutuante. Além de ser mais eficiente e mais rápido (você não precisa atualizar itens em qualquer buffer circular), eu diria que também é mais natural. Porque uma resposta exponencial de impulso corresponde melhor à maneira como a natureza se comporta, na maioria dos casos. Respondeu 20 de abril 12 às 9:59 Um problema com o filtro IIR como quase tocado por olin e supercat, mas aparentemente desconsiderado por outros é que o arredondamento apresenta alguma imprecisão (e potencialmente biastruncagem). Assumindo que N é um poder de dois, e apenas uma aritmética inteira é usada, a direita de mudança elimina sistematicamente os LSBs da nova amostra. Isso significa que, quanto tempo a série possa ser, a média nunca levará em consideração isso. Por exemplo, suponha uma série que diminua lentamente (8,8,8. 8,7,7,7. 7,6,6) e assume que a média é de fato 8 no início. A amostra do punho 7 trará a média para 7, independentemente da força do filtro. Apenas para uma amostra. A mesma história para 6, etc. Agora pense no contrário. A série sobe. A média permanecerá em 7 para sempre, até que a amostra seja grande o suficiente para fazê-la mudar. Claro, você pode corrigir o viés, adicionando 12N2, mas isso realmente não resolverá o problema de precisão. Nesse caso, a série decrescente permanecerá para sempre em 8 até a amostra ser 8-12 (N2). Para N4, por exemplo, qualquer amostra acima de zero manterá a média inalterada. Eu acredito que uma solução para isso implicaria manter um acumulador de LSBs perdidos. Mas eu não conseguiria o suficiente para ter código pronto, e não tenho certeza de que isso não prejudicaria o poder IIR em alguns outros casos de séries (por exemplo, se 7,9,7,9 seria de 8). Olin, sua cascata de dois estágios também precisaria de alguma explicação. Você quer dizer segurar dois valores médios com o resultado do primeiro alimentado no segundo em cada iteração. Qual é o benefício desta média média móvel média média Média móvel simples Você é encorajado a resolver esta tarefa de acordo com a descrição da tarefa, usando qualquer idioma que você conheça. Calculando a média móvel simples de uma série de números. Crie uma função de função estatal que leva um período e retorna uma rotina que leva um número como argumento e retorna uma média móvel simples de seus argumentos até agora. Uma média móvel simples é um método para calcular uma média de um fluxo de números apenas com a média dos últimos 160 P 160 números da corrente, 160 em que 160 P 160 é conhecido como o período. Pode ser implementado chamando uma rotina de inicialização com 160 P 160 como seu argumento, 160 I (P), 160, o que deve retornar uma rotina que, quando chamada com membros individuais e sucessivos de um fluxo de números, calcula a média de (acima Para), o último 160 P 160 deles, vamos chamar este 160 SMA (). A palavra 160 160 com estado na descrição da tarefa refere-se à necessidade de 160 SMA () 160 para lembrar certas informações entre chamadas para ela: 160 O período, 160 P 160 Um recipiente ordenado de pelo menos os últimos 160 P 160 números de cada um São chamadas individuais. O 160 declarado também significa que as chamadas sucessivas para 160 I (), 160 o inicializador, 160 devem retornar rotinas separadas que 160 não 160 compartilham o estado salvo para que possam ser usadas em dois fluxos de dados independentes. Pseudo-código para uma implementação de 160 SMA 160 é: Esta versão usa uma fila persistente para manter os valores p mais recentes. Cada função retornada da média init-moving tem seu estado em um átomo que possui um valor de fila. Esta implementação usa uma lista circular para armazenar os números dentro da janela no início de cada ponteiro de iteração refere-se à célula da lista que mantém o valor simplesmente deslocando-se da janela e para ser substituído pelo valor adicionado. Usando uma edição de encerramento Atualmente, esse sma não pode ser nogc porque ele aloca um fecho no heap. Algumas análises de escape podem remover a alocação de pilha. Usando uma edição de estrutura Esta versão evita a alocação de pilha do fechamento mantendo os dados no quadro de pilha da função principal. Mesmo resultado: para evitar que as aproximações de ponto flutuante continuem empilhando e crescendo, o código poderia executar uma soma periódica em toda a matriz de fila circular. Esta implementação produz dois (função) estado de compartilhamento de objetos. É idiomático em E para separar a entrada da saída (ler da escrita) ao invés de combiná-los em um único objeto. A estrutura é a mesma que a implementação do Desvio PadrãoE. O programa elixir abaixo gera uma função anônima com um período incorporado p, que é usado como o período da média móvel simples. A função de execução lê a entrada numérica e passa para a função anônima recém-criada e, em seguida, inspeciona o resultado para o STDOUT. A saída é mostrada abaixo, com a média, seguida da entrada agrupada, formando a base de cada média móvel. Erlang possui fechamentos, mas variáveis ​​imutáveis. Então, uma solução é usar processos e uma mensagem simples passando a API baseada. As linguas Matrix têm rotinas para calcular os padrões de deslizamento para uma determinada sequência de itens. É menos eficiente para loop como nos seguintes comandos. Indica continuamente uma entrada I. Que é adicionado ao final de uma lista L1. L1 pode ser encontrado pressionando 2ND1, e significa pode ser encontrado em ListOPS Pressione ON para terminar o programa. Função que retorna uma lista contendo os dados médios do argumento fornecido Programa que retorna um valor simples em cada invocação: a lista é a média da lista: p é o período: 5 retorna a lista média: Exemplo 2: Usando o programa movinav2 (i 5) - Inicializando o cálculo da média móvel e define o período de 5 movinav2 (3, x): x - novos dados na lista (valor 3), eo resultado será armazenado na variável x e exibido movinav2 (4, x) : X - novos dados (valor 4), e o novo resultado será armazenado na variável x e exibido (43) 2. Descrição da função movinavg: variável r - é o resultado (a lista média) que será retornada variável i - é a variável índice, e aponta para o final da sub-lista a lista em média. Variável z - uma variável auxiliar A função usa a variável i para determinar quais valores da lista serão considerados no próximo cálculo médio. Em cada iteração, a variável i aponta para o último valor na lista que será usado no cálculo médio. Então, só precisamos descobrir qual será o primeiro valor na lista. Normalmente, é preciso considerar os elementos p, então o primeiro elemento será o indexado por (i-p1). No entanto, nas primeiras iterações, esse cálculo geralmente será negativo, então a seguinte equação evitará índices negativos: max (i-p1,1) ou, organizando a equação, max (i-p, 0) 1. Mas o número de elementos nas primeiras iterações também será menor, o valor correto será (índice final - iniciar índice 1) ou, organizando a equação, (i - (max (ip, 0) 1) 1) e, em seguida, , (I-max (ip, 0)). A variável z mantém o valor comum (max (ip), 0) para que o beginindex seja (z1) e o número dos itens serão (iz) mid (list, z1, iz) retornará a lista de valor que será a soma média ( .) Irá somar-lhes soma (.) (Iz) ri irá em média e armazenar o resultado no lugar apropriado na lista de resultados fp1 cria uma aplicação parcial que conserta o (neste caso) o segundo e terceiro parâmetros

No comments:

Post a Comment