我使用FFTW生成系数,现在我想重建原始数据,但只使用第一个numCoefs
系数而不是全部系数。目前我正在使用下面的代码,这非常慢:
for ( unsigned int i = 0; i < length; ++i )
{
double sum = 0;
for ( unsigned int j = 0; j < numCoefs; ++j )
{
sum += ( coefs[j][0] * cos( j * omega * i ) ) + ( coefs[j][1] * sin( j * omega * i ) );
}
data[i] = sum;
}
有更快的方法吗?
答案 0 :(得分:6)
更简单的解决方案是将不需要的系数归零,然后使用FFTW进行IFFT。这将比上面的IDFT更有效率。
请注意,当您执行此类操作时,您可能会在时域中获得一些假象 - 您实际上是在频域中乘以阶跃函数,这相当于在s中使用sinc函数进行卷积。时域。为了减少时域中产生的“振铃”,你应该使用一个窗函数来平滑非零和零系数之间的转换。
答案 1 :(得分:1)
如果你的numCoefs
接近或大于log(长度),则IFFT(计算复杂度为O(n * log(n))很可能会更快,也可能更快 - 为你优化。除了要保留的系数之外,只需将所有二进制数归零,并确保在需要实际结果的同时保持其负频率复数共轭。
如果您的numCoefs
相对于日志(长度)较小,那么您可以尝试的其他优化包括使用sinf()
和cosf()
,如果您实际上不需要超过6位数的精确,并在内循环之外预先计算omega * i(尽管你的编译器应该为你做这个,除非你的优化设置低或关闭)。