単純な移動平均アルゴリズム

この問題は、信号処理および統計で広く使用されている移動平均アルゴリズムを実装するC ++で発生しました。
画像
基本は、MATLABの滑らかな関数です。
この関数は、信号のフィルタリングに使用できます。 データの配列と平均化ウィンドウは、入力パラメーターとして定義されます。
誰が気にします、私はカットをお願いします


そのため、このアルゴリズムにはいくつかの実装があります。 最も簡単なものを考えてください:
平均化ウィンドウのサイズが5である場合、平均化の各ステップで現在の値が取得され、前の4つがそれに加算され、結果が5で除算されます。ここでの明らかな問題は、アルゴリズムの初期化にあります。

MATLABでは、移動平均フィルタリングアルゴリズムはsmooth関数で実装されています
smooth(input、window)を使用した例、
inputは入力データの配列です
window-平均化ウィンドウ。
ウィンドウパラメーターを変更することにより、データの平滑化の程度を増減できます。
画像

この例を実装するソースを以下に示します。
clear all; %%  t=1;%   Fd=512;%   () A1=1;%   F1=10;%   () SNR=0.3;%  / T=0:1/Fd:t;%   Noise=A1*SNR*randn(1,length(T));%  Signal=A1*sind((F1*360).*T);%  SN=Signal+Noise; figure(1); subplot(4,1,1); plot(SN); subplot(4,1,2); plot(smooth(SN,3)); subplot(4,1,3); plot(smooth(SN,8)); subplot(4,1,4); plot(smooth(SN,20)); 


信号処理の遅延を補正するために、MATLABは動的にサイズ変更可能なウィンドウを使用します;メソッドの本質を次の例で示します。
画像

最初にこのアルゴリズムの独自の実装をMATLABで作成してから、C ++に転送しました

MATLABエディション:

 %my_smooth % ,    ,    1  ; window = 5; if(mod(window,2)==0) window=window+1; end hw=(window-1)/2; %        n=length(Signal); result=zeros(n,1); result(1)=SN(1); %      SN   for i=2:n %     init_sum = 0; if(i<=hw) %    ,     , %     k1=1; %       k2=2*i-1; %  z=k2; %   elseif (i+hw>n) % +   n -         %   k1=i-n+i; %  k2=n; %  -    z=k2-k1; %  else %     ,     k1=i-hw; k2=i+hw; z=window; end for j=k1:k2 %       init_sum=init_sum+SN(j); %   end result(i)=init_sum/(z); %      end 


このプログラムの結果は、奇数のウィンドウサイズで滑らかなmatlabと完全に一致し、偶数の値とはわずかに異なります(ウィンドウでも、matlabはわずかに異なると見なされます)。
ソースmファイルはここで取得できます

C ++エディション

 void smooth(double *input, double *output, int n, int window) { int i,j,z,k1,k2,hw; double tmp; if(fmod(window,2)==0) window++; hw=(window-1)/2; output[0]=input[0]; for (i=1;i<n;i++){ tmp=0; if(i<hw){ k1=0; k2=2*i; z=k2+1; } else if((i+hw)>(n-1)){ k1=i-n+i+1; k2=n-1; z=k2-k1+1; } else{ k1=i-hw; k2=i+hw; z=window; } for (j=k1;j<=k2;j++){ tmp=tmp+input[j]; } output[i]=tmp/z; } 


ご清聴ありがとうございました。建設的な批判は大歓迎です
PS:
アルゴリズムは、合計の計算を変更することで速度を最適化できます。
画像
4番目のステップで要素の合計を計算するには、3番目のステップで合計から配列の最初の要素(2、赤でマーク)を減算し、6番目の要素(8、黄色のセル)を追加する必要があることがわかります。
次のステップでは、手順が繰り返されます。

このアプローチは、平均化ウィンドウが大きい場合に効果的です。

Source: https://habr.com/ru/post/J134375/


All Articles