Skip to content

FFTfreq: possible off-by-one error for one-sided FFTs #49

@arthurits

Description

@arthurits

Could it be possible that there is some offset when computing the sample frequency by calling FftSharp.Transform.FFTfreq()?

These are the steps I've followed and the results obtained:

  • Create a 1-cycle 2-Hz-sinus wave at a sampling rate of 16 Hz (see 16 points 2 Hz sinus .txt) (The offset is less noticeable the higher the sampling frequency).
  • Compute the FFT using:
signalFFT = FftSharp.Transform.FFTmagnitude(signalWindowed);
freq = FftSharp.Transform.FFTfreq(sampleFreq, signalFFT.Length);
plotFFT.Plot.AddScatterLines(freq, signalFFT);
  • The plot shows the frequency of the signal at 1.78 Hz instead of 2 Hz.
    Frequency offset

Possible explanation:

  • The array returned by FftSharp.Transform.FFTmagnitude() has one more point than half its size: new double[input.Length / 2 + 1] (2n-1 +1).
  • Inside function FftSharp.Transform.FFTfreq(), the frequency is computed as:
if (OneSided)
    double fftPeriodHz = sampleRate / pointCount / 2;
else
    double fftPeriodHz = sampleRate / pointCount;
  • The problem is that pointCount is passed as the length of the array returned by FftSharp.Transform.FFTmagnitude() (2n-1 +1), so it has one more point than what is required to compute fftPeriodHz.

So, i can think of two options:

  1. Subtract 1 from the array's length when calling FftSharp.Transform.FFTfreq(). This might be counterintuitive and not obvious.
  2. Perform the subtraction inside FftSharp.Transform.FFTfreq():
if (OneSided)
    double fftPeriodHz = sampleRate / (pointCount-1) / 2;
else
    double fftPeriodHz = sampleRate / (pointCount-1);

This last option produces the correct result for the sinus wave mentioned at the beginning. I hesitated before doing any PR since I'm not sure which one would you consider more appropriate.
Correct frequency

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions