From efcb5d5b5b7fb0c60254ddac47a4d47ac917855d Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sat, 8 Oct 2016 18:57:04 +0200 Subject: [PATCH] FFT: verify mapping between all fourier options --- .../MatchingNaiveTransformTest.cs | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs index 145eeeb4..85c75e9b 100644 --- a/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs +++ b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs @@ -30,6 +30,7 @@ using System; using MathNet.Numerics.Distributions; using MathNet.Numerics.IntegralTransforms; +using MathNet.Numerics.Providers.FourierTransform; using NUnit.Framework; namespace MathNet.Numerics.UnitTests.IntegralTransformsTests @@ -69,6 +70,24 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests AssertHelpers.AlmostEqual(spectrumNaive, spectrumFast, maximumErrorDecimalPlaces); } + static void VerifyInplace( + Complex[] samples, + int maximumErrorDecimalPlaces, + FourierOptions options, + Action expected, + Action actual) + { + var spectrumExpected = new Complex[samples.Length]; + samples.CopyTo(spectrumExpected, 0); + expected(spectrumExpected, options); + + var spectrumActual = new Complex[samples.Length]; + samples.CopyTo(spectrumActual, 0); + actual(spectrumActual, options); + + AssertHelpers.AlmostEqual(spectrumExpected, spectrumActual, maximumErrorDecimalPlaces); + } + /// /// Fourier Radix2XX matches naive on real sine. /// @@ -144,6 +163,57 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.BluesteinInverse); } + /// + /// Fourier bluestein matches providers on random power of two. + /// + /// Fourier options. + [TestCase(FourierOptions.Default)] + [TestCase(FourierOptions.NoScaling)] + [TestCase(FourierOptions.AsymmetricScaling)] + [TestCase(FourierOptions.InverseExponent)] + [TestCase(FourierOptions.InverseExponent | FourierOptions.NoScaling)] + [TestCase(FourierOptions.InverseExponent | FourierOptions.AsymmetricScaling)] + public void FourierBluesteinMatchesProvider_Random_Arbitrary(FourierOptions options) + { + var samples = Generate.RandomComplex(0x7F, GetUniform(1)); + + VerifyInplace(samples, 10, options, Fourier.Forward, Fourier.BluesteinForward); + VerifyInplace(samples, 10, options, Fourier.Inverse, Fourier.BluesteinInverse); + } + + [Test] + public void AlgorithmsMatchProvider_PowerOfTwo_Large() + { + // 65536 = 2^16 + const FourierOptions options = FourierOptions.NoScaling; + var samples = Generate.RandomComplex(65536, GetUniform(1)); + var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); + + Verify(samples, 10, options, (a, b) => provider, Fourier.Radix2Forward); + Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); + } + + [Test] + public void AlgorithmsMatchProvider_Arbitrary_Large() + { + // 30870 = 2*3*3*5*7*7*7 + const FourierOptions options = FourierOptions.NoScaling; + var samples = Generate.RandomComplex(30870, GetUniform(1)); + var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); + + Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); + } + + [Test] + public void AlgorithmsMatchProvider_Arbitrary_Large_GH286() + { + const FourierOptions options = FourierOptions.NoScaling; + var samples = Generate.RandomComplex(46500, GetUniform(1)); + var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); + + Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); + } + [Test, Explicit("Long-Running")] public void AlgorithmsMatchNaive_PowerOfTwo_Large() {