-
need help with fftw..
I am trying to get a complex to complex fourier transform using fftw..
I first allocate space for 16 complex numbers. I initialise them to random numbers and then i perfrom the transform...
I am aware of the fact that in a complex to real mapping, the size of the output array is half the size of hte input array..
take a look at the output i have pasted here. i am getting all elements whose index is greater than (input array size)/2 to be zeros...
is this a valid output or have i done anything wrong..
Also, I have never used a complex array before, have i dealt with the initialisation correctly?
Code:
# include<complex.h>
# include<fftw3.h>
# include<time.h>
# include<math.h>
# define m 16
int main(int argc ,char *argv[])
{
int rc,i,j,sender,tag,number=0;
fftw_complex *in;
fftw_complex *out,*indexin,*indexout;
int count=0,sta,end,myid,nprocs;
double time1,time2;
fftw_plan p;
in=(complex *)(fftw_malloc(sizeof(complex)*m));
out=(complex *)(fftw_malloc(sizeof(complex)*m));
indexin=in;
indexout=out;
for(i=0;i<m;i++)
{
*in=rand();
printf("%d\t%f + i" ,i,*in++);
*in=rand();
printf(" %f\n",*in++);
}
in=indexin;
p=fftw_plan_dft_1d(m,in,out,FFTW_FORWARD,FFTW_ESTIMATE);
printf("\noutput array \n");
fftw_execute(p);
// out=indexout;
for(j=0;j<m;j++)
{
printf("%d\t%f +i ",j,*out++);
printf("%f\n",*out++);
}
printf("time consumed =%f\n",time2-time1);
fftw_destroy_plan(p);
fftw_free(indexin);
fftw_free(indexout);
return 0;
}
this is the output i am getting :
output:
Code:
0 1804289383.000000 + i 846930886.000000
1 1681692777.000000 + i 1714636915.000000
2 1957747793.000000 + i 424238335.000000
3 719885386.000000 + i 1649760492.000000
4 596516649.000000 + i 1189641421.000000
5 1025202362.000000 + i 1350490027.000000
6 783368690.000000 + i 1102520059.000000
7 2044897763.000000 + i 1967513926.000000
8 1365180540.000000 + i 1540383426.000000
9 304089172.000000 + i 1303455736.000000
10 35005211.000000 + i 521595368.000000
11 294702567.000000 + i 1726956429.000000
12 336465782.000000 + i 861021530.000000
13 278722862.000000 + i 233665123.000000
14 2145174067.000000 + i 468703135.000000
15 1101513929.000000 + i 1801979802.000000
output array
0 20859332864.000000 +i 2984769599.594296
1 410609648.520185 +i -1165990454.966789
2 -329755773.000000 +i 779267800.640235
3 -1091230550.520185 +i 2233043990.732258
4 367868742.000000 +i 2233043990.732258
5 -1091230550.520185 +i 779267800.640235
6 -329755773.000000 +i -1165990454.966789
7 410609648.520185 +i 2984769599.594296
8 0.000000 +i 0.000000
9 0.000000 +i 0.000000
10 0.000000 +i 0.000000
11 0.000000 +i 0.000000
12 0.000000 +i 0.000000
13 0.000000 +i 0.000000
14 0.000000 +i 0.000000
15 0.000000 +i 0.000000
-
Are you clobbering memory? Take this snippet:
Code:
for(i=0;i<m;i++)
{
*in=rand();
printf("%d\t%f + i" ,i,*in++);
*in=rand();
printf(" %f\n",*in++);
}
Unless I've missed something, you increment variable in 32 times, but you've only allocated space for 16.
Also, can you do a (complex) = rand() ? What is type complex?
-
from the man pages of fftw:
[ code]
The data is an array of type fftw_complex, which is by default a double[2] composed of the real (in[i][0]) and imaginary (in[i][1]) parts of a complex number.
[/code]
But, they havent described as to how complex types are stored in memory..
I think extending the way normal arrays are allocated , this would be happening :
the real part of the firlst complex number will be at in,
the imaginary part of the first would be at (in + 1)
the real part of the 2nd complex number will be ar (in+2) so on...
is this wrong??
if not ,if i have created an array of 16 complex numbers, there should be 32 reals in this array..
-
I am not too sure about doing (complex)= rand() or something of that kind.. ok will try.. thats why i am loading the real and imaginary parts separately..
-
> in=(complex *)(fftw_malloc(sizeof(complex)*m));
Do you really need that cast?
> for(i=0;i<m;i++)
Instead of messing about with pointer increment, and perhaps also messing up the save/restore of your pointers, how about
Code:
for(i=0;i<m;i++) {
in[i][0]=rand();
in[i][1]=rand();
}
Use the same idea when you print them as well.
-
surprisingly ,this is what i got ,when i did what u asked me to do:
Code:
fourier_sc.c:37: error: subscripted value is neither array nor pointer
it is pointing to the line
referencing "malloc"ed arrays like this is legal, isnt it??
and i removed the type casting thing.. i still get the same thing..
I have included stdlib.h ..so, that should not be the problem
-
OK, how about pasting what those types really are?
-
-
will this suffice:
"
The data is an array of type fftw_complex, which is by default a double[2] composed of the real (in[i][0]) and imaginary (in[i][1]) parts of a complex number.
If you have a C compiler, such as gcc, that supports the recent C99 standard, and you #include <complex.h> before <fftw3.h>, then fftw_complex is the native double-precision complex type and you can manipulate it with ordinary arithmetic. "
-
> which is by default a double[2]
Which is why I suggested [0] and [1] subscripts.
But then you turn around and say that doesn't work.
So what is it?
I guess you need to go read up on C99 and find out how the C99 complex type works.
-
well ,this is what i cud dig up :
Code:
complex number
/* complex in C99 is a built-in data type.
complex in C++ is a class. They are not compatible.
A program using complex conforming either C99 or C++ can readily run
in Ch without modification. */
#include <stdio.h>
#include <complex.h>
int main() {
double complex z1 = 1+I*2; // C99 and Ch
double_complex z2 = double_complex(1, 2); // C++ and Ch
double complex z3 = complex(1, 2); // Ch
double complex sz1, sz2, sz3;
sz1 = csqrt(z1); // C99 and Ch
sz2 = sqrt(z2); // C++ and Ch
sz3 = sqrt(z3); // C++ and Ch
printf("sz1 = %f, %f\n", creal(sz1), cimag(sz1)); // C99 and Ch
printf("sz2 = %f, %f\n", real(sz2), imag(sz2)); // C++ and Ch
printf("sz3 = %f\n", sz3); // Ch, added for users's convenience
}
--------------------------------------------------------------------------------
The output is:
sz1 = 1.272020, 0.786151
sz2 = 1.272020, 0.786151
sz3 = complex(1.272020,0.786151)
i cant do any kind of testing for the next 8 hrs or so.. will doing something like this help :
Code:
# include<complex.h>
# include<fftw3.h>
.............................
............................
int j;
fftw_complex *in,*out;
in=malloc(sizeof(fftw_complex)*16);
for( j=0;j<16;j++)
in[j] = rand() + I * rand();
.................................
................................ / * doing all the fftw stuff here */
/* the out put is stored in out */
for(j=0;j<16;j++)
printf("%d\t%f + I * %f\n", j,creal(out[j]), cimag(out[j]);
..............................
..................................