具有复数的C ++ FFTW(快速傅里叶变换)

时间:2016-01-12 18:13:06

标签: c++ fft fftw

我正在尝试在C ++中使用带复数的FFT。问题在于,当使用fftw_complex数字时,我无法使用常见的sintax制作内积或复数向量的总和。

这是一个简化的简化程序:

#include <complex.h>
#include <fftw3.h>


int main(void){

int n=1024;
    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);
//  out = 1*in;   /!\
//  out = in+0;  / ! \

    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);

    return 0;
}

评论的两行不起作用:

i)第一个在编译时给出:

test.cpp:13:10: error: invalid operands of types ‘int’ and ‘fftw_complex* {aka __complex__ double*}’ to binary ‘operator*’

ii)第二个在执行期间给出:

*** glibc detected *** ./prog: corrupted double-linked list: 0x09350030 ***

根据fftw.org [link]的文档,应该接受用于操纵fftw_complex的标准sintax。为什么不使用fftw_complex的向量?

例如,我想计算:

r = i*gamma_p*w/w0*m*exp(-l*z);

其中i是虚数; gamma_p,w0和z是实数; w,m和l是复数的向量。

我试过了:

    fftw_complex* i_NUMBER = (fftw_complex*) fftw_malloc(1*sizeof(fftw_complex));
memset(i_NUMBER, 0, n*sizeof(fftw_complex));
    i_NUMBER[0][0]=0;
    i_NUMBER[0][1]=1;   //#real(i_NUMBER)=0; imag(i_NUMBER)=1; i.e. i_NUMBER=i;
fftw_complex* r = (fftw_complex*) fftw_malloc(n*sizeof(fftw_complex));

for (int i=0; i<n; i++){
    r[i] = i_NUMBER[0]*gamma_p*w[i]/w0*m[i]*pow(e_NUMBER, -l[i]*z);
}

但编译器会提供有关操作数和操作类型的错误。

gnlse.h:58:22: error: invalid operands of types ‘fftw_complex {aka double [2]}’ and ‘double’ to binary ‘operator*’
gnlse.h:58:61: error: wrong type argument to unary minus

欢迎任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

你必须编写显式循环来处理向量。

out = in+0;将生成两个指向同一位置的指针。当您将其解除分配两次时,您将收到损坏的堆

更新

我想我知道可能是什么问题。默认的FFTW模式是C89。具有复数的自动计算几乎需要C99模式或使用<complex>标头的C ++。我猜你会选择一些例子,修改它并想知道为什么它不起作用。

在C89模式下,fftw_complex只是一个双倍[2]。因此,在C89模式下的任何表达都需要对真实和图像部分进行相当多的手动处理,这正是我提出的。不能混合表达强制指针复杂和双精度,功能和期望自动处理。

在C99模式中,你可以得到本地复合体,这使得在表达中与它们一起工作是一个真正的对待C89。

C ++本机复合体也应该可以正常工作。

有关详细说明,请参阅http://www.fftw.org/doc/Complex-numbers.html

我猜您现在已经在C89模式下有效了。您必须使用C99(通常在linux / usr / bin / c99上)编译示例,或者转移到C ++并沿着该行使用C ++本机复合体

#include <complex>

...

std::complex<double>* in  = new std::complex<double>[n];
std::complex<double>* out = new std::complex<double>[n];
...
p = fftw_plan_dft_1d(n,
                     reinterpret_cast<fftw_complex*>(in),
                     reinterpret_cast<fftw_complex*>(out),
                     FFTW_FORWARD, FFTW_ESTIMATE);
...