Complex One-Dimensional DFTs
Plan:为实现意外结果的最佳方法而烦恼。 [Ambrose Bierce, The Enlarged Devil’s Dictionary。] FFTW 计算大小为 N 的一维 DFT 的基本用法很简单,它通常看起来像这样的代码:
#include <fftw3.h>
...
{
fftw_complex *in, *out;
fftw_plan p;
...
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
...
fftw_execute(p); /* repeat as needed */
...
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
您必须将此代码与 fftw3 库链接。 在 Unix 系统上,使用 -lfftw3 -lm 链接。 示例代码首先分配输入和输出数组。 您可以以任何您喜欢的方式分配它们,但我们建议使用 fftw_malloc,它的行为类似于 malloc,只是它在 SIMD 指令(如 SSE 和 Altivec)可用时正确对齐数组(参见第 3.1 节 [SIMD 对齐和 fftw malloc ],第 15 页)。 [或者,我们提供了一个方便的包装函数 fftw_alloc_complex(N),它具有相同的效果。] 数据是 fftw_complex 类型的数组,默认情况下是由实数 (in[i] [0]) 组成的 double[2] 和复数的虚数 (in[i] [1]) 部分。 下一步是创建一个计划,这是一个包含 FFTW 计算 FFT 所需的所有数据的对象。 此函数创建计划:
fftw_plan fftw_plan_dft_1d(int n, fftw_complex *in, fftw_complex *out, int sign, unsigned flags);
第一个参数 n 是您尝试计算的变换的大小。大小 n 可以是任何正整数,但作为小因子乘积的大小转换效率最高(尽管素数大小仍使用 O(n log n) 算法)。接下来的两个参数是指向转换的输入和输出数组的指针。这些指针可以相等,表示就地转换。第四个参数 sign 可以是 FFTW_FORWARD (-1) 或 FFTW_BACKWARD (+1),表示你感兴趣的变换方向;从技术上讲,它是变换中指数的符号。 flags 参数通常是 FFTW_MEASURE 或 FFTW_ESTIMATE。 FFTW_MEASURE 指示 FFTW 运行并测量几个 FFT 的执行时间,以便找到计算大小为 n 的变换的最佳方法。此过程需要一些时间(通常为几秒钟),具体取决于您的机器和转换的大小。相反,FFTW_ESTIMATE 不运行任何计算,只是构建一个可能不是最佳的合理计划。简而言之,如果您的程序执行许多相同大小的转换并且初始化时间并不重要,请使用 FFTW_MEASURE;否则使用估计。您必须在初始化输入之前创建计划,因为 FFTW_MEASURE 会覆盖输入/输出数组。 (从技术上讲,FFTW_ESTIMATE 不会触及您的数组,但您应该始终先创建计划以确保确定。)一旦创建了计划,您可以根据需要多次使用它来对指定的输入/输出数组进行转换,通过 fftw_execute(plan) 计算实际转换:
void fftw_execute(const fftw_plan plan);
DFT 结果按顺序存储在数组 out 中,零频率 (DC) 分量存储在 out[0] 中。 如果 in != out,则变换是不合适的,并且输入数组 in 不会被修改。 否则,输入数组将被转换覆盖。 如果要转换相同大小的不同数组,可以使用 fftw_plan_dft_1d 创建一个新计划,如果可能,FFTW 会自动重用先前计划中的信息。 或者,如果您小心的话,您可以使用“guru”界面将给定计划应用于不同的阵列。 请参阅第 4 章 [FFTW 参考],第 21 页。完成计划后,您可以通过调用 fftw_destroy_plan(plan) 来释放它:
void fftw_destroy_plan(fftw_plan plan);
FFTW 计算未归一化的 DFT。因此,计算前向变换和后向变换(反之亦然)会导致原始数组按 n 缩放。有关 DFT 的定义,请参见第 42 页第 4.8 节 [FFTW 真正计算的内容]。如果您有支持 C99 标准的 C 编译器,例如 gcc,并且您在 < fftw3> 之前#include <complex.h>,则 fftw_complex 是本机双精度复数类型,您可以使用普通算术对其进行操作。否则,FFTW 定义自己的复数类型,与 C99 复数类型位兼容。请参阅第 21 页的第 4.1.1 节 [复数]。(C++ < complex> 模板类也可以通过类型转换使用。)要使用 FFTW 的单精度或长双精度版本,请将 fftw_ 前缀替换为 fftwf_ 或 fftwl_并与 -lfftw3f 或 -lfftw3l 链接,但使用相同的 <fftw3.h> 头文件。除了 FFTW_MEASURE 和 FFTW_ESTIMATE 之外,还有更多的标志。例如,如果您愿意等待更长的时间以获得可能更快的计划,请使用 FFTW_PATIENT(参见第 4 章 [FFTW 参考],第 21 页)。您还可以保存计划以备将来使用,如第 3.3 节 [Words of Wisdom-Saving Plans],第 18 页所述.
Complex Multi-Dimensional DFTs
多维变换的工作方式与一维变换大致相同:分配 fftw_complex 数组(最好使用 fftw_malloc),创建 fftw_plan,使用 fftw_execute(plan) 执行任意多次,然后使用 fftw_destroy_plan 进行清理 (计划)(和 fftw_free)。 FFTW 提供了两个用于创建 2d 和 3d 变换计划的例程,以及一个用于创建任意维度计划的例程。 2d 和 3d 例程具有以下签名:
//二维
fftw_plan fftw_plan_dft_2d(int n0, int n1, fftw_complex *in, fftw_complex *out, int sign, unsigned</

FFTW是一个高效的C库,用于计算一维和多维的复数及实数离散傅立叶变换(DFTs)。在复数DFT中,FFTW提供fftw_plan_dft系列函数来创建计划并执行变换,支持就地转换和不同精度版本。对于实数DFT,有fftw_plan_dft_r2c和fftw_plan_dft_c2r函数,分别用于实数到复数和复数到实数的转换,且输出具有Hermitian对称性。多维DFT的处理方式类似,但输入和输出的数组大小和排列方式有所不同,尤其在就地转换时需要额外的填充。FFTW还支持多种类型的实数到实数(r2r)变换,如DCT/DST和DHT。
最低0.47元/天 解锁文章
7836

被折叠的 条评论
为什么被折叠?



