如何在 FFTW 库中进行实数反演 FFT

发布于 2024-10-07 09:23:49 字数 880 浏览 12 评论 0原文

我正在尝试使用 FFT 进行一些过滤。我正在使用 r2r_1d 计划,但我不知道如何进行逆变换...

    void PerformFiltering(double* data, int n)
    {
                    /* FFT */
        double* spectrum = new double[n];

        fftw_plan plan;

        plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT00, FFTW_ESTIMATE);

        fftw_execute(plan); // signal to spectrum
        fftw_destroy_plan(plan); 


                    /* some filtering here */


                    /* Inverse FFT */
        plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT00, FFTW_ESTIMATE);
        fftw_execute(plan); // spectrum to signal (inverse FFT)
        fftw_destroy_plan(plan);

}

我做的所有事情都正确吗?我很困惑,因为在 FFTW 复杂的 DFT 中,您可以通过标志设置变换方向,如下所示:
p = fftw_plan_dft_1d(N, 输入, 输出, FFTW_FORWARD, FFTW_ESTIMATE);

p = fftw_plan_dft_1d(N, 输入, 输出, FFTW_BACKWARD, FFTW_ESTIMATE);

I'm trying to do some filtering with FFT. I'm using r2r_1d plan and I have no idea how to do the inverse transform...

    void PerformFiltering(double* data, int n)
    {
                    /* FFT */
        double* spectrum = new double[n];

        fftw_plan plan;

        plan = fftw_plan_r2r_1d(n, data, spectrum, FFTW_REDFT00, FFTW_ESTIMATE);

        fftw_execute(plan); // signal to spectrum
        fftw_destroy_plan(plan); 


                    /* some filtering here */


                    /* Inverse FFT */
        plan = fftw_plan_r2r_1d(n, spectrum, data, FFTW_REDFT00, FFTW_ESTIMATE);
        fftw_execute(plan); // spectrum to signal (inverse FFT)
        fftw_destroy_plan(plan);

}

Am I doing all the things right? I'm confused because in FFTW complex DFT's you can set a transform direction by flag like this:
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
or
p = fftw_plan_dft_1d(N, in, out, FFTW_BACKWARD, FFTW_ESTIMATE);

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

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

发布评论

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

评论(2

写给空气的情书 2024-10-14 09:23:49

http://www.fftw.org/fftw3_doc/Real_002dto_002dReal-Transform-Kinds.html

http://www.fftw.org/fftw3_doc/1d -Real_002deven-DFTs-_0028DCTs_0029.html

“种类”指定方向。

(另请注意,您可能希望通过除以 n 来重新归一化信号。FFTW 的归一化约定在变换及其逆之后乘以 n。)

http://www.fftw.org/fftw3_doc/Real_002dto_002dReal-Transform-Kinds.html

http://www.fftw.org/fftw3_doc/1d-Real_002deven-DFTs-_0028DCTs_0029.html

The "kind" specifies the direction.

(Note also that you'll probably want to renormalize your signal by dividing by n. The normalization convention of FFTW multiplies by n after a transform and its inverse.)

明月松间行 2024-10-14 09:23:49

你做对了。 FFTW_REDFT00 表示余弦变换,它是其自身的逆变换。所以不需要区分“向前”和“向后”。但是,请注意数组大小。如果您要检测频率为 10,并且您的数据包含 100 个有意义的点,则数组 data 应保存 101 个数据点,并设置 n = 101 而不是 100。标准化应为 2*(n-1)。请参阅下面的示例,使用 gcc ac -lfftw3 进行编译。

#include <stdio.h>
#include <math.h>
#include <fftw3.h>
#define n 101 /* note the 1 */
int main(void) {
  double in[n], in2[n], out[n];
  fftw_plan p, q;
  int i;
  p = fftw_plan_r2r_1d(n, in, out, FFTW_REDFT00, FFTW_ESTIMATE);
  for (i = 0; i < n; i++) in[i] = cos(2*M_PI*10*i/(n - 1)); /* n - 1 instead of n */
  fftw_execute(p);
  q = fftw_plan_r2r_1d(n, out, in2, FFTW_REDFT00, FFTW_ESTIMATE);
  fftw_execute(q);
  for (i = 0; i < n; i++)
    printf("%3d %9.5f %9.5f\n", i, in[i], in2[i]/(2*(n - 1))); /* n - 1 instead of n */
  fftw_destroy_plan(p); fftw_destroy_plan(q); fftw_cleanup();
  return 0;
}

You did it correctly. FFTW_REDFT00 means the cosine transform, which is its own inverse. So there is no need to distinguish "forward" and "backward." However, be careful about the array size. If you want to detect a frequency of 10, and your data contains 100 meaningful points, then the array data should hold 101 data points, and set n = 101 instead of 100. The normalization should be 2*(n-1). See the example below, compile with gcc a.c -lfftw3.

#include <stdio.h>
#include <math.h>
#include <fftw3.h>
#define n 101 /* note the 1 */
int main(void) {
  double in[n], in2[n], out[n];
  fftw_plan p, q;
  int i;
  p = fftw_plan_r2r_1d(n, in, out, FFTW_REDFT00, FFTW_ESTIMATE);
  for (i = 0; i < n; i++) in[i] = cos(2*M_PI*10*i/(n - 1)); /* n - 1 instead of n */
  fftw_execute(p);
  q = fftw_plan_r2r_1d(n, out, in2, FFTW_REDFT00, FFTW_ESTIMATE);
  fftw_execute(q);
  for (i = 0; i < n; i++)
    printf("%3d %9.5f %9.5f\n", i, in[i], in2[i]/(2*(n - 1))); /* n - 1 instead of n */
  fftw_destroy_plan(p); fftw_destroy_plan(q); fftw_cleanup();
  return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文