Matlab滤波器的实现

Matlab滤波器的实现,matlab,signal-processing,Matlab,Signal Processing,我读到Matlab的filter命令是用来解差分方程的。filter()是在内部使用z变换,还是仅仅使用递归,也就是说,对于起始值x(0),y(0),它只是在时间上向前运行差分方程?对不起,如果这个问题没有意义,我是这个领域的新手 多亏了,滤波器实现可能是对频域技术的巧妙运用,但是根据MATLAB文档,它在数学上等同于求解差分方程: Y = FILTER(B,A,X) filters the data in vector X with the filter described by ve

我读到Matlab的filter命令是用来解差分方程的。filter()是在内部使用z变换,还是仅仅使用递归,也就是说,对于起始值x(0),y(0),它只是在时间上向前运行差分方程?对不起,如果这个问题没有意义,我是这个领域的新手


多亏了,

滤波器实现可能是对频域技术的巧妙运用,但是根据MATLAB文档,它在数学上等同于求解差分方程:

Y = FILTER(B,A,X) filters the data in vector X with the filter described by vectors A and B to create the filtered data Y. The filter is a "Direct Form II Transposed" implementation of the standard difference equation: a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb) - a(2)*y(n-1) - ... - a(na+1)*y(n-na) Y=过滤器(B,A,X)使用 由向量A和B描述的过滤器,用于创建过滤后的 数据Y。过滤器为“直接形式II转置” 标准差分方程的实施: a(1)*y(n)=b(1)*x(n)+b(2)*x(n-1)+……+b(nb+1)*x(n-nb) -a(2)*y(n-1)-…-a(na+1)*y(n-na)
初始条件被选择为全零,因为在开始滤波之前,我们假设没有信号(全零)。如果您想指定这些初始条件,那么
filter
命令允许您指定初始(
Zi
)和最终(
Zf
)条件的向量:
[Y,Zf]=filter(B,A,X,Zi)

MatLab filter()函数实现iir滤波器(递归滤波器),即它求解差分方程。在频域中实现会有更高的成本。时域是O(n),频域理想的是log(n),如果使用FFT,O(n)。

< P>这里是我以前在C++中实现了Matlab的内置<代码>过滤器< /代码>函数,如果有人需要的话。在
Zi
中,传递初始条件,并在需要时收集最终条件

#include <vector>
#include <exception>
#include <algorithm>

typedef vector<double> vectord;

void filter(vectord B, vectord A, const vectord &X, vectord &Y, vectord &Zi)
{
    if (A.empty())
        throw std::domain_error("The feedback filter coefficients are empty.");
    if (std::all_of(A.begin(), A.end(), [](double coef){ return coef == 0; }))
        throw std::domain_error("At least one of the feedback filter coefficients has to be non-zero.");
    if (A[0] == 0)
        throw std::domain_error("First feedback coefficient has to be non-zero.");

    // Normalize feedback coefficients if a[0] != 1;
    auto a0 = A[0];
    if (a0 != 1.0)
    {       
        std::transform(A.begin(), A.end(), A.begin(), [a0](double v) { return v / a0; });
        std::transform(B.begin(), B.end(), B.begin(), [a0](double v) { return v / a0; });
    }

    size_t input_size = X.size();
    size_t filter_order = std::max(A.size(), B.size());
    B.resize(filter_order, 0);
    A.resize(filter_order, 0);  
    Zi.resize(filter_order, 0);
    Y.resize(input_size);

    for (size_t i = 0; i < input_size; ++i)
    {
        size_t order = filter_order - 1;
        while (order)
        {
            if (i >= order)
                Zi[order - 1] = B[order] * X[i - order] - A[order] * Y[i - order] + Zi[order];
            --order;
        }
        Y[i] = B[0] * X[i] + Zi[0];
    }
    Zi.resize(filter_order - 1);
}
#包括
#包括
#包括
类型定义向量向量;
无效过滤器(向量B、向量A、常量向量D和X、向量D和Y、向量D和Zi)
{
if(A.empty())
抛出std::domain_错误(“反馈滤波器系数为空”);
if(std::all_of(A.begin(),A.end(),[](双coef){return coef==0;}))
throw std::domain_error(“至少一个反馈滤波器系数必须为非零”);
如果(A[0]==0)
throw std::domain_error(“第一反馈系数必须非零”);
//如果a[0]!=1,则对反馈系数进行规范化;
自动a0=A[0];
如果(a0!=1.0)
{       
std::transform(A.begin(),A.end(),A.begin(),[a0](双v){return v/a0;});
std::transform(B.begin(),B.end(),B.begin(),[a0](双v){返回v/a0;});
}
大小输入大小=X.size();
大小过滤器顺序=std::max(A.size(),B.size());
B.调整大小(过滤器顺序,0);
A.调整大小(过滤器顺序,0);
调整大小(过滤顺序,0);
Y.调整大小(输入大小);
对于(大小i=0;i<输入大小;++i)
{
大小顺序=过滤器顺序-1;
while(订单)
{
如果(i>=订单)
Zi[顺序-1]=B[顺序]*X[顺序i]-A[顺序]*Y[顺序i]+Zi[顺序];
--秩序;
}
Y[i]=B[0]*X[i]+Zi[0];
}
调整大小(过滤器顺序-1);
}
请随意使用以下代码进行测试:

TEST_METHOD(TestFilter)
{
    vectord b_coeff = { /* Initialise your feedforward coefficients here */ };
    vectord a_coeff = { /* Initialise your feedback coefficients here */ };

    vectord input_signal = { /* Some input data to be filtered */ };
    vectord y_filter_ori = { /* MATLAB output from calling y_filter_ori = filter(b_coeff, a_coeff, input_signal); */ };

    vectord y_filter_out; vectord zi = { 0 };  // Set empty initial conditions
    filter(b_coeff, a_coeff, input_signal, y_filter_out, zi);
    Assert::IsTrue(compare(y_filter_out, y_filter_ori, 0.0001));
}

bool compare(const vectord &original, const vectord &expected, double tolerance = DBL_EPSILON)
{
    if (original.size() != expected.size())
        return false;
    size_t size = original.size();

    for (size_t i = 0; i < size; ++i)
    {
        auto diff = abs(original[i] - expected[i]);
        if (diff >= tolerance)
            return false;
    }
    return true;
}
TEST\u方法(TestFilter)
{
向量b_coeff={/*在此处初始化前馈系数*/};
向量a_coeff={/*在此处初始化反馈系数*/};
向量输入_信号={/*一些要过滤的输入数据*/};
向量y_filter_ori={/*调用y_filter_ori=filter(b_系数,a_系数,输入信号)的MATLAB输出;*/};
vectord y_filter_out;vectord zi={0};//设置空初始条件
滤波器(b_系数、a_系数、输入信号、y_滤波器、zi);
断言::IsTrue(比较(y_filter_out,y_filter_ori,0.0001));
}
布尔比较(常量向量与原始值、常量向量与预期值、双公差=DBL_ε)
{
如果(原始.size()!=预期的.size())
返回false;
size_t size=original.size();
对于(大小i=0;i=公差)
返回false;
}
返回true;
}

我想知道为什么有人会考虑FRQ域解决方案,考虑到你分享的性能不同。这个主题是一个巨大的研究领域。递归滤波器的实现速度非常快,但这种方法只能实现有限数量的滤波器特性。大多数情况下,所需的滤波器要么仅在频域中进行近似,要么在频域中实现,具有上述缺点,即计算成本较高和其他副作用,例如实时应用中的额外延迟。