#include<stdio.h>
#include<fftw3.h>
#include<math.h>
#include <stdlib.h>
int main(){
int N=2000;
int i,j;
FILE *filepointer;
filepointer=fopen("2DDFT_spacetime.plt","w");
//double in[N][N];
double *in;
fftw_complex *out;
fftw_plan p;
double fx=13.0;
double fz=9.0;
double x[N];
double xstart=0.0;
double xend=5.0/fx;
double z[N];
double zstart=0.0;
double zend=5.0/fz;
double dx=(xend-xstart)/(N-1);
double dz=(zend-zstart)/(N-1);
x[0]=xstart;
z[0]=zstart;
in = (double*) malloc(sizeof(double) * N * N); //allocates input array
out = fftw_alloc_complex(N*((int)floor(N/2)+1)); //wrapper function ;allocates output array
p = fftw_plan_dft_r2c_2d(N,N, in, out, FFTW_MEASURE);
for(i=1;i<N;i++) {
x[i]=x[i-1]+dx;
}
for(i=1;i<N;i++) {
z[i]=z[i-1]+dz;
}
for(i=0;i<N;i++) {
for(j=0;j<N;j++) {
in[i*N+j]=cos(2*M_PI*fx*x[i]+2*M_PI*fz*z[j]);
}
}
fftw_execute(p);
fprintf(filepointer,"TITLE =\"FFTW\"\nVARIABLES=\"Wavenumber-x\"\n\"Wavenumber-z\"\n\"Amplitude\"\nZONE T=\"Amplitude\"\n I=%d, J=%d, K=1, ZONETYPE=Ordered\n DATAPACKING=POINT\n DT=(SINGLE SINGLE SINGLE)\n",N,(int)floor(N/2)+1);
for(j=0;j<(int)floor(N/2)+1;j++) {
for(i=0;i<N;i++) {
fprintf(filepointer," %.9E %.9E %.9E\n",i/(xend-xstart),j/(zend-zstart),sqrt(pow(out[i*((int)floor(N/2)+1)+j][0],2)+pow(out[i*((int)floor(N/2)+1)+j][1],2)));
}
}
fftw_destroy_plan(p);
free(in);
fftw_free(out);
fclose(filepointer);
return(1);
}
I begin by allocating memory for a NxN double array and a NxN fftw_complex array, which is defined as typedef double fftw_complex[2]
in the FFTW library. I assign real numbers to the array of doubles, do the real to complex FFT, and get the output in the array of fftw_complex.
Should I access the real and imaginary parts of the output complex number as out[i*((int)floor(N/2)+1)+j][0]
and out[i*((int)floor(N/2)+1)+j][1]
respectively?
[0]
to be real and[1]
to be complex? Also, C has built-in support for complex numbers since forever, so the best solution is to drop the icky custom types in favour for standard C. – Lundindouble *in;
todouble (*in)[N];
. - Change malloc toin = malloc(sizeof(double) * N * N);
(remove the cast) - Access array byin[i][j]
. – Lundin[0]
is meant to be real and[1]
is meant to be complex, as mentioned in the documentation and confirmed by me with my experiments with 1D FFTW. Using the above program, I am now almost certain that the output variables must be accessed in the way I have mentioned in my question. – mmrbest