DSPRelated.com
Forums

input to FFTW

Started by seia0106 May 10, 2004
Hello I am trying to write a simple program to use FFTW to find FFT of
both real and complex inputs.
my test input array is 
A={1,0,1,-1,0,1,0,-1}

Now I used the example in documentation and wrote the following
program but it is not giving the correct results.  Also when i use
this program for real inputs using fftw_plan_dft_r2c_1d() method,
results are wrong. Can someone please help find out what am I doing
wrong here? Here is the program.
Thanks in advance.

#include <fftw3.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>

double A[8]={0,0,1,0,0,0,-1,0,0,0,1,0,0,0,-1,0};
int N=8;
main()
{
fftw_plan p;
fftw_complex *in;
fftw_complex *out;

//memory allocation
out=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N);
in=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N);

//for filling the input array
for(int ii=0;ii<8;ii++){
in[0][ii]=A[j];
std::cout<<in[0][ii]<<std::endl;
j++;
}

//plan creation and exection
p=fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_ESTIMATE);
fftw_execute(p);

//resources deallocation
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
seia0106 wrote:
> Hello I am trying to write a simple program to use FFTW to find FFT of > both real and complex inputs. > my test input array is > A={1,0,1,-1,0,1,0,-1}
[snip]
> fftw_plan p; > fftw_complex *in; > fftw_complex *out; > > //memory allocation > out=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N); > in=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N); > > //for filling the input array > for(int ii=0;ii<8;ii++){ > in[0][ii]=A[j]; > std::cout<<in[0][ii]<<std::endl; > j++; > }
You've successfully demonstrated one of the pitfalls of using an array as a representation for complex data. :) I think you want to use in[ii][0] instead of in[0][ii] The latter address the ii'th element of the zeroth element of in, which is an array of size two. There may be some ultra paranoid compiler tag that would catch this, but it would also warn about a lot of correct code. If you can live with roughly half the speed of fftw, you may want to take a look at the kissfft project on sourceforge.net. I built it with simplicity and extensibility in mind. It compiles to a fraction of fftw's code size. It handles fixed point and uses a BSD style license, i.e. you can include it in a commercial/closed source product. If none of that is as important to you as speed, then stick with fftw. It's good and fast. Hope this helps, -- Mark
Mark Borgerding <mark@borgerding.net> wrote...
> You've successfully demonstrated one of the pitfalls of using an array > as a representation for complex data. :)
We used a struct with .re and .im fields in FFTW 2, but people complained that this wasn't guaranteed to be bit-compatible with C99 complex numbers (or C++ complex numbers, which nowadays are supposed to follow the C99 format), since a struct can theoretically have padding. Sigh...if only more compilers supported C99 types. (Although the only example I've seen raised where the struct wasn't equivalent to a float[2] or double[2] was on obsolete Cray hardware.) Steven
Mark Borgerding <mark@borgerding.net> wrote in message news:<_eOnc.18$OE3.4@fe1.columbus.rr.com>...

> > > You've successfully demonstrated one of the pitfalls of using an array > as a representation for complex data. :) > > I think you want to use > in[ii][0] instead of > in[0][ii] > > The latter address the ii'th element of the zeroth element of in, which > is an array of size two. There may be some ultra paranoid compiler tag > that would catch this, but it would also warn about a lot of correct code. > > If you can live with roughly half the speed of fftw, you may want to > take a look at the kissfft project on sourceforge.net. I built it with > simplicity and extensibility in mind. It compiles to a fraction of > fftw's code size. It handles fixed point and uses a BSD style license, > i.e. you can include it in a commercial/closed source product. > > If none of that is as important to you as speed, then stick with fftw. > It's good and fast. > > > Hope this helps, > -- Mark
Thanks for the reply Mark, Well. I tried as you suggested(in[ii][0]) but it raised a runtime error.
miahmed67@yahoo.com (seia0106) wrote...
> Thanks for the reply Mark, > Well. I tried as you suggested(in[ii][0]) but it raised a runtime error.
I can't imagine what it would be...aside from the fact that the code sample you posted was riddled with syntax errors ('j' is undeclared, and there are too many initializers in A[8]), was missing <iostream>, and you neglected to initialize the imaginary parts of the input array. Once those errors are corrected (along with the one Mark noted), it works fine for me (Linux/g++, and passes valgrind). Steven
Thanks for the reply. Here is the code which is not giving the results
that i get with Matlab.

#include <fftw3.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>
int j;
double A[8]={0,1,0,-1,0,1,0,-1};
int N=8;
void main()
{
fftw_plan p;
fftw_complex *in;
fftw_complex *out;

//memory allocation
out=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N);
in=(fftw_complex*)fftw_malloc(sizeof(fftw_complex)*N);

//for filling the input array
for(int ii=0;ii<N;ii++){
in[ii][0]=A[j];
in[0][ii]=0;

std::cout<<in[ii][0]<<std::endl;
std::cout<<in[0][ii]<<std::endl;
j++;
} getch();

//plan creation and exection
p=fftw_plan_dft_1d(N,in,out,FFTW_FORWARD,FFTW_ESTIMATE);
fftw_execute(p);

for (int iii=0;iii<N;iii++){
std::cout<<out[iii][0]<<std::endl;
std::cout<<out[0][iii]<<std::endl;
}getch();
//resources deallocation
fftw_destroy_plan(p);
fftw_free(in);
fftw_free(out);
}
miahmed67@yahoo.com (seia0106) wrote...
> for(int ii=0;ii<N;ii++){ > in[ii][0]=A[j]; > in[0][ii]=0;
This makes no sense...the real and imaginary parts are stored in in[ii][0] and in[ii][1] (a similar error appears elsewhere). This is not about DSP, nor is it about FFTW, it's about elementary C programming. You need to learn to debug your own code, or stick with Matlab. Once you fix your bugs, the code works fine and gives the correct result. No, I'm not going to send you the corrected code. Regards, Steven G. Johnson
stevenj@alum.mit.edu (Steven G. Johnson) wrote in message news:<27cfb406.0405121641.635ccad9@posting.google.com>...
> > > Once you fix your bugs, the code works fine and gives the correct > result. No, I'm not going to send you the corrected code. > > Regards, > Steven G. Johnson
Hi Steven, Thanks. No need to send the corrected code. You have taught me something. You were right that i had problem(or confusion) with the representation of complex numbers in C and C++. The FFTW program is giving the correct results now. Thanks again and have a nice weekend.