4
$\begingroup$

I don't understand the documentation of Fourier. My goal is the get the coefficients of the Fourier-series (i.e. $\sum_{n\in \mathbb{Z}} c_{n,m} e^{inx+imy}$) of data points which looks like this: {{datapoint1,{x,y}},...}

However, according to its docs Fourier only seems to handle lists of data points without any coordinates attached to them, pretending they are one unity apart. Although the "Details and Options" section of the documentation does say that it can parse nested lists to account for data in any dimensions, unfortunately no example is given to e.g. interpret the output.

Is there no built in function to get the coefficients of this series? This should be done numerically, unless the analytical approach works for arbitrary data sets. I do not have a workable expression for the generator of these points, NFourierTransform does not work.

Should I use some fitting functions instead? If so, which one is best for Fourier transforms?

$\endgroup$
7
  • $\begingroup$ Fourier works on regularly/uniformly sampled data. Are your {x,y} coordinates uniform and are they sorted properly? If so you could just do Fourier[data[[All, All, 1]]]. If not, you'll need to sample it first. $\endgroup$
    – flinty
    Commented Mar 26 at 9:27
  • $\begingroup$ @flinty I can sample them uniformly, such that essentially the x-y Plane becomes a grid. But how does Fourier even know it should return to me the coefficients of a 2D fourier series? The way you write it, I again just get a list of datapoints, but I have lost all information on where they once where? I edited my question to account for another comment in the docs. $\endgroup$ Commented Mar 26 at 9:33
  • $\begingroup$ Yes but that's expected. When you move to the frequency domain you lose all that time/space information. If you want to preserve it, I'm afraid that's impossible, though if you use wavelets you can preserve some of the time/space information. See here $\endgroup$
    – flinty
    Commented Mar 26 at 9:53
  • 2
    $\begingroup$ You are mixing up Fourier Series and the Fourier Transform. When you run Fourier on an array of numbers, it will output an array of the same dimension but full of complex numbers. It also says in the docs that Fourier is equivalent to multiplication with a FourierMatrix. If you go to the docs for FourierMatrix you'll see the layout. $\endgroup$
    – flinty
    Commented Mar 26 at 10:16
  • 2
    $\begingroup$ Maybe experimenting a bit will help you: With[{f = 7, n = 50}, data = Table[Cos[2 \[Pi] (f x)/n], {x, n}, {y, n}]; MatrixPlot[Abs[Fourier[data]], ColorFunction -> GrayLevel]] Here I have set up a cos wave with frequency f=7 (relative to the sample rate of 50). If you look at the brightest pixel, you'll see it appears on row 7+1 because row 1 col 1 is the DC coefficient 0 Hz. There is also the symmetric part at row 50-7+1 (because this is a Real valued signal). If we do the same but change x to y, we get a vertical cos wave, and you get the same thing but with the columns instead of rows. $\endgroup$
    – flinty
    Commented Mar 26 at 10:45

1 Answer 1

5
$\begingroup$

In the 1D case, the FFT is a linear transformation. Therefore it can be done multiplying the data vector by a matrix. Here is an example:

n=5;
dat=RandomReal[{-1,1},n];
fmat=FourierMatrix[n];
Fourier[dat] == fmat.dat

True

For the 2D case you FFT the rows, then the columns separately. This can be written in MMA rather compact. Here is an example, remembering that the Fourier matrix is symmetrical:

n = 5;
fmat = FourierMatrix[n];
d = RandomReal[{-1, 1}, {n, n}];
Fourier[d] == fmat . d . fmat

True

For the 3D case, we first write the general formula using sums:

n = 3;
fm = FourierMatrix[n];
dat = RandomReal[{-1, 1}, {n, n, n}];
Table[Sum[
   fm[[j1, i1]]   fm[[j2, i2]] fm[[j3, i3]] dat[[i1, i2, i3]], {i1, 
    n}, {i2, n}, {i3, n}], {j1, n}, {j2, n}, {j3, n}] == Fourier[dat]

True

This can easily be extended to higher dimensions. But we may write the same more compact using Dot, what is a bit more complicated because of the needed Transpositions (with more complicated calculations, we get small numerical errors due to machine precision):

n = 3;
fm = FourierMatrix[n];
dat = RandomReal[{-1, 1}, {n, n, n}];
Table[Sum[
   fm[[j1, i1]]   fm[[j2, i2]] fm[[j3, i3]] dat[[i1, i2, i3]], {i1, 
    n}, {i2, n}, {i3, n}], {j1, n}, {j2, n}, {j3, n}] - Fourier[dat] //Chop

{{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 
   0}}, {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}
$\endgroup$
1
  • $\begingroup$ Good exposition to also clarify what is meant in the docs about nested lists. Thanks! $\endgroup$ Commented Mar 26 at 14:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.