由於最近在做與數據處理有關的項目,因此不可避免的去啃與數學相關性很大的一些算法,在查閱了網上的資料以及《數字信號處理》等書的基礎上寫出了一些單變量和數組數據的滑動平均算法,廢話少說,直接上程序實例配以解釋(在BCB中調試成功):
/*********************************
* 函數名稱:Glide_Average_Value_Filter*
* 函數參數:[In]:1.Data[N](滑動平均所需的數組,N*
* 爲滑動點數,全局數組) *
* 2.NewData(新進入數組的數據點)。*
* 函數返回值:double類型的該點滑動平均值。 *
* 作者:wang xiao jun *
*********************************/
#Define N 37
double Global_Data[N];/*全局函數*/
double TmainForm::Glide_Average_Value_Filter(double Data[N],double NewData)
{
int i = 0;
double Average_Value = 0 ,Sum = 0;
/*數組整體向左移動,去除數組第一個值*/
for(i = 0;i < N;i++)
{
Data[i] = Data[i+1];
Sum + = Data[i];
}
/*將最新值放入數組最右端*/
Data[N-1] = NewData;
/*計算數據總和*/
Sum + = NewData;
/*計算平均值*/
Average_Value = Sum/N;
return(Average_Value);
}
這種方法使用的數據結構爲線性隊列而非環形隊列,所以,每次有新的值進入隊列時都要移動整個數組,導致了算法的效率變低,其示意圖如圖所示:
我們其實可以使用另外一種數據結構,那就是環形隊列,其結構如下圖所示:
這種結構就避免了每次函數執行時數組的移動,如下程序寫的是利用環形隊列進行二維數組的滑動平均。
/*********************************
* 函數名稱:Spec_Moving_Average_Filter *
* 函數參數:[In]:1.Amra[NUM][N](滑動平均所需的數組,N*
* 爲滑動點數,全局數組) *
* 2.NewData[N](新進入數組的數據點)。*
* 函數返回值:double類型的該點滑動平均值。 *
* 作者:wang xiao jun *
*********************************/
#include <stdio.h>
#Define N 6
#Define NUM 3
double *Spec_Moving_Average_Filter(Amra[NUM][N],NewData[N],int N)
{
int Num_Of_Spec = 0;
int i = 0 , j =0;
double *p_Aver = (double *) malloc (sizeof (double) * 2048); /*定義均值光譜數組*/
/*新數據加入滑動平均數組*/
for(i = 0 ; i < N ; i++)
{
Arma[ Num_Of_Spec ][i] = NewData[i];
}
/*環形數據隊列*/
if (Num_Of_Spec++ == NUM)
Num_Of_Spec = 0;
/*滑動平均運算*/
for(i = 0 ; i <NUM ; i++)
{
for(j = 0 ; j< N; j++,p_Aver++)
{
*p_Aver = Arma[i][j];
}
}
/*求取均值*/
for(i = 0;i < N ;i++ )
{
(*p_Aver)/ = NUM;
}
return (p_Aver);
}
int main()
{
double Intensity[N] = {1,2,3,4,5,6,}; /*定義全局單體數組*/
doubel Moving_Average[NUM][N]; /*定義全局滑動平均二維數組*/
double *p_Average;
while(1)
{
Intensity =GetAD();
p_Average = Spec_Moving_Average_Filter(Moving_Average,Intenstiy,N);
Intensity = p_Average;
/*後續的數據處理*/
free (p_Average);
}
return 0;
}