Hello,
I am new to using the FFTW algorithms in C++, and need some help
getting started. I have used matlab (and done a good deal of C++) for
many years, and I am rewriting some of my matlab code in C++ to see if
it helps with speed/memory issues. I'll give an overview of what I'm
trying to do, and see if anyone has suggestions.
So, I am reading in a MAT file, and the data I want is stored in a 3D
array. Matlab arrays are represented in fortran (column-first) format,
which is not what FFTW uses, but I think that can be overcome by
specifying the fftw plan slightly differently.
The data contains epoched EEG data, where the dimensions are [samples,
channels, trials]. For example, the array might consist of 40 trials,
each with 64 channels, and each of these with 3000 samples, therefore
with dimensions of [3000, 64, 40], for a total of 7,680,000 double
elements.
I want to calculate the spectrogram along the samples dimension; I am
using the matlab definition of spectrogram, where I specify the window
length, overlap, and size of the FFT. A moving window is applied,
taking the DFT for each window (padding zeros when necessary). The
dimensions of the output are then [freqs, samples, channels, trials],
where freqs is nfft/2+1, the times are the number of samples (dependent
on the window length and overlap), and channels and trials are
unchanged.
There are a few methods of doing this (I hope...)
(1) The initial thought on how to do this is to basically pound it out
in several for loops. For each trial and channel, I take winLen samples
(say 100), pad to nfft (say 512), do the DFT via FFTW, get the
magnitude and remove redundant data (so I'm left with 257 samples),
move ahead overlap samples, and wash-rinse-repeat. This is intuitively
the simplest, and probably where I want to start, but I do not know how
do accomplish this using the fftw interfaces. With FFTW, I know I
create a plan, in this case using fftw_plan_dft_r2c_1d, passing the fft
length, input array pointer, output array pointer, and flags. My
confusion is about the fact that I will be doing this thousands of
times on different data, and I think that I do not need to recreate the
plan every time, but how is that accomplished? The way I'm envisioning
it, I create the plan using the FFTW_MEASURE flag, then use
fftw_execute repeatedly, changing the contents of the input array (not
the pointer value, but the contents of the array) in between every
execute. Also, does the input array in the create plan function need to
have valid data (ie the first chunk of data), or is it finding the
optimal algorithm based on the size of the FFT alone? I think I'm
primarily getting confused by the wording of the FFTW manual, where it
says things like "To apply a given plan to a different array, use can
use the guru interface." By different array, does that mean that the
original contents of x have changed, or that the pointer x itself has
changed? If the size of the data is not changing, it seems pretty
inefficient to recalculate the plan for every step. (Again, I'm not
familiar with FFTW, so any example code that shows EXACTLY how to do
this would be very appreciated.)
(2) How do the multidimensional functions work? If you are familiar
with matlab, if I have a 2D array X, of size 100 x 50, for example, and
I use the fft function like: fft(X, 512, 2), the function calculates
the fft along the 2nd dimension, returning an array of size 100x512.
(If I do fft(X, 512, 1) or fft(X,512), the returned answer is 512x50).
Is this possible with FFTW? The spectrogram function works this way in
matlab, where it takes a 1D vector of data, creates a 2D array based on
the winLen and overlap, and takes the FFT down the winLen dimension.
(3) Again, for the multidemensional functions, would it be possible to
do the fft of an entire 4D array, only along a specified dimension?
This would be similar to the matlab spectrogram, but not limited to a
2D array.
I really appreciate anyone who takes the time to wade through this
series of questions. Any help you can give me is obviously of
tremendous help.
Thanks!
Adam