gpt4 book ai didi

c++ - 使用 Eigen 和 FFTW 进行二维傅里叶变换

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:44:00 33 4
gpt4 key购买 nike

我正在尝试使用 FFTW 进行实值二维傅立叶变换。我的数据存储在动态大小的特征矩阵中。这是我写的包装器类:

FFT2D.h:

#include <Eigen>

class FFT2D {
public:

enum FFT_TYPE {FORWARD=0, REVERSE=1};
FFT2D(EMatrix &input, EMatrix &output, FFT_TYPE type_ = FORWARD);
~FFT2D();

void execute();

private:
EMatrix& input;
EMatrix& output;
fftw_plan plan;
FFT_TYPE type;
};

FFT2D.cpp:

#include "FFT2D.h"
#include <fftw3.h>
#include "Defs.h"


FFT2D::FFT2D(EMatrix &input_, EMatrix &output_, FFT_TYPE type_)
: type(type_), input(input_), output(output_) {

if (type == FORWARD)
plan = fftw_plan_dft_2d((int) input.rows(), (int) input.cols(),
(fftw_complex *) &input(0), (fftw_complex *) &output(0),
FFTW_FORWARD, FFTW_ESTIMATE);
else
// placeholder for ifft-2d code, unwritten
}


FFT2D::~FFT2D() {
fftw_destroy_plan(plan);
}

void FFT2D::execute() {
fftw_execute(plan); // seg-fault here
}

EMatrix 的定义:

typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> EMatrix;

问题是,我在 FFT2D::execute() 中遇到段错误。我知道我在构造函数中设置了错误,并且我尝试了多种不同的方法,但我似乎无法在这方面取得任何进展。

我尝试过的事情包括:将 EMatrix typedef 更改为 Eigen::ColMajor,传递 (fftw_complex *) input.data()fftw_plan_dft_2d,使用不同的 fftw 计划 (fftw_plan_dft_r2c_2d)。

我的 C++(显然)生锈了,但归根结底,我需要在 double 的实值二维特征矩阵上进行二维傅里叶变换。提前致谢。

最佳答案

这里的主要问题是没有“实值傅里叶变换”这样的东西。它只是虚部为零的东西的傅立叶变换,但零仍然必须存在,正如您从 fftw_complex 中看到的那样定义:

typedef double fftw_complex[2];

这是有道理的,因为输出可以(并且可能会)具有非零虚部。
虽然输出将具有一些对称属性,即在一维变换的情况下它将是偶函数。

因此 (fftw_complex *) &input(0) cast 并没有真正起作用 - FFTW 期望两倍 double传递给它的值。

解决方案是将矩阵原始数据与零交错,有多种方法可以做到这一点。几个例子:

  • 您可以将整个矩阵复制到一个新数组中,然后再将其传递给 FFTW,并在过程中添加零。
  • 您可以在矩阵本身中为零保留空间 - 这样您就可以避免复制,但它可能需要大量重构:)
  • 我能想到的最好方法是使用 std::complex<double>作为标量。这会在某种程度上损害您对“实值 FFT”的注意,但同样一开始几乎没有这样的事情。相反,您将能够保持所有实际值(value)操作的原样,以及 std::complex 的布局。适合 fftw_complex完美。

这里可能还有其他一些事情需要考虑,比如存储顺序(FFTW 按行优先顺序在数组上运行,因此特征矩阵应该符合)和线性访问特征矩阵数据的有效性(对我来说似乎没问题)。

关于c++ - 使用 Eigen 和 FFTW 进行二维傅里叶变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42967508/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com