I am trying to use FFT with complex numbers in C++. The problem is that I cannot make inner products, or sums of complex vectors with a common sintax, when using fftw_complex numbers.
Here is a reduced simple program:
#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;
}
The two lines that are commented do not work:
i) the 1st one gives, when compiling:
test.cpp:13:10: error: invalid operands of types ‘int’ and ‘fftw_complex* {aka __complex__ double*}’ to binary ‘operator*’
ii) the 2nd one gives, during the execution:
*** glibc detected *** ./prog: corrupted double-linked list: 0x09350030 ***
Accordingly to the documentation of fftw.org [link] , standard sintax for manipulating fftw_complex should be accepted. Why not with vectors of fftw_complex?
For instance, I want to compute:
r = i*gamma_p*w/w0*m*exp(-l*z);
where i is the imaginary number; gamma_p, w0, and z are real numbers; w, m, and l are vectors of complex numbers.
I tried:
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);
}
but the compiler gives errors about the types of operands and operations.
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
Any help is welcome, thanks!
You have to write explicit loops to works with vectors.
Line out = in+0;
will produce two pointer pointing to the same location. When you deallocation it twice, you'll get corrupted heap
UPDATE
I think I know what problem might be. Default FFTW mode is C89. Automatic computations with complex numbers pretty much require either C99 mode or C++ using <complex>
header. I would guess you picked some example, modified it and wondering why it doesn't work.
In C89 mode fftw_complex is just a double[2]. So any expression in C89 mode requires pretty much manual handling of the real and imag part, just what I proposed. Cannot mix in expression coerced-to-pointer complex and doubles, functions and expect automatic handling.
In C99 mode you could get native complex which makes working with them in expression a real treat wrt C89.
C++ native complex should work as well.
See http://www.fftw.org/doc/Complex-numbers.html for a detailed description.
My guess you're now effectively in C89 mode. You have to compile the example either with C99 (typically on linux /usr/bin/c99), or move to C++ and use C++ native complex along the line
#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);
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.