C++实现复数的滤波filter

C++实现复数的滤波filter

  • 导言
    • 函数需求分析
    • 源码
    • 追求速度
    • 注意

导言

最近在进行Qt开发,涉及大量的matlab转C的工作,其中包括插值滤波等,这里对matlab的filter函数进行了研究并用C++进行了重写。
经对比,结果与matlab的filter()函数生成的滤波结果一致。

函数需求分析

这里我对工作中调用matlab的filter()函数的实例为例子进行讲解:

  1. 原matlab程序
   temp1_i=filter(lbf,1,real(x_d(1:lbn+LEN)));
   temp1_q=filter(lbf,1,imag(x_d(1:lbn+LEN)));
  1. filter()生成的结果
    在这里插入图片描述
    C++实现复数的滤波filter_第1张图片

  2. C++版filter()输入输出参数详情

参数名 介绍
Ti 已有的点的x坐标的值
To 插入的点的X坐标的值
I_Id 已有的点实部的y坐标的值
Q_Id 已有的点虚部的y坐标的值
Y 插入的点的实部和虚部的Y坐标的值以复数的形式返回
  comDouble filter(vector<double> b, double a, comDouble x)
  /*
  	注意:该函数仅实现了a为标量且为1时的函数滤波!!!
  	参数介绍:
  	b:		滤波器系数
  	a:		分母系数
  	x:		复数
  	x.real: 复数实部
  	x.imag: 复数虚部

  	Y:		复数滤波结果
  	Y.real:复数实部滤波结果
  	Y.imag:复数虚部滤波结果

  	公式:(a = 1时)
  	当 i < 滤波器阶数 时有:
  		Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j 滤波器阶数 时有:
  		Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j<滤波器阶数)
  */
  1. C++版interp函数生成结果 :结果表明,生成结果与matlab生成结果一致。

源码

那么废话不多说,直接上代码

#include <vector>
#include <iostream>
using namespace std;
const struct comDouble
{
   vector<double> real;
   vector<double> imag;

   double time;
};
comDouble filter(vector<double> b, double a, comDouble x)
{
   /*
   	注意:该函数仅实现了a为标量且为1时的函数滤波!!!
   	参数介绍:
   	b:		滤波器系数
   	a:		分母系数
   	x:		复数
   	x.real: 复数实部
   	x.imag: 复数虚部

   	Y:		复数滤波结果
   	Y.real:复数实部滤波结果
   	Y.imag:复数虚部滤波结果

   	公式:(a = 1时)
   	当 i < 滤波器阶数 时有:
   		Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j 滤波器阶数 时有:
   		Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j<滤波器阶数)
   */
   comDouble Y;
   for (int i = 0; i < b.size(); i++)
   {
   		double real = 0.0;
   		double imag = 0.0;
   
   		for (int j = 0; j <= i; j++) {
   			real += b[j] * x.real[i - j];
   			imag += b[j] * x.imag[i - j];
   		}
   		Y.real.push_back(real);
   		Y.imag.push_back(imag);
   }
   for (int i = b.size(); i < x.real.size(); i++) {
   		double real = 0.0;
   		double imag = 0.0;
   		
   		for (int j = 0; j < b.size(); j++) {
   			real += b[j] * x.real[i - j];
   			imag += b[j] * x.imag[i - j];
   		}
   		
   		Y.real.push_back(real);
   		Y.imag.push_back(imag);
   }
   return Y;
}

追求速度

   #include <iostream>
   using namespace std;
   struct comDoubleC
   {
   	double *real;
   	double *imag;
   	double time;
   	int rsize;
   	int isize;
   
   	comDoubleC(int reallen, int imaglen) {
   		this->real = new double[reallen];
   		this->imag = new double[imaglen];
   		this->time = 0;
   		this->rsize = 0;
   		this->isize = 0;
   	}
   };
   //fir滤波
   comDoubleC filter(
           double lbf[],
           int lbflen,
           double x_dreal[],
           double x_dimag[],
           int x_dLen,
           comDoubleC temp1_iq)
   {
       /*
           注意:该函数仅实现了a为标量且为1时的函数滤波!!!
           参数介绍:
           lbf:		滤波器系数
           x_dreal: 复数实部
           x_dimag: 复数虚部

           temp1_iq:结果---在函数外管理内存

           公式:(a = 1时)
           当 i < 滤波器阶数 时有:
               Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j 滤波器阶数 时有:
               Y[i] = ∑b[j]*x[i-j] (下限j=0, 上限j<滤波器阶数)
       */
       double real;
       double imag;
       for (int i = 0; i < lbflen; i++)
       {
           real = 0.0;
           imag = 0.0;
           for (int j = 0; j <= i; j++) {
               real += lbf[j] * x_dreal[i - j];
               imag += lbf[j] * x_dimag[i - j];
           }
           temp1_iq.real[i] = real;
           temp1_iq.imag[i] = imag;
       }
       for (int i = lbflen; i < x_dLen; i++) {
           real = 0.0;
           imag = 0.0;
           for (int j = 0; j < lbflen/2; j++) {
               real += lbf[j] * x_dreal[i - lbflen + j];
               imag += lbf[j] * x_dimag[i - lbflen + j];
           }
           temp1_iq.real[i] = real;
           temp1_iq.imag[i] = imag;
       }
       return temp1_iq;
   }

注意

该文章仅个人学习使用,欢迎大家一起交流学习

你可能感兴趣的:(matlab转C,FIR滤波器,matlab,filter)