傅里叶级数求和的快速方法?
我已经使用 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;
}
有更快的方法吗?
I have generated the coefficients using FFTW, now I want to reconstruct the original data, but using only the first numCoefs
coefficients rather than all of them. At the moment I'm using the below code, which is very slow:
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;
}
Is there a faster way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一个更简单的解决方案是将不需要的系数归零,然后使用 FFTW 进行 IFFT。这将比上面进行 IDFT 更有效。
请注意,当您执行此类操作时,您可能会在时域中得到一些伪像 - 您实际上是在频域中乘以阶跃函数,这相当于在时域中与 sinc 函数进行卷积。为了减少时域中产生的“振铃”,您应该使用窗函数来平滑非零系数和零系数之间的过渡。
A much simpler solution would be to zero the unwanted coefficients and then do an IFFT with FFTW. This will be a lot more efficient than doing an IDFT as above.
Note that you may get some artefacts in the time domain when you do this kind of thing - you're effectively multiplying by a step function in the frequency domain, which is equivalent to convolution with a sinc function in the time domain. To reduce the resulting "ringing" in the time domain you should use a window function to smooth out the transition between non-zero and zero coeffs.
如果您的 numCoefs 接近或大于 log(length),那么 IFFT(计算复杂度为 O(n*log(n)))很可能会更快,并且预- 为您优化。只需将除您想要保留的系数之外的所有箱归零,并且如果您想要真实的结果,请确保也保留它们的负频率复共轭。
如果您的
numCoefs
相对于 log(length) 较小,那么您可以尝试的其他优化包括使用sinf()
和cosf()
如果您实际上并不需要超过 6 位的精度,并且在内循环之外预先计算 omega*i (尽管您的编译器应该为您执行此操作,除非您的优化设置较低或关闭)。If your
numCoefs
is anywhere near or greater than log(length), then an IFFT, which is O(n*log(n)) in computational complexity, will most likely be faster, as well as pre-optimized for you. Just zero all the bins except for the coefficients you want to keep, and make sure to also keep their negative frequency complex conjugates as well if you want a real result.If your
numCoefs
is small relative to log(length), then other optimizations you could try include usingsinf()
andcosf()
if you don't really need more than 6 digits of precision, and pre-calculating omega*i outside the inner loop (although your compiler should do be doing that for you unless you have the optimization setting low or off).