FFT Amplitude issue

Hi,
I try to convert simple sine wave from time domain to frequency domain.the issue is, Amplitude is not same.

here is my configuration
i am using Math.Net.numeric ver.4.12.0.0
Signal Length 1024
Sample Rate 512
Signal Frequency 10
Amplitude 1

here is my code

var points = Generate.Sinusoidal(1024, 512, 10, 1);

for (int i = 0; i < points .Length; i++)
{
chart1.Series[“Series1”].Points.AddXY
(i,points [i]);

}
Fourier.Forward(points ,FourierOptions.Default);

for (int i = 0; i < points .Length; i++)
{
chart2.Series[“Series1”].Points.AddXY
(i, points [i].Magnitude);

}

on top chart i have amplitude 1 while in bottom chart i have 16.

short update

chart2.Series[“Series1”].Points.AddXY
(i, points [i].Magnitude);

to

chart2.Series[“Series1”].Points.AddXY
(i, (points [i].Magnitude * 2)/points .Length);

now the amplitude is correct.

i also change this

Fourier.Forward(points ,FourierOptions.Default);

to

Fourier.Forward(points ,FourierOptions.NoScaling);

multiply the amplitude with 2 and divide with array length.

during the test i see the strange amplitude. if i change the sample frequency then the amplitude also change, it should not be.

its look like window or scalling issue.
it would be nice if someone share very short example.

thank you

There seems to be a misunderstanding about Fourier transforms. Those amplitudes you mentioned are not supposed to be the same, and this is also not directly a scaling issue. Fourier transforms are about energy, not amplitudes. The frequency space essentially informs about the energy distribution of all the frequencies in the time space signal. In the discrete case, with energy we essentially mean the sum of the squares of all samples.

Parseval’s theorem states that the energy in both time and frequency space is the same (this is only ensured with FourierOptions.Default). Indeed, in your example, the energy of that sine wave signal is 512, which is the same as 16^2+16^2 for the two non-zero-energy frequencies. Since the energy for a given sine wave can be computed, we can leverage the theorem to reconstruct the amplitudes.

Example:

var r = 512.0; // sample rate
var n = 1024; // signal length (works best if this is k*sample rate)

// create time space real-valued signal as sum of three waves
var wave1 = Generate.Sinusoidal(n, r, 10.0, 1.2);
var wave2 = Generate.Sinusoidal(n, r, 35.0, 4.9);
var wave3 = Generate.Sinusoidal(n, r, 4.5, 20.3);
var signals = Generate.Unfold(n, k => Tuple.Create(wave1[k] + wave2[k] + wave3[k], k+1), 0);

// compute complex frequency space
var freq = Generate.Map(signals, x => new Complex(x, 0.0));
Fourier.Forward(freq);

// try to reconstruct the original frequencies and amplitudes
var threshold = 0.001;
var frequencies = Fourier.FrequencyScale(n,r);
var sineWaves = new Dictionary<double, double>();
for (int i=0;i<freq.Length/2;i++) // since real valued we can skip the negative frequencies
{
	var m = freq[i].Magnitude;
	if (m > threshold)
	{
		var z = 2.0 * frequencies[i] * Math.PI / r;
		sineWaves[frequencies[i]] = Math.Sqrt((2*m*m)*4.0/(1.0 + 2.0 * n - Trig.Csc(z) * Math.Sin(z * (1.0 + 2.0 * n))));
	}
}

This collects the following, which matches what we expect given the three waves generated above:

image

Please try FourierOptions.Matlab instead of FourierOptions.Default.

MathNet.Numerics.IntegralTransforms.Fourier.Forward(mathNetComplexArr, FourierOptions.Matlab);//FFT