Browse Source

transforms: reorganized unit tests, now full coverage

Signed-off-by: Christoph Ruegg <git@cdrnet.ch>
pull/2/head
Christoph Ruegg 17 years ago
parent
commit
19e351b7da
  1. 290
      src/UnitTests/IntegralTransformsTests/DftTest.cs
  2. 96
      src/UnitTests/IntegralTransformsTests/FourierTest.cs
  3. 64
      src/UnitTests/IntegralTransformsTests/HartleyTest.cs
  4. 173
      src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
  5. 164
      src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
  6. 82
      src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs
  7. 73
      src/UnitTests/IntegralTransformsTests/SampleProvider.cs
  8. 8
      src/UnitTests/UnitTests.csproj

290
src/UnitTests/IntegralTransformsTests/DftTest.cs

@ -1,290 +0,0 @@
// <copyright file="DftTest.cs" company="Math.NET">
// 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.
// </copyright>
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<spectrum.Length; i++)
{
if(i == 1)
{
Assert.AreApproximatelyEqual(-8, spectrum[i].Imaginary, 1e-12, "imag second");
}
else if (i == spectrum.Length - 1)
{
Assert.AreApproximatelyEqual(8, spectrum[i].Imaginary, 1e-12, "imag last");
}
else
{
Assert.AreApproximatelyEqual(0, spectrum[i].Imaginary, 1e-12, "imag");
}
}
}
[Test]
[Row(FourierOptions.Default)]
[Row(FourierOptions.Matlab)]
public void NaiveIsReversible(FourierOptions options)
{
var samples = ProvideSamples(0x80);
var work = new Complex[samples.Length];
samples.CopyTo(work, 0);
var dft = new DiscreteFourierTransform();
work = dft.NaiveForward(work, options);
Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
work = dft.NaiveInverse(work, options);
AssertHelpers.AlmostEqualList(samples, work, 1e-12);
}
[Test]
public void Radix2MatchesNaiveOnRealSine()
{
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 spectrumNaive = dft.NaiveForward(realSine, FourierOptions.Matlab);
var spectrumRadix2 = new Complex[realSine.Length];
realSine.CopyTo(spectrumRadix2, 0);
dft.Radix2Forward(spectrumRadix2, FourierOptions.Matlab);
AssertHelpers.AlmostEqualList(spectrumNaive, spectrumRadix2, 1e-12);
}
[Test]
public void Radix2MatchesNaiveOnRandom()
{
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.Radix2Forward(work, FourierOptions.Matlab);
AssertHelpers.AlmostEqualList(spectrumNaive, work, 1e-12);
}
[Test]
[Row(FourierOptions.Default)]
[Row(FourierOptions.Matlab)]
public void Radix2IsReversible(FourierOptions options)
{
var samples = ProvideSamples(0x8000);
var work = new Complex[samples.Length];
samples.CopyTo(work, 0);
var dft = new DiscreteFourierTransform();
dft.Radix2Forward(work, options);
Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
dft.Radix2Inverse(work, options);
AssertHelpers.AlmostEqualList(samples, work, 1e-12);
}
[Test]
public void Radix2ThrowsWhenNotPowerOfTwo()
{
var samples = ProvideSamples(0x7F);
var dft = new DiscreteFourierTransform();
Assert.Throws(
typeof(ArgumentException),
() => 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);
}
}
}

96
src/UnitTests/IntegralTransformsTests/FourierTest.cs

@ -0,0 +1,96 @@
// <copyright file="FourierTest.cs" company="Math.NET">
// 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.
// </copyright>
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<spectrum.Length; i++)
{
if(i == 1)
{
Assert.AreApproximatelyEqual(-8, spectrum[i].Imaginary, 1e-12, "imag second");
}
else if (i == spectrum.Length - 1)
{
Assert.AreApproximatelyEqual(8, spectrum[i].Imaginary, 1e-12, "imag last");
}
else
{
Assert.AreApproximatelyEqual(0, spectrum[i].Imaginary, 1e-12, "imag");
}
}
}
[Test]
public void Radix2ThrowsWhenNotPowerOfTwo()
{
var samples = SampleProvider.ProvideComplexSamples(0x7F);
var dft = new DiscreteFourierTransform();
Assert.Throws(
typeof(ArgumentException),
() => 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));
}
}
}

64
src/UnitTests/IntegralTransformsTests/DhtTest.cs → src/UnitTests/IntegralTransformsTests/HartleyTest.cs

@ -1,4 +1,4 @@
// <copyright file="DhtTest.cs" company="Math.NET">
// <copyright file="HartleyTest.cs" company="Math.NET">
// 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<Complex[]> dft,
Func<double[], double[]> 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));
}
}
}

173
src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs

@ -0,0 +1,173 @@
// <copyright file="InverseTransformTest.cs" company="Math.NET">
// 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.
// </copyright>
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<Complex[], Complex[]> forward,
Func<Complex[], Complex[]> 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<double[], double[]> forward,
Func<double[], double[]> 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);
}
}
}

164
src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs

@ -0,0 +1,164 @@
// <copyright file="MatchingNaiveTransformTest.cs" company="Math.NET">
// 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.
// </copyright>
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<Complex[], Complex[]> naive,
Action<Complex[]> 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));
}
}
}

82
src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

@ -0,0 +1,82 @@
// <copyright file="ParsevalTheoremTest.cs" company="Math.NET">
// 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.
// </copyright>
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);
}
}
}

73
src/UnitTests/IntegralTransformsTests/SampleProvider.cs

@ -0,0 +1,73 @@
// <copyright file="SampleProvider.cs" company="Math.NET">
// 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.
// </copyright>
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;
}
}
}

8
src/UnitTests/UnitTests.csproj

@ -67,8 +67,12 @@
<Compile Include="DistributionTests\Continuous\ContinuousUniformTests.cs" />
<Compile Include="DistributionTests\Continuous\GammaTests.cs" />
<Compile Include="DistributionTests\Continuous\NormalTests.cs" />
<Compile Include="IntegralTransformsTests\DhtTest.cs" />
<Compile Include="IntegralTransformsTests\DftTest.cs" />
<Compile Include="IntegralTransformsTests\HartleyTest.cs" />
<Compile Include="IntegralTransformsTests\FourierTest.cs" />
<Compile Include="IntegralTransformsTests\MatchingNaiveTransformTest.cs" />
<Compile Include="IntegralTransformsTests\ParsevalTheoremTest.cs" />
<Compile Include="IntegralTransformsTests\InverseTransformTest.cs" />
<Compile Include="IntegralTransformsTests\SampleProvider.cs" />
<Compile Include="IntegrationTests\IntegrationTest.cs" />
<Compile Include="InterpolationTests\InterpolationContract.cs" />
<Compile Include="InterpolationTests\InterpolationTest.cs" />

Loading…
Cancel
Save