我正在尝试在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
欢迎任何帮助,谢谢!
答案 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);
...