Edit
This is a popular question with several answers. This edit organises the answers and gives links.
- Fourier just gives y values (ordinates) if you wish to read off frequencies and amplitudes you need to add an x axis (abscissa) and scale the ordinates. Details for doing this and other basic information on Fourier are given here.
There are other methods for finding the frequency and amplitude besides Fourier these are:
A method due to Daniel Lichtblau that looks for periodicities in the time history answer below.
A method using Prony series. Code from Daniel Lichtblau answer below.
Straightforward fitting of sine wave to data. There are pitfalls in formulating this problem which are discussed here.
A method using auto-correlation due to Szabolics. Answer below.
The original question was how to use the output from Fourier when the computed values do not lie at a single point. This is answered in two ways below.
Original Question
The problem is that a typical harmonic time history will not have an integer number of cycles in the data. For example, with the following time history you get a numerical Fourier transform.
sr = 400; (* sample rate *)
nn = 200; (* number of points *)
f = 17.2; (* frequency in Hz *)
A = 1; B = 0.1; (* Coefficients of Cos and Sin *)
th = N @ Table[A Cos[2 Pi f t] + B Sin[2 Pi f t], {t, 0, (nn - 1)/sr, 1/sr}];
ft = Fourier[th, FourierParameters -> {-1, -1}];
n = Position[#, mx = Max[#]] & [Abs[ft]][[1, 1]];
ListPlot[Abs[ft[[1 ;; n + 10]]], PlotRange -> All]
This produces a plot with several points making up the peak. The frequency resolution is 2 Hz and there is no point at the harmonic frequency of 17.2 Hz. Clearly the frequency is bracketed between the 9 th and 10 th point (16 Hz and 18 Hz). How do we find the exact frequency and amplitude? I have considered extending by zeros but although this increases the resolution it still results in points on either side of the frequency. Also, I have considered calculating points with non-integer values. However, the resulting spectrum does not have a maximum at the frequency of the time history. My actual data includes noise and other harmonics hence my use of Fourier which is good at concentrating the data I am interested in around a few points in the spectrum. I have worked out one very poor way of finding the frequency and amplitude and will post this when I have worked out how to use StackExchange more fully.
aft = Abs[ft]/Max[Abs[ft]]; lower = {9, 10}; v1 = (lower - 1).aft[[lower]]/Total[aft[[lower]]] 2*v1 Out[139]= 8.61412 Out[140]= 17.2282
$\endgroup$