我尝试实现一个通用的IIR滤波器。主要内容如下:

    // Loop over all SOS sections:
    value_type y = x;
    BOOST_FOREACH( Sos& n, m_sos )
    {
        y = update( n, y );
    }

与:
...update( Sos& sos, const value_type& x ) const
{

    const value_type xs = sos.m_s * x;

    const value_type w0 =   xs
                          - sos.m_a( 1 ) * sos.m_w( 0 )
                          - sos.m_a( 2 ) * sos.m_w( 1 );

    const value_type y =   w0
                         + sos.m_b( 1 ) * sos.m_w( 0 )
                         + sos.m_b( 2 ) * sos.m_w( 1 );

    sos.m_w( 1 ) = sos.m_w( 0 );
    sos.m_w( 0 ) = w0;

    return y;
}

系数m_a,m_b是变量,在运行期间从文件读取一次。
因此,在编译期间这些值是未知的。根据设计
过滤器,可能会发生某些系数为1.0或0.0的情况。因此对应
操作可以省略。这样可以节省很多性能。
可以肯定的是,我现在可以针对一个专用过滤器优化代码,但如上所述
实现应非常通用。
我的第一个想法是某种自我修改算法...但是也许有人有一个很棒的想法或暗示... :)

最佳答案

您可以制作过滤功能的模板化版本。我不知道如何将其直接应用于您的代码,但是请考虑以下几点:

// Z1 means "coefficient 1 is zero"
template <bool Z1, bool Z2, bool Z3, bool Z4, bool Z5>
...update( Sos& sos, const value_type& x ) const
{
    value_type coef1 = Z1 ? 0 : sos.m_a( 1 ); // or whatever else
    value_type coef2 = Z2 ? 0 : ...;
    value_type coef3 = Z3 ? 0 : ...;
    value_type coef4 = Z4 ? 0 : ...;
    value_type coef5 = Z5 ? 0 : ...;

    ... // the rest of your code
}

到目前为止,它定义了32个不同的函数,每个函数均已得到最大程度的优化(编译器应检测乘以零常数的乘法并优化代码)。然后,您可以使用函数指针数组:
auto my_table[] = {
    &update<0, 0, 0, 0, 0>,
    &update<0, 0, 0, 0, 1>,
    ...
    &update<1, 1, 1, 1, 1>
};

然后检查性能不重要的系数(从文件中读取系数),从数组中获取函数指针,并将其存储在对象Sos中。

如果听起来太含糊,我感到抱歉;我对您的代码不够了解,无法用可编译代码表达我的想法。

10-06 01:54