Browse Source

FFT: code reorg, drop Transform class (now redundant)

provider
Christoph Ruegg 13 years ago
parent
commit
671c9639bc
  1. 24
      src/Numerics/IntegralTransforms/Fourier.Bluestein.cs
  2. 28
      src/Numerics/IntegralTransforms/Fourier.Naive.cs
  3. 100
      src/Numerics/IntegralTransforms/Fourier.Options.cs
  4. 26
      src/Numerics/IntegralTransforms/Fourier.RadixN.cs
  5. 211
      src/Numerics/IntegralTransforms/Fourier.cs
  6. 30
      src/Numerics/IntegralTransforms/Hartley.Naive.cs
  7. 28
      src/Numerics/IntegralTransforms/Hartley.cs
  8. 81
      src/Numerics/IntegralTransforms/Transform.cs
  9. 5
      src/Numerics/Numerics.csproj
  10. 4
      src/UnitTests/IntegralTransformsTests/HartleyTest.cs
  11. 8
      src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
  12. 111
      src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
  13. 8
      src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

24
src/Numerics/IntegralTransforms/Fourier.Bluestein.cs

@ -1,4 +1,4 @@
// <copyright file="DiscreteFourierTransform.Bluestein.cs" company="Math.NET">
// <copyright file="Fourier.Bluestein.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -155,27 +155,5 @@ namespace MathNet.Numerics.IntegralTransforms
SwapRealImaginary(samples);
}
}
/// <summary>
/// Bluestein forward FFT for arbitrary sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void BluesteinForward(Complex[] samples, FourierOptions options)
{
Bluestein(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples);
}
/// <summary>
/// Bluestein inverse FFT for arbitrary sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void BluesteinInverse(Complex[] samples, FourierOptions options)
{
Bluestein(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples);
}
}
}

28
src/Numerics/IntegralTransforms/Fourier.Naive.cs

@ -1,4 +1,4 @@
// <copyright file="DiscreteFourierTransform.Naive.cs" company="Math.NET">
// <copyright file="Fourier.Naive.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -72,31 +72,5 @@ namespace MathNet.Numerics.IntegralTransforms
return spectrum;
}
/// <summary>
/// Naive forward DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static Complex[] NaiveForward(Complex[] timeSpace, FourierOptions options)
{
var frequencySpace = Naive(timeSpace, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive inverse DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static Complex[] NaiveInverse(Complex[] frequencySpace, FourierOptions options)
{
var timeSpace = Naive(frequencySpace, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
}
}

100
src/Numerics/IntegralTransforms/Fourier.Options.cs

@ -1,100 +0,0 @@
// <copyright file="DiscreteFourierTransform.Options.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 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 System;
namespace MathNet.Numerics.IntegralTransforms
{
#if !NOSYSNUMERICS
using Complex = System.Numerics.Complex;
#endif
/// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary>
public static partial class Fourier
{
/// <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, 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, 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;
}
}
}
}

26
src/Numerics/IntegralTransforms/Fourier.RadixN.cs

@ -1,4 +1,4 @@
// <copyright file="DiscreteFourierTransform.RadixN.cs" company="Math.NET">
// <copyright file="Fourier.RadixN.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -144,29 +144,5 @@ namespace MathNet.Numerics.IntegralTransforms
});
}
}
/// <summary>
/// Radix-2 forward FFT for power-of-two sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/>
public static void Radix2Forward(Complex[] samples, FourierOptions options)
{
Radix2Parallel(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples);
}
/// <summary>
/// Radix-2 inverse FFT for power-of-two sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/>
public static void Radix2Inverse(Complex[] samples, FourierOptions options)
{
Radix2Parallel(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples);
}
}
}

211
src/Numerics/IntegralTransforms/Fourier.cs

@ -0,0 +1,211 @@
// <copyright file="Fourier.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 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 System;
namespace MathNet.Numerics.IntegralTransforms
{
#if !NOSYSNUMERICS
using System.Numerics;
#endif
/// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary>
public static partial class Fourier
{
/// <summary>
/// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void Forward(Complex[] samples)
{
BluesteinForward(samples, FourierOptions.Default);
}
/// <summary>
/// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void Forward(Complex[] samples, FourierOptions options)
{
BluesteinForward(samples, options);
}
/// <summary>
/// Applies the inverse Fast Fourier Transform (iFFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void Inverse(Complex[] samples)
{
BluesteinInverse(samples, FourierOptions.Default);
}
/// <summary>
/// Applies the inverse Fast Fourier Transform (iFFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void Inverse(Complex[] samples, FourierOptions options)
{
BluesteinInverse(samples, options);
}
/// <summary>
/// Naive forward DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static Complex[] NaiveForward(Complex[] timeSpace, FourierOptions options)
{
var frequencySpace = Naive(timeSpace, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive inverse DFT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static Complex[] NaiveInverse(Complex[] frequencySpace, FourierOptions options)
{
var timeSpace = Naive(frequencySpace, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
/// <summary>
/// Radix-2 forward FFT for power-of-two sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/>
public static void Radix2Forward(Complex[] samples, FourierOptions options)
{
Radix2Parallel(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples);
}
/// <summary>
/// Radix-2 inverse FFT for power-of-two sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/>
public static void Radix2Inverse(Complex[] samples, FourierOptions options)
{
Radix2Parallel(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples);
}
/// <summary>
/// Bluestein forward FFT for arbitrary sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void BluesteinForward(Complex[] samples, FourierOptions options)
{
Bluestein(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples);
}
/// <summary>
/// Bluestein inverse FFT for arbitrary sized sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void BluesteinInverse(Complex[] samples, FourierOptions options)
{
Bluestein(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples);
}
/// <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, 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, 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;
}
}
}
}

30
src/Numerics/IntegralTransforms/Hartley.Naive.cs

@ -1,10 +1,10 @@
// <copyright file="DiscreteHartleyTransform.Naive.cs" company="Math.NET">
// <copyright file="Hartley.Naive.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -66,31 +66,5 @@ namespace MathNet.Numerics.IntegralTransforms
return spectrum;
}
/// <summary>
/// Naive forward DHT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static double[] NaiveForward(double[] timeSpace, HartleyOptions options)
{
var frequencySpace = Naive(timeSpace);
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive inverse DHT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static double[] NaiveInverse(double[] frequencySpace, HartleyOptions options)
{
var timeSpace = Naive(frequencySpace);
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
}
}

28
src/Numerics/IntegralTransforms/Hartley.Options.cs → src/Numerics/IntegralTransforms/Hartley.cs

@ -1,4 +1,4 @@
// <copyright file="DiscreteHartleyTransform.Options.cs" company="Math.NET">
// <copyright file="Hartley.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -37,6 +37,32 @@ namespace MathNet.Numerics.IntegralTransforms
/// </summary>
public static partial class Hartley
{
/// <summary>
/// Naive forward DHT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns>
public static double[] NaiveForward(double[] timeSpace, HartleyOptions options)
{
var frequencySpace = Naive(timeSpace);
ForwardScaleByOptions(options, frequencySpace);
return frequencySpace;
}
/// <summary>
/// Naive inverse DHT, useful e.g. to verify faster algorithms.
/// </summary>
/// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns>
public static double[] NaiveInverse(double[] frequencySpace, HartleyOptions options)
{
var timeSpace = Naive(frequencySpace);
InverseScaleByOptions(options, timeSpace);
return timeSpace;
}
/// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary>

81
src/Numerics/IntegralTransforms/Transform.cs

@ -1,81 +0,0 @@
// <copyright file="Transform.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2014 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.IntegralTransforms
{
#if !NOSYSNUMERICS
using Complex = System.Numerics.Complex;
#endif
/// <summary>
/// Integral Transforms (including FFT).
/// </summary>
public static class Transform
{
/// <summary>
/// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void FourierForward(Complex[] samples)
{
Fourier.BluesteinForward(samples, FourierOptions.Default);
}
/// <summary>
/// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void FourierForward(Complex[] samples, FourierOptions options)
{
Fourier.BluesteinForward(samples, options);
}
/// <summary>
/// Applies the inverse Fast Fourier Transform (iFFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void FourierInverse(Complex[] samples)
{
Fourier.BluesteinInverse(samples, FourierOptions.Default);
}
/// <summary>
/// Applies the inverse Fast Fourier Transform (iFFT) to arbitrary-length sample vectors.
/// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param>
public static void FourierInverse(Complex[] samples, FourierOptions options)
{
Fourier.BluesteinInverse(samples, options);
}
}
}

5
src/Numerics/Numerics.csproj

@ -93,6 +93,8 @@
<Compile Include="Euclid.cs" />
<Compile Include="Generate.cs" />
<Compile Include="GoodnessOfFit.cs" />
<Compile Include="IntegralTransforms\Fourier.cs" />
<Compile Include="IntegralTransforms\Hartley.cs" />
<Compile Include="Interpolation\Barycentric.cs" />
<Compile Include="Interpolation\CubicSpline.cs" />
<Compile Include="Interpolation\QuadraticSpline.cs" />
@ -372,14 +374,11 @@
<Compile Include="Distributions\IDiscreteDistribution.cs" />
<Compile Include="Distributions\IUnivariateDistribution.cs" />
<Compile Include="IntegralTransforms\Hartley.Naive.cs" />
<Compile Include="IntegralTransforms\Hartley.Options.cs" />
<Compile Include="IntegralTransforms\HartleyOptions.cs" />
<Compile Include="GlobalizationHelper.cs" />
<Compile Include="IntegralTransforms\Fourier.Options.cs" />
<Compile Include="IntegralTransforms\Fourier.Bluestein.cs" />
<Compile Include="IntegralTransforms\Fourier.Naive.cs" />
<Compile Include="IntegralTransforms\Fourier.RadixN.cs" />
<Compile Include="IntegralTransforms\Transform.cs" />
<Compile Include="IntegralTransforms\FourierOptions.cs" />
<Compile Include="Integration\DoubleExponentialTransformation.cs" />
<Compile Include="Integration\SimpsonRule.cs" />

4
src/UnitTests/IntegralTransformsTests/HartleyTest.cs

@ -89,13 +89,13 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
samples,
5,
false,
s => Transform.FourierForward(s, fourierOptions),
s => Fourier.Forward(s, fourierOptions),
s => Hartley.NaiveForward(s, hartleyOptions));
VerifyMatchesDft(
samples,
5,
true,
s => Transform.FourierInverse(s, fourierOptions),
s => Fourier.Inverse(s, fourierOptions),
s => Hartley.NaiveInverse(s, hartleyOptions));
}
}

8
src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs

@ -139,16 +139,16 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var work = new Complex[samples.Length];
samples.CopyTo(work, 0);
Transform.FourierForward(work);
Fourier.Forward(work);
Assert.IsFalse(work.ListAlmostEqual(samples, 6));
Transform.FourierInverse(work);
Fourier.Inverse(work);
AssertHelpers.ListAlmostEqual(samples, work, 10);
Transform.FourierInverse(work, FourierOptions.Default);
Fourier.Inverse(work, FourierOptions.Default);
Assert.IsFalse(work.ListAlmostEqual(samples, 6));
Transform.FourierForward(work, FourierOptions.Default);
Fourier.Forward(work, FourierOptions.Default);
AssertHelpers.ListAlmostEqual(samples, work, 10);
}
}

111
src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs

@ -54,20 +54,18 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
return new ContinuousUniform(-1, 1, new System.Random(seed));
}
/// <summary>
/// Verify matches naive complex.
/// </summary>
static void VerifyMatchesNaiveComplex(
static void Verify(
Complex[] samples,
int maximumErrorDecimalPlaces,
Func<Complex[], Complex[]> naive,
Action<Complex[]> fast)
FourierOptions options,
Func<Complex[], FourierOptions, Complex[]> naive,
Action<Complex[], FourierOptions> fast)
{
var spectrumNaive = naive(samples);
var spectrumNaive = naive(samples, options);
var spectrumFast = new Complex[samples.Length];
samples.CopyTo(spectrumFast, 0);
fast(spectrumFast);
fast(spectrumFast, options);
AssertHelpers.ListAlmostEqual(spectrumNaive, spectrumFast, maximumErrorDecimalPlaces);
}
@ -79,21 +77,12 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Default)]
[TestCase(FourierOptions.Matlab)]
[TestCase(FourierOptions.NumericalRecipes)]
public void FourierRadix2MatchesNaiveOnRealSine(FourierOptions options)
public void FourierRadix2MatchesNaive_RealSine(FourierOptions options)
{
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
VerifyMatchesNaiveComplex(
samples,
12,
s => Fourier.NaiveForward(s, options),
s => Fourier.Radix2Forward(s, options));
VerifyMatchesNaiveComplex(
samples,
12,
s => Fourier.NaiveInverse(s, options),
s => Fourier.Radix2Inverse(s, options));
Verify(samples, 12, options, Fourier.NaiveForward, Fourier.Radix2Forward);
Verify(samples, 12, options, Fourier.NaiveInverse, Fourier.Radix2Inverse);
}
/// <summary>
@ -103,21 +92,12 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Default)]
[TestCase(FourierOptions.Matlab)]
[TestCase(FourierOptions.NumericalRecipes)]
public void FourierRadix2MatchesNaiveOnRandom(FourierOptions options)
public void FourierRadix2MatchesNaive_Random(FourierOptions options)
{
var samples = Generate.RandomComplex(0x80, GetUniform(1));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveForward(s, options),
s => Fourier.Radix2Forward(s, options));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveInverse(s, options),
s => Fourier.Radix2Inverse(s, options));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.Radix2Forward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.Radix2Inverse);
}
/// <summary>
@ -127,21 +107,12 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Default)]
[TestCase(FourierOptions.Matlab)]
[TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRealSineNonPowerOfTwo(FourierOptions options)
public void FourierBluesteinMatchesNaive_RealSine_Arbitrary(FourierOptions options)
{
var samples = Generate.PeriodicMap(14, w => new Complex(Math.Sin(w), 0), 14, 1.0, Constants.Pi2);
VerifyMatchesNaiveComplex(
samples,
12,
s => Fourier.NaiveForward(s, options),
s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex(
samples,
12,
s => Fourier.NaiveInverse(s, options),
s => Fourier.BluesteinInverse(s, options));
Verify(samples, 12, options, Fourier.NaiveForward, Fourier.BluesteinForward);
Verify(samples, 12, options, Fourier.NaiveInverse, Fourier.BluesteinInverse);
}
/// <summary>
@ -151,21 +122,12 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Default)]
[TestCase(FourierOptions.Matlab)]
[TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRandomPowerOfTwo(FourierOptions options)
public void FourierBluesteinMatchesNaive_Random_PowerOfTwo(FourierOptions options)
{
var samples = Generate.RandomComplex(0x80, GetUniform(1));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveForward(s, options),
s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveInverse(s, options),
s => Fourier.BluesteinInverse(s, options));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.BluesteinForward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.BluesteinInverse);
}
/// <summary>
@ -175,20 +137,35 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Default)]
[TestCase(FourierOptions.Matlab)]
[TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRandomNonPowerOfTwo(FourierOptions options)
public void FourierBluesteinMatchesNaive_Random_Arbitrary(FourierOptions options)
{
var samples = Generate.RandomComplex(0x7F, GetUniform(1));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveForward(s, options),
s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex(
samples,
10,
s => Fourier.NaiveInverse(s, options),
s => Fourier.BluesteinInverse(s, options));
Verify(samples, 10, options, Fourier.NaiveForward, Fourier.BluesteinForward);
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.BluesteinInverse);
}
[Test, Explicit("Long-Running")]
public void AlgorithmsMatchNaive_PowerOfTwo_Large()
{
// 65536 = 2^16
const FourierOptions options = FourierOptions.NoScaling;
var samples = Generate.RandomComplex(65536, GetUniform(1));
var naive = Fourier.NaiveForward(samples, options);
Verify(samples, 10, options, (a, b) => naive, Fourier.Radix2Forward);
Verify(samples, 10, options, (a, b) => naive, Fourier.BluesteinForward);
}
[Test, Explicit("Long-Running")]
public void AlgorithmsMatchNaive_Arbitrary_Large()
{
// 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);
Verify(samples, 10, options, (a, b) => naive, Fourier.BluesteinForward);
}
}
}

8
src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

@ -42,7 +42,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
#endif
/// <summary>
/// Parseval theorem verification tests.
/// Parseval's theorem verification tests.
/// </summary>
[TestFixture, Category("FFT")]
public class ParsevalTheoremTest
@ -56,7 +56,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
}
/// <summary>
/// Fourier default transform satisfies parsevals theorem.
/// Fourier default transform satisfies Parseval's theorem.
/// </summary>
/// <param name="count">Samples count.</param>
[TestCase(0x1000)]
@ -71,7 +71,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
samples.CopyTo(work, 0);
// Default -> Symmetric Scaling
Transform.FourierForward(work);
Fourier.Forward(work);
var frequencySpaceEnergy = (from s in work select s.MagnitudeSquared()).Mean();
@ -79,7 +79,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
}
/// <summary>
/// Hartley default naive satisfies parsevals theorem.
/// Hartley default naive satisfies Parseval's theorem.
/// </summary>
/// <param name="count">Samples count.</param>
[TestCase(0x40)]

Loading…
Cancel
Save