Browse Source

FFT: migrate naive algorithm as reference to test project, obsolete functions

spatial
Christoph Ruegg 9 years ago
parent
commit
24378f41a3
  1. 4
      src/Numerics.Tests/IntegralTransformsTests/FourierTest.cs
  2. 8
      src/Numerics.Tests/IntegralTransformsTests/InverseTransformTest.cs
  3. 52
      src/Numerics.Tests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
  4. 221
      src/Numerics.Tests/IntegralTransformsTests/ReferenceDiscreteFourierTransform.cs
  5. 131
      src/Numerics/IntegralTransforms/Fourier.cs

4
src/Numerics.Tests/IntegralTransformsTests/FourierTest.cs

@ -58,7 +58,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var samples = Generate.PeriodicMap(16, w => new Complex32((float)Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
// real-odd transforms to imaginary odd
var spectrum = Fourier.NaiveForward(samples, FourierOptions.Matlab);
var spectrum = ReferenceDiscreteFourierTransform.NaiveForward(samples, FourierOptions.Matlab);
// all real components must be zero
foreach (var c in spectrum)
@ -93,7 +93,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
// real-odd transforms to imaginary odd
var spectrum = Fourier.NaiveForward(samples, FourierOptions.Matlab);
var spectrum = ReferenceDiscreteFourierTransform.NaiveForward(samples, FourierOptions.Matlab);
// all real components must be zero
foreach (var c in spectrum)

8
src/Numerics.Tests/IntegralTransformsTests/InverseTransformTest.cs

@ -60,10 +60,10 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var work = new Complex32[samples.Length];
samples.CopyTo(work, 0);
work = Fourier.NaiveForward(work, options);
work = ReferenceDiscreteFourierTransform.NaiveForward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6));
work = Fourier.NaiveInverse(work, options);
work = ReferenceDiscreteFourierTransform.NaiveInverse(work, options);
AssertHelpers.AlmostEqual(samples, work, 11);
}
@ -79,10 +79,10 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var work = new Complex[samples.Length];
samples.CopyTo(work, 0);
work = Fourier.NaiveForward(work, options);
work = ReferenceDiscreteFourierTransform.NaiveForward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6));
work = Fourier.NaiveInverse(work, options);
work = ReferenceDiscreteFourierTransform.NaiveInverse(work, options);
AssertHelpers.AlmostEqual(samples, work, 12);
}

52
src/Numerics.Tests/IntegralTransformsTests/MatchingNaiveTransformTest.cs

@ -129,8 +129,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.PeriodicMap(16, w => new Complex32((float)Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
Verify(samples, 6, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 6, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 6, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 6, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -144,8 +144,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
Verify(samples, 12, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 12, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 12, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 12, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -159,8 +159,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex32(0x80, GetUniform(1));
Verify(samples, 5, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -174,8 +174,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex(0x80, GetUniform(1));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -189,8 +189,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.PeriodicMap(14, w => new Complex32((float)Math.Sin(w), 0), 14, 1.0, Constants.Pi2);
Verify(samples, 6, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 6, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 6, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 6, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -204,8 +204,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.PeriodicMap(14, w => new Complex(Math.Sin(w), 0), 14, 1.0, Constants.Pi2);
Verify(samples, 12, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 12, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 12, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 12, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -219,8 +219,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex32(0x80, GetUniform(1));
Verify(samples, 5, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -234,8 +234,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex(0x80, GetUniform(1));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -249,8 +249,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex32(0x7F, GetUniform(1));
Verify(samples, 5, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 5, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -264,8 +264,8 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Generate.RandomComplex(0x7F, GetUniform(1));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.Inverse);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
Verify(samples, 10, options, ReferenceDiscreteFourierTransform.NaiveInverse, Fourier.Inverse);
}
/// <summary>
@ -422,7 +422,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
// 65536 = 2^16
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex32(65536, GetUniform(1));
var naive = Fourier.NaiveForward(samples, options);
var naive = ReferenceDiscreteFourierTransform.NaiveForward(samples, options);
Verify(samples, 3, options, (a, b) => naive, Fourier.Forward);
}
@ -433,7 +433,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
// 65536 = 2^16
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex(65536, GetUniform(1));
var naive = Fourier.NaiveForward(samples, options);
var naive = ReferenceDiscreteFourierTransform.NaiveForward(samples, options);
Verify(samples, 10, options, (a, b) => naive, Fourier.Forward);
}
@ -445,7 +445,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex32(30870, GetUniform(1));
Verify(samples, 4, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 4, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
}
[Test, Explicit("Long-Running")]
@ -454,7 +454,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
// 30870 = 2*3*3*5*7*7*7
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex(30870, GetUniform(1));
var naive = Fourier.NaiveForward(samples, options);
var naive = ReferenceDiscreteFourierTransform.NaiveForward(samples, options);
Verify(samples, 10, options, (a, b) => naive, Fourier.Forward);
}
@ -465,7 +465,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex32(46500, GetUniform(1));
Verify(samples, 4, options, Fourier.NaiveForward, Fourier.Forward);
Verify(samples, 4, options, ReferenceDiscreteFourierTransform.NaiveForward, Fourier.Forward);
}
[Test, Explicit("Long-Running")]
@ -473,7 +473,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex(46500, GetUniform(1));
var naive = Fourier.NaiveForward(samples, options);
var naive = ReferenceDiscreteFourierTransform.NaiveForward(samples, options);
Verify(samples, 10, options, (a, b) => naive, Fourier.Forward);
}

221
src/Numerics.Tests/IntegralTransformsTests/ReferenceDiscreteFourierTransform.cs

@ -0,0 +1,221 @@
using System;
using System.Numerics;
using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
static class ReferenceDiscreteFourierTransform
{
/// <summary>
/// Naive forward DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="samples">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static Complex32[] NaiveForward(Complex32[] samples, FourierOptions options = FourierOptions.Default)
{
var frequencySpace = Naive(samples, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive forward DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="samples">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static Complex[] NaiveForward(Complex[] samples, FourierOptions options = FourierOptions.Default)
{
var frequencySpace = Naive(samples, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive inverse DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="spectrum">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static Complex32[] NaiveInverse(Complex32[] spectrum, FourierOptions options = FourierOptions.Default)
{
var timeSpace = Naive(spectrum, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
/// <summary>
/// Naive inverse DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="spectrum">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static Complex[] NaiveInverse(Complex[] spectrum, FourierOptions options = FourierOptions.Default)
{
var timeSpace = Naive(spectrum, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
/// <summary>
/// Naive generic DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="samples">Time-space sample vector.</param>
/// <param name="exponentSign">Fourier series exponent sign.</param>
/// <returns>Corresponding frequency-space vector.</returns>
static Complex32[] Naive(Complex32[] samples, int exponentSign)
{
var w0 = exponentSign * Constants.Pi2 / samples.Length;
var spectrum = new Complex32[samples.Length];
CommonParallel.For(0, samples.Length, (u, v) =>
{
for (int i = u; i < v; i++)
{
var wk = w0 * i;
var sum = Complex32.Zero;
for (var n = 0; n < samples.Length; n++)
{
var w = n * wk;
sum += samples[n] * new Complex32((float)Math.Cos(w), (float)Math.Sin(w));
}
spectrum[i] = sum;
}
});
return spectrum;
}
/// <summary>
/// Naive generic DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="samples">Time-space sample vector.</param>
/// <param name="exponentSign">Fourier series exponent sign.</param>
/// <returns>Corresponding frequency-space vector.</returns>
static Complex[] Naive(Complex[] samples, int exponentSign)
{
var w0 = exponentSign * Constants.Pi2 / samples.Length;
var spectrum = new Complex[samples.Length];
CommonParallel.For(0, samples.Length, (u, v) =>
{
for (int i = u; i < v; i++)
{
var wk = w0 * i;
var sum = Complex.Zero;
for (var n = 0; n < samples.Length; n++)
{
var w = n * wk;
sum += samples[n] * new Complex(Math.Cos(w), Math.Sin(w));
}
spectrum[i] = sum;
}
});
return spectrum;
}
/// <summary>
/// Extract the exponent sign to be used in forward transforms according to the
/// provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Fourier series exponent sign.</returns>
static int SignByOptions(FourierOptions options)
{
return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1;
}
/// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void ForwardScaleByOptions(FourierOptions options, Complex32[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
var scalingFactor = (float)Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void ForwardScaleByOptions(FourierOptions options, Complex[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
var scalingFactor = Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void InverseScaleByOptions(FourierOptions options, Complex32[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
{
return;
}
var scalingFactor = (float)1.0 / samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{
scalingFactor = (float)Math.Sqrt(scalingFactor);
}
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void InverseScaleByOptions(FourierOptions options, Complex[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
{
return;
}
var scalingFactor = 1.0 / samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{
scalingFactor = Math.Sqrt(scalingFactor);
}
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
}
}

131
src/Numerics/IntegralTransforms/Fourier.cs

@ -751,11 +751,13 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="samples">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
[Obsolete("Use Forward instead. Will be dropped in version 5.0 and behave like Forward until then.")]
public static Complex32[] NaiveForward(Complex32[] samples, FourierOptions options = FourierOptions.Default)
{
var frequencySpace = Naive(samples, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
var result = new Complex32[samples.Length];
samples.Copy(result);
Forward(result, options);
return result;
}
/// <summary>
@ -764,11 +766,13 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="samples">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
[Obsolete("Use Forward instead. Will be dropped in version 5.0 and behave like Forward until then.")]
public static Complex[] NaiveForward(Complex[] samples, FourierOptions options = FourierOptions.Default)
{
var frequencySpace = Naive(samples, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
var result = new Complex[samples.Length];
samples.Copy(result);
Forward(result, options);
return result;
}
/// <summary>
@ -777,11 +781,13 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="spectrum">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
[Obsolete("Use Inverse instead. Will be dropped in version 5.0 and behave like Inverse until then.")]
public static Complex32[] NaiveInverse(Complex32[] spectrum, FourierOptions options = FourierOptions.Default)
{
var timeSpace = Naive(spectrum, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
var result = new Complex32[spectrum.Length];
spectrum.Copy(result);
Inverse(result, options);
return result;
}
/// <summary>
@ -790,11 +796,13 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="spectrum">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
[Obsolete("Use Inverse instead. Will be dropped in version 5.0 and behave like Inverse until then.")]
public static Complex[] NaiveInverse(Complex[] spectrum, FourierOptions options = FourierOptions.Default)
{
var timeSpace = Naive(spectrum, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
var result = new Complex[spectrum.Length];
spectrum.Copy(result);
Inverse(result, options);
return result;
}
/// <summary>
@ -889,105 +897,6 @@ namespace MathNet.Numerics.IntegralTransforms
Inverse(spectrum, options);
}
/// <summary>
/// Extract the exponent sign to be used in forward transforms according to the
/// provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Fourier series exponent sign.</returns>
static int SignByOptions(FourierOptions options)
{
return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1;
}
/// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void ForwardScaleByOptions(FourierOptions options, Complex32[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
var scalingFactor = (float)Math.Sqrt(1.0 / samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void ForwardScaleByOptions(FourierOptions options, Complex[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
var scalingFactor = Math.Sqrt(1.0/samples.Length);
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void InverseScaleByOptions(FourierOptions options, Complex32[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
{
return;
}
var scalingFactor = (float)1.0 / samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{
scalingFactor = (float)Math.Sqrt(scalingFactor);
}
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options.
/// </summary>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param>
static void InverseScaleByOptions(FourierOptions options, Complex[] samples)
{
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
{
return;
}
var scalingFactor = 1.0/samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{
scalingFactor = Math.Sqrt(scalingFactor);
}
for (int i = 0; i < samples.Length; i++)
{
samples[i] *= scalingFactor;
}
}
/// <summary>
/// Generate the frequencies corresponding to each index in frequency space.
/// The frequency space has a resolution of sampleRate/N.

Loading…
Cancel
Save