一,原理部分
filter()函数的原理并不复杂,本质上就是解下面的方程
滤波过程就是解常系数线性差分方程的过程,形式如:
其中,x(n)序列为滤波前的信号序列,ak, bm为H(z)系统函数分母与分子的系统数组,求出的y(n)即为滤波后的信号序列。
注:x(n)与y(n)的长度要相等,且a0=1。
公式的化简工程如下:
默认条件,当k<0时,x(k), y(k)都为0。例如n=0时,y(0)=b0*x0+b1*x(-1)+...+bM*x(-M)-a1*y(-1)-...-aN*y(-N)=b0*x(0)。经过迭代,可以求出y(n)序列的所有值。
上面这个化简工程的公式,每一项都需要除以a0,a0应该是等于1。
二,代码实现
/**
* 通过差分方程滤波
* @param bArr 分子系数数组
* @param aArr 分母系数数组
* @param xArr 需要滤波的数组
* @return 滤波之后的结果
*/
public static double[] filter(double[] bArr, double[] aArr, double[] xArr){
int lenB = bArr.length;
int lenA = aArr.length;
int lenX = xArr.length;
int M = lenB - 1;
int N = lenA - 1;
double[] yArr = new double[lenX];
for(int i = 0; i < lenX; i++){
double yFront = 0;
for(int j = 0; j <= M && j <= i; j++){
yFront = yFront + bArr[j] * xArr[i - j];
}
double yBehind = 0;
for(int j = 1; j <= N && j <= i; j++){
yBehind = yBehind + aArr[j] * yArr[i - j];
}
yArr[i] = (yFront - yBehind) / aArr[0];
}
return yArr;
}
该函数运行结果和matlab结果进行过对比,结果是相同的。可以放心使用