FFTW:前向 fft 的逆函数不等于原始函数

发布于 2024-09-19 00:03:45 字数 1469 浏览 1 评论 0原文

我正在尝试使用 FFTW 来计算快速求和,但遇到了一个问题:(

int numFreq3 = numFreq*numFreq*numFreq;

FFTW_complex* dummy_sq_fft = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_complex* dummy_sq = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_complex* orig = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_plan dummyPlan = FFTW_plan_dft_3d( numFreq, numFreq, numFreq,
                  orig, dummy_sq_fft,
                  FFTW_FORWARD, FFTW_MEASURE );

FFTW_plan dummyInvPlan = FFTW_plan_dft_3d( numFreq, numFreq, numFreq,
                      dummy_sq_fft, dummy_sq,
                      FFTW_BACKWARD, FFTW_MEASURE );

for(int i= 0; i < numFreq3; i++) {
  orig[ i ][ 0 ] = sparseProfile02[ 0 ][ i ][ 0 ];
  //img. part == 0
  orig[ i ][ 1 ]  = sparseProfile02[ 0 ][ i ] [ 1 ];
}

FFTW_execute(dummyPlan);
FFTW_execute(dummyInvPlan);

int count = 0; 
for(int i=0; i<numFreq3; i++) {
  double factor = dummy_sq[ i ][ 0 ]/sparseProfile02[ 0 ][ i ][ 0 ];

  if(factor < 0) {
    count++;
  }
}

std::cout<<"Count "<<count<<"\n";

FFTW_free(dummy_sq_fft);
FFTW_free(dummy_sq);
FFTW_destroy_plan(dummyPlan);
FFTW_destroy_plan(dummyInvPlan);

这里稀疏Profile02[0] 的类型为 FFTW_complex*,并且仅包含正实数据。)

因为我们有 dummy_sq = IFFT(FFT( SparseProfile02[ 0 ])),我们必须有 dummy_sq = n^3*sparseProfile02。但这只是在某些时候是正确的。事实上,只要稀疏Profile02 网格上的相应值为零(但反之则不然),dummy_sq 网格上的值就是负数。有谁知道为什么会发生这种情况?

I'm trying to use FFTW to compute fast summations, and I've run into an issue:

int numFreq3 = numFreq*numFreq*numFreq;

FFTW_complex* dummy_sq_fft = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_complex* dummy_sq = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_complex* orig = (FFTW_complex*)FFTW_malloc( sizeof(FFTW_complex)*numFreq3 );

FFTW_plan dummyPlan = FFTW_plan_dft_3d( numFreq, numFreq, numFreq,
                  orig, dummy_sq_fft,
                  FFTW_FORWARD, FFTW_MEASURE );

FFTW_plan dummyInvPlan = FFTW_plan_dft_3d( numFreq, numFreq, numFreq,
                      dummy_sq_fft, dummy_sq,
                      FFTW_BACKWARD, FFTW_MEASURE );

for(int i= 0; i < numFreq3; i++) {
  orig[ i ][ 0 ] = sparseProfile02[ 0 ][ i ][ 0 ];
  //img. part == 0
  orig[ i ][ 1 ]  = sparseProfile02[ 0 ][ i ] [ 1 ];
}

FFTW_execute(dummyPlan);
FFTW_execute(dummyInvPlan);

int count = 0; 
for(int i=0; i<numFreq3; i++) {
  double factor = dummy_sq[ i ][ 0 ]/sparseProfile02[ 0 ][ i ][ 0 ];

  if(factor < 0) {
    count++;
  }
}

std::cout<<"Count "<<count<<"\n";

FFTW_free(dummy_sq_fft);
FFTW_free(dummy_sq);
FFTW_destroy_plan(dummyPlan);
FFTW_destroy_plan(dummyInvPlan);

(Here sparseProfile02[0] is of type FFTW_complex*, and contains only positive real data.)

Since we have dummy_sq = IFFT(FFT(sparseProfile02[ 0 ])), we must have dummy_sq = n^3*sparseProfile02. But this is true only some of the time; in fact, values on the dummy_sq grid are negative whenever corresponding values on the sparseProfile02 grid are zero (but not vice-versa). Does anyone know why this is happening?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘香 2024-09-26 00:03:45

冒着涉足死灵术的风险,您应该在 fftw 文档(此处)中注意到,它明确指出 fftw 不会标准化,因此先前变换信号的逆变换结果将是按“n”缩放的原始信号或信号的长度。

可能是问题所在。

At the risk of dabbling in necromancy, you should note in the fftw docs (here) that it expressly states that fftw does not normalize, thus the result of the inverse transform of a previously transformed signal will be the original signal scaled by 'n' or the length of the signal.

Could be the problem.

格子衫的從容 2024-09-26 00:03:45

FFT(正向和反向)有舍入误差,我认为这就是困扰您的问题。一般来说,您不应期望零在整个过程中始终保持为零(尽管对于简单的测试用例它可能为零)。在您的测试循环中,

fabs(dummy_sq[i][0] - numFreq*numFreq*numFreq*sparseProfile02[0][i][0])

相对于数据量而言是否很大?

作为一个非常简单(病态)的示例,仅使用实值大小为 2 的 1D FFT:

ifft(fft([1e20, 1.0])) != [2e20, 2.0]

1.0 在双精度 FFT 的 1e20 中丢失。

当您除以稀疏Profile02 中的零样本时,您也可能会得到一些 NaN。

The FFTs (forward and inverse) have rounding error, and I think this is what's biting you. In general, you shouldn't expect a zero to stay exactly zero through your process (although it could be zero for trivial test cases). In your test loop, is

fabs(dummy_sq[i][0] - numFreq*numFreq*numFreq*sparseProfile02[0][i][0])

large relative to the magnitude of your data?

As a really simple (pathological) example with just a 1D FFT of size 2 with real values:

ifft(fft([1e20, 1.0])) != [2e20, 2.0]

The 1.0 is lost in the 1e20 with a double precision FFT.

It's also possible you're getting some NaNs for factor when you divide by a zero sample in sparseProfile02.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文