计算数字滤波器的频率响应 (2)

将上次的程序用C++重写了一遍。希望对大家有用。

下面是代码:

class IIR_BODE
{
private:
    double *m_pNum;
    double *m_pDen;
    int m_num_order;
    int m_den_order;
    complex<double> poly_val(double p[], int order, double omega);
public:
    IIR_BODE();
    void setPara(double num[], int num_order, double den[], int den_order);
    complex<double> bode(double omega);
    void bode(double omega[], int n, complex<double> resp[]);
};
IIR_BODE::IIR_BODE()
{
    m_pNum = NULL;
    m_pDen = NULL;
    m_num_order = -1;
    m_den_order = -1;
}

void IIR_BODE::setPara(double num[], int num_order, double den[], int den_order)
{
    delete[] m_pNum;
    delete[] m_pDen;
    m_pNum = new double[num_order + 1];
    m_pDen = new double[den_order + 1];
    m_num_order = num_order;
    m_den_order = den_order;
    for(int i = 0; i <= m_num_order; i++)
    {
        m_pNum[i] = num[i];
    }
    for(int i = 0; i <= m_den_order; i++)
    {
        m_pDen[i] = den[i];
    }
}
complex<double> IIR_BODE::bode(double omega)
{
    complex<double> h;
    h = poly_val(m_pNum, m_num_order, omega) / poly_val(m_pDen, m_den_order, omega);
    return h;
}
complex<double> IIR_BODE::poly_val(double p[], int order, double omega)
{
    complex<double> z, sum = 0.0;
    z = complex<double>( cos(omega), -sin(omega) );
    for (int i = order; i >= 0; i--)
    {
        sum = sum * z + p[i];
    }
    return sum;
}
void IIR_BODE::bode(double omega[], int n, complex<double> resp[])
{
    for(int i = 0; i < n; i++)
    {
        resp[i] = bode(omega[i]);
    }
}

下面是测试代码,测试的是一个4阶切比雪夫低通滤波器的频率响应:

#include <iostream>
#include <math.h>
using namespace std;

int main()
{
    double b[5] = {0.001836, 0.007344, 0.011016, 0.007344, 0.001836};
    double a[5] = {1.0, -3.0544, 3.8291, -2.2925, 0.55075};
    double argz, old_argz = 0, omega;
    complex<double> z;
    int len = 100;
    IIR_BODE bode;
    bode.setPara(b, 4, a, 4);
    
    for (int i = 0; i < len; i++)
    {
        omega = M_PI * i / (len);
        z = bode.bode(omega);
        argz = arg(z);
        argz = argz - round( (argz - old_argz) / M_PI ) * M_PI;
        old_argz = argz;
        cout << omega << ", " << abs(z) << ", " << argz << endl;
    }
}

程序很简答,没什么值得多说的。不过倒是用到了个小技巧使得计算出的相频曲线是连续的。
计算数字滤波器的频率响应 (2)_第1张图片

计算数字滤波器的频率响应 (2)_第2张图片

你可能感兴趣的:(计算数字滤波器的频率响应 (2))