From 24378f41a3b62079bc7373f8035ff3023723fc7e Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Thu, 22 Feb 2018 21:28:50 +0100 Subject: [PATCH] FFT: migrate naive algorithm as reference to test project, obsolete functions --- .../IntegralTransformsTests/FourierTest.cs | 4 +- .../InverseTransformTest.cs | 8 +- .../MatchingNaiveTransformTest.cs | 52 ++--- .../ReferenceDiscreteFourierTransform.cs | 221 ++++++++++++++++++ src/Numerics/IntegralTransforms/Fourier.cs | 131 ++--------- 5 files changed, 273 insertions(+), 143 deletions(-) create mode 100644 src/Numerics.Tests/IntegralTransformsTests/ReferenceDiscreteFourierTransform.cs diff --git a/src/Numerics.Tests/IntegralTransformsTests/FourierTest.cs b/src/Numerics.Tests/IntegralTransformsTests/FourierTest.cs index f58739c7..53e2e529 100644 --- a/src/Numerics.Tests/IntegralTransformsTests/FourierTest.cs +++ b/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) diff --git a/src/Numerics.Tests/IntegralTransformsTests/InverseTransformTest.cs b/src/Numerics.Tests/IntegralTransformsTests/InverseTransformTest.cs index a0928eb3..9bb78a94 100644 --- a/src/Numerics.Tests/IntegralTransformsTests/InverseTransformTest.cs +++ b/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); } diff --git a/src/Numerics.Tests/IntegralTransformsTests/MatchingNaiveTransformTest.cs b/src/Numerics.Tests/IntegralTransformsTests/MatchingNaiveTransformTest.cs index 4b19a9a5..acf360ae 100644 --- a/src/Numerics.Tests/IntegralTransformsTests/MatchingNaiveTransformTest.cs +++ b/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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } /// @@ -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); } diff --git a/src/Numerics.Tests/IntegralTransformsTests/ReferenceDiscreteFourierTransform.cs b/src/Numerics.Tests/IntegralTransformsTests/ReferenceDiscreteFourierTransform.cs new file mode 100644 index 00000000..57584016 --- /dev/null +++ b/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 + { + /// + /// Naive forward DFT, useful e.g. to verify faster algorithms. + /// + /// Time-space sample vector. + /// Fourier Transform Convention Options. + /// Corresponding frequency-space vector. + public static Complex32[] NaiveForward(Complex32[] samples, FourierOptions options = FourierOptions.Default) + { + var frequencySpace = Naive(samples, SignByOptions(options)); + ForwardScaleByOptions(options, frequencySpace); + return frequencySpace; + } + + /// + /// Naive forward DFT, useful e.g. to verify faster algorithms. + /// + /// Time-space sample vector. + /// Fourier Transform Convention Options. + /// Corresponding frequency-space vector. + public static Complex[] NaiveForward(Complex[] samples, FourierOptions options = FourierOptions.Default) + { + var frequencySpace = Naive(samples, SignByOptions(options)); + ForwardScaleByOptions(options, frequencySpace); + return frequencySpace; + } + + /// + /// Naive inverse DFT, useful e.g. to verify faster algorithms. + /// + /// Frequency-space sample vector. + /// Fourier Transform Convention Options. + /// Corresponding time-space vector. + public static Complex32[] NaiveInverse(Complex32[] spectrum, FourierOptions options = FourierOptions.Default) + { + var timeSpace = Naive(spectrum, -SignByOptions(options)); + InverseScaleByOptions(options, timeSpace); + return timeSpace; + } + + /// + /// Naive inverse DFT, useful e.g. to verify faster algorithms. + /// + /// Frequency-space sample vector. + /// Fourier Transform Convention Options. + /// Corresponding time-space vector. + public static Complex[] NaiveInverse(Complex[] spectrum, FourierOptions options = FourierOptions.Default) + { + var timeSpace = Naive(spectrum, -SignByOptions(options)); + InverseScaleByOptions(options, timeSpace); + return timeSpace; + } + + /// + /// Naive generic DFT, useful e.g. to verify faster algorithms. + /// + /// Time-space sample vector. + /// Fourier series exponent sign. + /// Corresponding frequency-space vector. + 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; + } + + /// + /// Naive generic DFT, useful e.g. to verify faster algorithms. + /// + /// Time-space sample vector. + /// Fourier series exponent sign. + /// Corresponding frequency-space vector. + 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; + } + + /// + /// Extract the exponent sign to be used in forward transforms according to the + /// provided convention options. + /// + /// Fourier Transform Convention Options. + /// Fourier series exponent sign. + static int SignByOptions(FourierOptions options) + { + return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1; + } + + /// + /// Rescale FFT-the resulting vector according to the provided convention options. + /// + /// Fourier Transform Convention Options. + /// Sample Vector. + 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; + } + } + + /// + /// Rescale FFT-the resulting vector according to the provided convention options. + /// + /// Fourier Transform Convention Options. + /// Sample Vector. + 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; + } + } + + /// + /// Rescale the iFFT-resulting vector according to the provided convention options. + /// + /// Fourier Transform Convention Options. + /// Sample Vector. + 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; + } + } + + /// + /// Rescale the iFFT-resulting vector according to the provided convention options. + /// + /// Fourier Transform Convention Options. + /// Sample Vector. + 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; + } + } + } +} diff --git a/src/Numerics/IntegralTransforms/Fourier.cs b/src/Numerics/IntegralTransforms/Fourier.cs index 6e75d7ec..34396e73 100644 --- a/src/Numerics/IntegralTransforms/Fourier.cs +++ b/src/Numerics/IntegralTransforms/Fourier.cs @@ -751,11 +751,13 @@ namespace MathNet.Numerics.IntegralTransforms /// Time-space sample vector. /// Fourier Transform Convention Options. /// Corresponding frequency-space vector. + [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; } /// @@ -764,11 +766,13 @@ namespace MathNet.Numerics.IntegralTransforms /// Time-space sample vector. /// Fourier Transform Convention Options. /// Corresponding frequency-space vector. + [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; } /// @@ -777,11 +781,13 @@ namespace MathNet.Numerics.IntegralTransforms /// Frequency-space sample vector. /// Fourier Transform Convention Options. /// Corresponding time-space vector. + [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; } /// @@ -790,11 +796,13 @@ namespace MathNet.Numerics.IntegralTransforms /// Frequency-space sample vector. /// Fourier Transform Convention Options. /// Corresponding time-space vector. + [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; } /// @@ -889,105 +897,6 @@ namespace MathNet.Numerics.IntegralTransforms Inverse(spectrum, options); } - /// - /// Extract the exponent sign to be used in forward transforms according to the - /// provided convention options. - /// - /// Fourier Transform Convention Options. - /// Fourier series exponent sign. - static int SignByOptions(FourierOptions options) - { - return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1; - } - - /// - /// Rescale FFT-the resulting vector according to the provided convention options. - /// - /// Fourier Transform Convention Options. - /// Sample Vector. - 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; - } - } - - /// - /// Rescale FFT-the resulting vector according to the provided convention options. - /// - /// Fourier Transform Convention Options. - /// Sample Vector. - 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; - } - } - - /// - /// Rescale the iFFT-resulting vector according to the provided convention options. - /// - /// Fourier Transform Convention Options. - /// Sample Vector. - 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; - } - } - - /// - /// Rescale the iFFT-resulting vector according to the provided convention options. - /// - /// Fourier Transform Convention Options. - /// Sample Vector. - 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; - } - } - /// /// Generate the frequencies corresponding to each index in frequency space. /// The frequency space has a resolution of sampleRate/N.