I am trying to get the PSD of a real data set by making use of fftw3
library
To test I wrote a small program as shown below ,that generates the a signal whic
Some remarks to your expected output function.
Your input is a function with pure real values. The result of a DFT has complex values. So you have to declare the variable out not as double but as fftw_complex *out.
In general the number of dft input values is the same as the number of output values. However, the output spectrum of a dft contains the complex amplitudes for positive frequencies as well as for negative frequencies.
In the special case for pure real input, the amplitudes of the positive frequencies are conjugated complex values of the amplitudes of the negative frequencies. For that, only the frequencies of the positive spectrum are calculated, which means that the number of the complex output values is the half of the number of real input values.
If your input is a simple sinewave, the spectrum contains only a single frequency component. This is true for 10, 100, 1000 or even more input samples. All other values are zero. So it doesn't make any sense to work with a huge number of input values.
If the input data set contains a single period, the complex output value is contained in out[1].
If the If the input data set contains M complete periods, in your case 5, so the result is stored in out[5]
I did some modifications on your code. To make some facts more clear.
#include
#include
#include
#include
#include "fftw3.h"
int performDFT(int nbrOfInputSamples, char *fileName)
{
int nbrOfOutputSamples;
double *in;
fftw_complex *out;
fftw_plan p;
// In the case of pure real input data,
// the output values of the positive frequencies and the negative frequencies
// are conjugated complex values.
// This means, that there no need for calculating both.
// If you have the complex values for the positive frequencies,
// you can calculate the values of the negative frequencies just by
// changing the sign of the value's imaginary part
// So the number of complex output values ( amplitudes of frequency components)
// are the half of the number of the real input values ( amplitutes in time domain):
nbrOfOutputSamples = ceil(nbrOfInputSamples/2.0);
// Create a plan for a 1D DFT with real input and complex output
in = (double*) fftw_malloc(sizeof(double) * nbrOfInputSamples);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nbrOfOutputSamples);
p = fftw_plan_dft_r2c_1d(nbrOfInputSamples, in, out, FFTW_ESTIMATE);
// Read data from input file to input array
FILE* inputFile = NULL;
inputFile = fopen(fileName,"r");
if(inputFile==NULL){
fprintf(stdout,"couldn't open the file %s\n", fileName);
return -1;
}
double value;
int idx = 0;
while(!feof(inputFile)){
fscanf(inputFile, "%lf", &value);
in[idx++] = value;
}
fclose(inputFile);
// Perform the dft
fftw_execute(p);
// Print output results
char outputFileName[] = "dftvalues.txt";
FILE* outputFile = NULL;
outputFile = fopen(outputFileName,"w+");
if(outputFile==NULL){
fprintf(stdout,"couldn't open the file %s\n", outputFileName);
return -1;
}
double realVal;
double imagVal;
double powVal;
double absVal;
fprintf(stdout, " Frequency Real Imag Abs Power\n");
for (idx=0; idx
To get the power of a frequency, you have to consider the positive frequency as well as the negative frequency. However, the plan r2c delivers only the right positive half of the spectrum. So you have to double the power of the positive side to get the total power.
By the way, the documentation of the fftw3 package describes the usage of plans quite well. You should invest the time to go over the manual.