【问题标题】:Implementation of IIR Lowpass Filter in C++C++中IIR低通滤波器的实现
【发布时间】:2014-03-20 16:05:18
【问题描述】:

我有巴特沃斯低通滤波器的滤波器系数,来自 Matlab 函数 [b, a] = butter(3, 0.4, 'low'),我实现了 Matlab 根据 their documentationfilter(b, a, X) 使用的相同计算。例如,过滤恒定信号 5.0 的结果是相同的,但仅针对前 10 个值!?

我想我的循环缓冲区是错误的,但我找不到任何问题。值正确写入x 使用过滤方法,数组初始化为零,循环缓冲区指针n 具有正确的值......你有什么想法吗?

// Interface
class LowpassFilter {
private:
    double x[10]; // input vector
    double y[10]; // output vector
    int n;    // pointer to the current array index

public:
    LowpassFilter(); 
    double filter(double sample);
};


// Implementation

// filter coefficients a and b
const double a[] = {1.0, -0.577240524806303, 0.421787048689562, -0.056297236491843};
const double b[] = {0.098531160923927, 0.295593482771781, 0.295593482771781, 0.098531160923927};
static int c = 0;

LowpassFilter::LowpassFilter() : x{0.0}, y{0.0}, n(0) { } // Constructor

double LowpassFilter::filter(double sample)
{
    x[n] = sample;
    y[n] = b[0] * x[n] + b[1] * x[(n-1)%10] + b[2] * x[(n-2)%10] + b[3] * x[(n-3)%10]
                       - a[1] * y[(n-1)%10] - a[2] * y[(n-2)%10] - a[3] * y[(n-3)%10];

    std::cout << c++ << ": " << y[n] << std::endl; // for checking the result with the Matlab results

    double result = y[n];
    n = (n + 1) % 10; // new pointer index 
    return result;
}

【问题讨论】:

  • 当 n == 0 和 (n-2)%10 时,模数会发生什么? Check this.
  • 你输出什么?你看到了什么问题。
  • @MichaelDorner:模确实有负值,这就是问题的原因。替换例如(n-1)%10(n+10-1)%10 以确保您始终获得预期的正值。
  • 非常感谢,你说得对!

标签: c++ matlab filter lowpass-filter


【解决方案1】:

感谢Mike Seymouremsr,问题是y[n] 计算中的负索引。要解决这个问题,只需采用一行:

y[n] = b[0] * x[n] + b[1] * x[(n-1+m)%m] + b[2] * x[(n-2+m)%m] + b[3] * x[(n-3+m)%m]
                   - a[1] * y[(n-1+m)%m] - a[2] * y[(n-2+m)%m] - a[3] * y[(n-3+m)%m];

确保索引为正。现在它工作正常。非常感谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-11
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    相关资源
    最近更新 更多