由于最近在做与数据处理有关的项目,因此不可避免的去啃与数学相关性很大的一些算法,在查阅了网上的资料以及《数字信号处理》等书的基础上写出了一些单变量和数组数据的滑动平均算法,废话少说,直接上程序实例配以解释(在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;
}