1.IIR滤波器构造
之前在介绍FIR滤波器的时候,我们提到过,IIR滤波器的单位冲击响应是无限的!用差分方程来表达一个滤波器,应该是下式这个样子的。
这个式子是N次差分方程的表达式。我们明显可以看出,计算输出y(n)的时候,需要以前的输出值与输入值。换言之,这个可能表达式还有反馈环节。当
为0的时候,这个滤波器由于没有反馈,其单位冲击响应是有限的,是FIR滤波器。当
不为0是时候,是IIR滤波器。
很明显,这是一个1阶才差分方程。由于
不为0,这是一个1阶IIR滤波器的差分方程。为了方便观察,我们将其画系统成框图。
很明显的,要实现这个滤波器,我们需要2个单位的存储空间,用来存储过去的输入值与输出值。这样的话,考虑N阶的滤波器,我们就需要2N个存储单元。这种结构被称作直接I型结构。
3.直接II型IIR滤波器
我们先观察上图的直接I型滤波器,将其视为有两个较小系统串联而成的系统。由于是串联,那么,顺序必定不影响输入输出结果,那么,我们将其调整一下位置。得到就像下图一样的一个新的系统。
然后,我们可以发现,其实,这个系统完全没有必要使用两个延迟算子,可以合并使用。将其延迟算子合并,那么,可以得到下面这样一个系统。
这个系统与之前的直接I型系统一样,拥有完全相同的输入输出特性。并且,节省了一半的延迟算子。实现这个滤波器所需要的存储空间为N。
3.直接II型IIR滤波器的实现(C语言)
- #include <stdio.h>
- #include <math.h>
- #include <malloc.h>
- #include <string.h>
- double IIR_Filter(double *a, int Lenth_a,
- double *b, int Lenth_b,
- double Input_Data,
- double *Memory_Buffer)
- {
- int Count;
- double Output_Data = 0;
- int Memory_Lenth = 0;
- if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a;
- else Memory_Lenth = Lenth_b;
- Output_Data += (*a) * Input_Data; //a(0)*x(n)
- for(Count = 1; Count < Lenth_a ;Count++)
- {
- Output_Data -= (*(a + Count)) *
- (*(Memory_Buffer + (Memory_Lenth - 1) - Count));
- }
- //------------------------save data--------------------------//
- *(Memory_Buffer + Memory_Lenth - 1) = Output_Data;
- Output_Data = 0;
- //----------------------------------------------------------//
- for(Count = 0; Count < Lenth_b ;Count++)
- {
- Output_Data += (*(b + Count)) *
- (*(Memory_Buffer + (Memory_Lenth - 1) - Count));
- }
- //------------------------move data--------------------------//
- for(Count = 0 ; Count < Memory_Lenth -1 ; Count++)
- {
- *(Memory_Buffer + Count) = *(Memory_Buffer + Count + 1);
- }
- *(Memory_Buffer + Memory_Lenth - 1) = 0;
- //-----------------------------------------------------------//
- return (double)Output_Data;
- }
- int main(void)
- {
- double a[] = {1 , 0.5554 ,0.1542 };
- double b[] = {0 , 0 ,0.1542 };
- int Lenth_a = sizeof(a)/sizeof(double);
- int Lenth_b = sizeof(b)/sizeof(double);
- int Memory_Lenth = 0;
- if(Lenth_a >= Lenth_b) Memory_Lenth = Lenth_a;
- else Memory_Lenth = Lenth_b;
- printf("Memory Lenth : %d \n" , Memory_Lenth);
- double Input = 0 ;
- double Output = 0;
- double *Memory_Buffer;
- Memory_Buffer = (double *) malloc(sizeof(double)*Memory_Lenth);
- memset(Memory_Buffer,
- 0,
- sizeof(double)*Memory_Lenth);
- FILE* Input_Data;
- FILE* Output_Data;
- Input_Data = fopen("input.dat","r");
- Output_Data= fopen("output.txt","w");
- while(1)
- {
- if(fscanf(Input_Data, "%lf", &Input) == EOF) break;
- Output = IIR_Filter( a, Lenth_a,
- b, Lenth_b,
- Input,
- Memory_Buffer);
- fprintf(Output_Data,"%lf,",Output);
- //printf("Output: %lf \n" ,Output);
- }
- printf("Finish \n");
- return (int)1;
- }