diff --git a/src/UnitTests/IntegralTransformsTests/DftTest.cs b/src/UnitTests/IntegralTransformsTests/DftTest.cs
deleted file mode 100644
index be55e3e1..00000000
--- a/src/UnitTests/IntegralTransformsTests/DftTest.cs
+++ /dev/null
@@ -1,290 +0,0 @@
-//
-// Math.NET Numerics, part of the Math.NET Project
-// http://mathnet.opensourcedotnet.info
-//
-// Copyright (c) 2009 Math.NET
-//
-// Permission is hereby granted, free of charge, to any person
-// obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without
-// restriction, including without limitation the rights to use,
-// copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following
-// conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-
-namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
-{
- using System;
- using System.Linq;
- using MbUnit.Framework;
- using IntegralTransforms;
- using IntegralTransforms.Algorithms;
- using Statistics;
-
- [TestFixture]
- public class DftTest
- {
- private static readonly Random _random = new Random();
-
- private static Complex[] ProvideSamples(int count)
- {
- var samples = new Complex[count];
- for (int i = 0; i < samples.Length; i++)
- {
- samples[i] = Complex.WithRealImaginary(
- 1 - (2 * _random.NextDouble()),
- 1 - (2 * _random.NextDouble()));
- }
-
- return samples;
- }
-
- [Test]
- public void NaiveTransformsRealSineCorrectly()
- {
- var realSine = new Complex[16];
- for (int i = 0; i < realSine.Length; i++)
- {
- realSine[i] = Math.Sin(i / 8.0 * Constants.Pi);
- }
-
- // real-odd transforms to imaginary odd
- var dft = new DiscreteFourierTransform();
- var spectrum = dft.NaiveForward(realSine, FourierOptions.Matlab);
-
- // all real components must be zero
- foreach (var c in spectrum)
- {
- Assert.AreApproximatelyEqual(0, c.Real, 1e-12, "real");
- }
-
- // all imaginary components except second and last musth be zero
- for(int i = 0; i dft.Radix2Forward(samples, FourierOptions.Default));
-
- Assert.Throws(
- typeof(ArgumentException),
- () => dft.Radix2Inverse(samples, FourierOptions.Default));
- }
-
- [Test]
- public void BluesteinMatchesNaiveOnRealSine()
- {
- var realSine = new Complex[14];
- for (int i = 0; i < realSine.Length; i++)
- {
- realSine[i] = Math.Sin(i / 7.0 * Constants.Pi);
- }
-
- // real-odd transforms to imaginary odd
- var dft = new DiscreteFourierTransform();
- var spectrumNaive = dft.NaiveForward(realSine, FourierOptions.Matlab);
-
- var spectrumBluestein = new Complex[realSine.Length];
- realSine.CopyTo(spectrumBluestein, 0);
- dft.BluesteinForward(spectrumBluestein, FourierOptions.Matlab);
-
- AssertHelpers.AlmostEqualList(spectrumNaive, spectrumBluestein, 1e-12);
- }
-
- [Test]
- public void BluesteinMatchesNaiveOnRandomPowerOfTwo()
- {
- var samples = ProvideSamples(0x80);
- var work = new Complex[samples.Length];
- samples.CopyTo(work, 0);
-
- var dft = new DiscreteFourierTransform();
- var spectrumNaive = dft.NaiveForward(samples, FourierOptions.Matlab);
- dft.BluesteinForward(work, FourierOptions.Matlab);
-
- AssertHelpers.AlmostEqualList(spectrumNaive, work, 1e-12);
- }
-
- [Test]
- public void BluesteinMatchesNaiveOnRandomNonPowerOfTwo()
- {
- var samples = ProvideSamples(0x7F);
- var work = new Complex[samples.Length];
- samples.CopyTo(work, 0);
-
- var dft = new DiscreteFourierTransform();
- var spectrumNaive = dft.NaiveForward(samples, FourierOptions.Matlab);
- dft.BluesteinForward(work, FourierOptions.Matlab);
-
- AssertHelpers.AlmostEqualList(spectrumNaive, work, 1e-12);
- }
-
- [Test]
- [Row(FourierOptions.Default)]
- [Row(FourierOptions.Matlab)]
- public void BluesteinIsReversible(FourierOptions options)
- {
- var samples = ProvideSamples(0x7FFF);
- var work = new Complex[samples.Length];
- samples.CopyTo(work, 0);
-
- var dft = new DiscreteFourierTransform();
- dft.BluesteinForward(work, options);
-
- Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
-
- dft.BluesteinInverse(work, options);
-
- AssertHelpers.AlmostEqualList(samples, work, 1e-12);
- }
-
- [Test]
- public void DefaultTransformIsReversible()
- {
- var samples = ProvideSamples(0x7FFF);
- var work = new Complex[samples.Length];
- samples.CopyTo(work, 0);
-
- Transform.FourierForward(work);
-
- Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
-
- Transform.FourierInverse(work);
-
- AssertHelpers.AlmostEqualList(samples, work, 1e-12);
-
- Transform.FourierInverse(work, FourierOptions.Default);
-
- Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
-
- Transform.FourierForward(work, FourierOptions.Default);
-
- AssertHelpers.AlmostEqualList(samples, work, 1e-12);
- }
-
- [Test]
- public void TransformSatisfiesParsevalsTheorem()
- {
- var samples = ProvideSamples(0x1000);
-
- var timeSpaceEnergy = (from s in samples select s.ModulusSquared).Mean();
-
- var work = new Complex[samples.Length];
- samples.CopyTo(work, 0);
-
- // Only symmetric scaling scaling satisfies the theorem, hence FourierOptions.Default.
- Transform.FourierForward(work, FourierOptions.Default);
-
- var frequencySpaceEnergy = (from s in work select s.ModulusSquared).Mean();
-
- Assert.AreApproximatelyEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12);
- }
- }
-}
diff --git a/src/UnitTests/IntegralTransformsTests/FourierTest.cs b/src/UnitTests/IntegralTransformsTests/FourierTest.cs
new file mode 100644
index 00000000..bb5221a4
--- /dev/null
+++ b/src/UnitTests/IntegralTransformsTests/FourierTest.cs
@@ -0,0 +1,96 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System;
+ using MbUnit.Framework;
+ using IntegralTransforms;
+ using IntegralTransforms.Algorithms;
+
+ [TestFixture]
+ public class FourierTest
+ {
+ [Test]
+ public void NaiveTransformsRealSineCorrectly()
+ {
+ var samples = SampleProvider.ProvideComplexRealSine(16);
+
+ // real-odd transforms to imaginary odd
+ var dft = new DiscreteFourierTransform();
+ var spectrum = dft.NaiveForward(samples, FourierOptions.Matlab);
+
+ // all real components must be zero
+ foreach (var c in spectrum)
+ {
+ Assert.AreApproximatelyEqual(0, c.Real, 1e-12, "real");
+ }
+
+ // all imaginary components except second and last musth be zero
+ for(int i = 0; i dft.Radix2Forward(samples, FourierOptions.Default));
+
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => dft.Radix2Inverse(samples, FourierOptions.Default));
+
+ Assert.Throws(
+ typeof (ArgumentException),
+ () => DiscreteFourierTransform.Radix2(samples, -1));
+
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => DiscreteFourierTransform.Radix2Parallel(samples, -1));
+ }
+ }
+}
diff --git a/src/UnitTests/IntegralTransformsTests/DhtTest.cs b/src/UnitTests/IntegralTransformsTests/HartleyTest.cs
similarity index 60%
rename from src/UnitTests/IntegralTransformsTests/DhtTest.cs
rename to src/UnitTests/IntegralTransformsTests/HartleyTest.cs
index 679cc30b..5e250fb4 100644
--- a/src/UnitTests/IntegralTransformsTests/DhtTest.cs
+++ b/src/UnitTests/IntegralTransformsTests/HartleyTest.cs
@@ -1,4 +1,4 @@
-//
+//
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
@@ -34,19 +34,22 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
using IntegralTransforms.Algorithms;
[TestFixture]
- public class DhtTest
+ public class HartleyTest
{
- private static readonly Random _random = new Random();
-
- private static double[] ProvideSamples(int count)
+ private static void VerifyMatchesDFT(
+ double[] samples,
+ double maximumError,
+ bool inverse,
+ Action dft,
+ Func hartley)
{
- var samples = new double[count];
- for (int i = 0; i < samples.Length; i++)
- {
- samples[i] = 1 - (2 * _random.NextDouble());
- }
+ var hartleyReal = hartley(samples);
+
+ var fourierComplex = Array.ConvertAll(samples, s => new Complex(s, inverse ? -s : s));
+ dft(fourierComplex);
+ var fourierReal = Array.ConvertAll(fourierComplex, s => s.Real);
- return samples;
+ AssertHelpers.AlmostEqualList(fourierReal, hartleyReal, maximumError);
}
[Test]
@@ -55,35 +58,22 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[Row(HartleyOptions.NoScaling, FourierOptions.NoScaling)]
public void NaiveMatchesDFT(HartleyOptions hartleyOptions, FourierOptions fourierOptions)
{
- var samples = ProvideSamples(0x80);
-
- var dht = new DiscreteHartleyTransform();
- var hartley = dht.NaiveForward(samples, hartleyOptions);
-
- var fourierComplex = Array.ConvertAll(samples, s => new Complex(s, s));
- Transform.FourierForward(fourierComplex, fourierOptions);
- var fourierReal = Array.ConvertAll(fourierComplex, s => s.Real);
-
- AssertHelpers.AlmostEqualList(fourierReal, hartley, 1e-10);
- }
-
- [Test]
- [Row(HartleyOptions.Default)]
- [Row(HartleyOptions.AsymmetricScaling)]
- public void NaiveIsReversible(HartleyOptions options)
- {
- var samples = ProvideSamples(0x80);
- var work = new double[samples.Length];
- samples.CopyTo(work, 0);
-
var dht = new DiscreteHartleyTransform();
- work = dht.NaiveForward(work, options);
-
- Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-10));
+ var samples = SampleProvider.ProvideRealSamples(0x80);
- work = dht.NaiveInverse(work, options);
+ VerifyMatchesDFT(
+ samples,
+ 1e-10,
+ false,
+ s => Transform.FourierForward(s, fourierOptions),
+ s => dht.NaiveForward(s, hartleyOptions));
- AssertHelpers.AlmostEqualList(samples, work, 1e-10);
+ VerifyMatchesDFT(
+ samples,
+ 1e-10,
+ true,
+ s => Transform.FourierInverse(s, fourierOptions),
+ s => dht.NaiveInverse(s, hartleyOptions));
}
}
}
diff --git a/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs b/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
new file mode 100644
index 00000000..dc663072
--- /dev/null
+++ b/src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
@@ -0,0 +1,173 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System;
+ using IntegralTransforms;
+ using IntegralTransforms.Algorithms;
+ using MbUnit.Framework;
+
+ [TestFixture]
+ public class InverseTransformTest
+ {
+ private static void VerifyIsReversibleComplex(
+ int count,
+ double maximumError,
+ Func forward,
+ Func inverse)
+ {
+ var samples = SampleProvider.ProvideComplexSamples(count);
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ work = forward(work);
+
+ Assert.IsFalse(work.AlmostEqualListWithError(samples, maximumError));
+
+ work = inverse(work);
+
+ AssertHelpers.AlmostEqualList(samples, work, maximumError);
+ }
+
+ private static void VerifyIsReversibleReal(
+ int count,
+ double maximumError,
+ Func forward,
+ Func inverse)
+ {
+ var samples = SampleProvider.ProvideRealSamples(count);
+ var work = new double[samples.Length];
+ samples.CopyTo(work, 0);
+
+ work = forward(work);
+
+ Assert.IsFalse(work.AlmostEqualListWithError(samples, maximumError));
+
+ work = inverse(work);
+
+ AssertHelpers.AlmostEqualList(samples, work, maximumError);
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ public void FourierNaiveIsReversible(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+
+ VerifyIsReversibleComplex(
+ 0x80,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.NaiveInverse(s, options));
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ public void FourierRadix2IsReversible(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+
+ VerifyIsReversibleComplex(
+ 0x8000,
+ 1e-12,
+ s =>
+ {
+ dft.Radix2Forward(s, options);
+ return s;
+ },
+ s =>
+ {
+ dft.Radix2Inverse(s, options);
+ return s;
+ });
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ public void FourierBluesteinIsReversible(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+
+ VerifyIsReversibleComplex(
+ 0x7FFF,
+ 1e-12,
+ s =>
+ {
+ dft.BluesteinForward(s, options);
+ return s;
+ },
+ s =>
+ {
+ dft.BluesteinInverse(s, options);
+ return s;
+ });
+ }
+
+ [Test]
+ [Row(HartleyOptions.Default)]
+ [Row(HartleyOptions.AsymmetricScaling)]
+ public void HartleyNaiveIsReversible(HartleyOptions options)
+ {
+ var dht = new DiscreteHartleyTransform();
+
+ VerifyIsReversibleReal(
+ 0x80,
+ 1e-10,
+ s => dht.NaiveForward(s, options),
+ s => dht.NaiveInverse(s, options));
+ }
+
+ [Test]
+ public void FourierDefaultTransformIsReversible()
+ {
+ var samples = SampleProvider.ProvideComplexSamples(0x7FFF);
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ Transform.FourierForward(work);
+
+ Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
+
+ Transform.FourierInverse(work);
+
+ AssertHelpers.AlmostEqualList(samples, work, 1e-12);
+
+ Transform.FourierInverse(work, FourierOptions.Default);
+
+ Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
+
+ Transform.FourierForward(work, FourierOptions.Default);
+
+ AssertHelpers.AlmostEqualList(samples, work, 1e-12);
+ }
+ }
+}
diff --git a/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
new file mode 100644
index 00000000..259a4fc9
--- /dev/null
+++ b/src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
@@ -0,0 +1,164 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System;
+ using IntegralTransforms;
+ using IntegralTransforms.Algorithms;
+ using MbUnit.Framework;
+
+ [TestFixture]
+ public class MatchingNaiveTransformTest
+ {
+ private static void VerifyMatchesNaiveComplex(
+ Complex[] samples,
+ double maximumError,
+ Func naive,
+ Action fast)
+ {
+ var spectrumNaive = naive(samples);
+
+ var spectrumFast = new Complex[samples.Length];
+ samples.CopyTo(spectrumFast, 0);
+ fast(spectrumFast);
+
+ AssertHelpers.AlmostEqualList(spectrumNaive, spectrumFast, maximumError);
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ [Row(FourierOptions.NumericalRecipes)]
+ public void FourierRadix2MatchesNaiveOnRealSine(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+ var samples = SampleProvider.ProvideComplexRealSine(16);
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.Radix2Forward(s, options));
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveInverse(s, options),
+ s => dft.Radix2Inverse(s, options));
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ [Row(FourierOptions.NumericalRecipes)]
+ public void FourierRadix2MatchesNaiveOnRandom(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+ var samples = SampleProvider.ProvideComplexSamples(0x80);
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.Radix2Forward(s, options));
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveInverse(s, options),
+ s => dft.Radix2Inverse(s, options));
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ [Row(FourierOptions.NumericalRecipes)]
+ public void FourierBluesteinMatchesNaiveOnRealSineNonPowerOfTwo(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+ var samples = SampleProvider.ProvideComplexRealSine(14);
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.BluesteinForward(s, options));
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveInverse(s, options),
+ s => dft.BluesteinInverse(s, options));
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ [Row(FourierOptions.NumericalRecipes)]
+ public void FourierBluesteinMatchesNaiveOnRandomPowerOfTwo(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+ var samples = SampleProvider.ProvideComplexSamples(0x80);
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.BluesteinForward(s, options));
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveInverse(s, options),
+ s => dft.BluesteinInverse(s, options));
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ [Row(FourierOptions.NumericalRecipes)]
+ public void FourierBluesteinMatchesNaiveOnRandomNonPowerOfTwo(FourierOptions options)
+ {
+ var dft = new DiscreteFourierTransform();
+ var samples = SampleProvider.ProvideComplexSamples(0x7F);
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveForward(s, options),
+ s => dft.BluesteinForward(s, options));
+
+ VerifyMatchesNaiveComplex(
+ samples,
+ 1e-12,
+ s => dft.NaiveInverse(s, options),
+ s => dft.BluesteinInverse(s, options));
+ }
+ }
+}
diff --git a/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs b/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs
new file mode 100644
index 00000000..40426719
--- /dev/null
+++ b/src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs
@@ -0,0 +1,82 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using MathNet.Numerics.IntegralTransforms.Algorithms;
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System.Linq;
+ using MbUnit.Framework;
+ using IntegralTransforms;
+ using Statistics;
+
+ [TestFixture]
+ public class ParsevalTheoremTest
+ {
+ [Test]
+ [Row(0x1000)]
+ [Row(0x7FF)]
+ public void FourierDefaultTransformSatisfiesParsevalsTheorem(int count)
+ {
+ var samples = SampleProvider.ProvideComplexSamples(count);
+
+ var timeSpaceEnergy = (from s in samples select s.ModulusSquared).Mean();
+
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ // Default -> Symmetric Scaling
+ Transform.FourierForward(work);
+
+ var frequencySpaceEnergy = (from s in work select s.ModulusSquared).Mean();
+
+ Assert.AreApproximatelyEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12);
+ }
+
+ [Test]
+ [Row(0x40)]
+ [Row(0x1F)]
+ public void HartleyDefaultNaiveSatisfiesParsevalsTheorem(int count)
+ {
+ var samples = SampleProvider.ProvideRealSamples(count);
+
+ var timeSpaceEnergy = (from s in samples select s * s).Mean();
+
+ var work = new double[samples.Length];
+ samples.CopyTo(work, 0);
+
+ // Default -> Symmetric Scaling
+ var dht = new DiscreteHartleyTransform();
+ work = dht.NaiveForward(work, HartleyOptions.Default);
+
+ var frequencySpaceEnergy = (from s in work select s * s).Mean();
+
+ Assert.AreApproximatelyEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12);
+ }
+ }
+}
diff --git a/src/UnitTests/IntegralTransformsTests/SampleProvider.cs b/src/UnitTests/IntegralTransformsTests/SampleProvider.cs
new file mode 100644
index 00000000..e2ee1cc0
--- /dev/null
+++ b/src/UnitTests/IntegralTransformsTests/SampleProvider.cs
@@ -0,0 +1,73 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System;
+
+ internal static class SampleProvider
+ {
+ private static readonly Random _random = new Random();
+
+ internal static Complex[] ProvideComplexSamples(int count)
+ {
+ var samples = new Complex[count];
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = Complex.WithRealImaginary(
+ 1 - (2 * _random.NextDouble()),
+ 1 - (2 * _random.NextDouble()));
+ }
+
+ return samples;
+ }
+
+ internal static double[] ProvideRealSamples(int count)
+ {
+ var samples = new double[count];
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = 1 - (2 * _random.NextDouble());
+ }
+
+ return samples;
+ }
+
+ internal static Complex[] ProvideComplexRealSine(int count)
+ {
+ double halfPeriod = count / 2.0;
+ var samples = new Complex[count];
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = Math.Sin(i * Constants.Pi / halfPeriod);
+ }
+
+ return samples;
+ }
+ }
+}
diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj
index ca45201b..fe292ad0 100644
--- a/src/UnitTests/UnitTests.csproj
+++ b/src/UnitTests/UnitTests.csproj
@@ -67,8 +67,12 @@
-
-
+
+
+
+
+
+