MathGroup Archive 2009

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Efficiently compute Fourier coefficients for discrete function

  • To: mathgroup at smc.vnet.net
  • Subject: [mg105450] Re: Efficiently compute Fourier coefficients for discrete function
  • From: Bill Rowe <readnews at sbcglobal.net>
  • Date: Thu, 3 Dec 2009 06:14:20 -0500 (EST)

On 12/2/09 at 6:25 AM, kelly.terry.jones at gmail.com (Kelly Jones)
wrote:

>Mathematica-wise, how to efficiently compute the Fourier
>coefficients for a function defined at finite "random" points.

What is it you see as being efficient. Possibly, you are trying
to maximize the amount of computation that can be done in a
given time on a given computer system. Another possibility it
you want to minimize the total time required to obtain a
solution. Note this last would also include time you spend
writing code in addition to execution time for that code.
Possibly you have something else in mind.

I will assume you want to minimize the total time to get a solution.

>Example:

>This defines Sin[3*x] for 100 random values of x:

>l = Table[Random[],{i,1,100}]
>l2 = Table[{l[[i]],Sin[3*l[[i]]]},{i,1,Length[l]}]

Since Sin operates on lists l2 can be computed more efficiently by

l = RandomReal[1,{100}];
l2 = Transpose@{l,Sin[3 l]};

>This calculates the nth Fourier coefficient:

>pfourier[s_,n_] := Sum[s[[i]][[2]]*Exp[-I*n*s[[i]][[1]]],
>{i,1,Length[s]}]

>(I realize I'm off by a factor of pi; I'm only interested in
>relative size for now).

>As expected, the imaginary/sine part of the 3rd coefficient has the
>greatest magnitude:

>Table[Im[pfourier[l2,n]],{n,1,10}]

>I could compute pfourier[l2,n] for all n, but that seems
>inefficient.

>Is there a simpler function (similar to Fourier and
>FourierTransform) that does this?

A few observations. Since you have chosen values from a uniform
distribution, this will fairly closely approximate a uniformly
sampled function as the number of samples gets higher. That is
using Fourier directly should be effective at finding the
maximum frequency component of the data.

For the rest of my remarks, I will use a sample of 128 points
since I know Fourier is a bit more efficient when the number of
points is a power of 2.

Notice the two plots

x = RandomReal[1,{128}];
ListPlot[Transpose@{x, Sin[3 x]}]

and

ListPlot[Sin[3 Sort[x]],DataRange->{0,1}]

are fairly similar.

So the simple straight forward way of finding the index of the
maximum frequency component is:

In[19]:= Ordering[Abs[Fourier[Sin[3 Sort@x]][[2 ;; 64]]], -1]

Out[19]= {1}

Here, I take advantage of knowing the first coefficient is the
dc component and all of the useful frequency information is
contained in the first half of the values returned by Fourier.

The result isn't 3 as you might expect because the data does not
represent sin[3 x]. Instead, it is a half-sine wave since you
restricted x to the range of 0 to 1. If you had sampled over a
full cycle, the result would be 3 as should be expected. That is:

In[20]:= x = RandomReal[2 \[Pi], {128}];
Ordering[Abs[Fourier[Sin[3 Sort@x]][[2 ;; 64]]], -1]

Out[21]= {3}

Unless you have some purpose in mind you haven't made clear, I
see no point to creating your own function to compute the nth coefficient.

Do note, the cheat I am doing here (treating the random sample
intervals as being uniform intervals) will work increasingly
well as the number of sample points increases. But clearly as
the number of sample points decrease, this cheat will become a problem.



  • Prev by Date: Re: Re: Combine images, Show[] and its effect on
  • Next by Date: Re: Re: Permanent Computation Efficiency
  • Previous by thread: Re: Efficiently compute Fourier coefficients for discrete function
  • Next by thread: Re: Permanent Computation Efficiency