如果我使用某些特定数字,则双倍乘法需要100倍

时间:2017-06-29 16:57:37

标签: c# math filter double

我有一个简单的功能来实现IIR过滤器:

public static double[] Process(FilterWeights fw, double[] points)
{
    int len = points.Length;
    double[] b = fw.b;
    double[] a = fw.a;
    double[] pout = new double[len];
    for (int i = 7; i < len - 7; i++)
    {
        double bb = b[0] * points[i] + b[1] * points[i - 1] + b[2] * points[i - 2] + b[3] * points[i - 3] + b[4] * points[i - 4] + b[5] * points[i - 5] + b[6] * points[i - 6];
        double aa = a[1] * pout[i - 1] + a[2] * pout[i - 2] + a[3] * pout[i - 3] + a[4] * pout[i - 4] + a[5] * pout[i - 5] + a[6] * pout[i - 6];

        pout[i] = bb - aa;
    }
    return pout;
}

当我使用这些权重时:

double[] b = { 0.00127153313835457, 0, -0.0038145994150637, 0, 0.0038145994150637, 0, -0.00127153313835457 };
double[] a = { 1, -5.52631330458372, 12.7445836427234, -15.7022100579719, 10.9025543810024, -4.04524317719105, 0.626628537931204 };

该函数以0.1s

执行

当我使用这些

double[] b = { 0.990561854840211 / divider, -5.94337112904127 / divider, 14.8584278226032 / divider, -19.8112370968042 / divider, 14.8584278226032 / divider, -5.94337112904127 / divider, 0.990561854840211 / divider };
double[] a = { 1, -5.98103409448638 / divider, 14.9053502415818 / divider, -19.8110589417825 / divider, 14.8114163250404 / divider, -5.90588631861786 / divider, 0.98121278826448 / divider };

需要10秒钟。

我做了一次性能分析,确实是这一行:

double aa = a[1] * pout[i - 1] + a[2] * pout[i - 2] + a[3] * pout[i - 3] + a[4] * pout[i - 4] + a[5] * pout[i - 5] + a[6] * pout[i - 6];

在第二种情况下需要更长的时间。

我完全不知所措。我尝试截断数字,将它们除以1000和其他方法,但看起来数字中有一些东西会使计算量增加10倍!

第一组的重量是带有3阶的0.5-10hz带通过的butterworth滤波器。第二组的重量用于0.2hz的高通滤波器,顺序为6.有意义的是,高阶滤波器需要更长的时间,但我无法解释实际数字如何影响双倍乘,即使所有权重除以较大因子也是如此。

1 个答案:

答案 0 :(得分:0)

感谢Joshua Webb。 实际上,输入阵列具有NaN,这导致bb在一次迭代中有条件地变为NaN。一旦发生这种情况,所有随后的aa计算也会涉及并导致NaNs,这似乎比非NaN数字之间的正常乘法需要更长的时间。 从输入数组中删除所有NaN后,问题似乎已得到解决:D