Browse Source

FFT: Fourier and Hartley classes now static, compact names, dropped Algorithms namespace

provider
Christoph Ruegg 13 years ago
parent
commit
cb08427ac9
  1. 28
      src/Numerics/IntegralTransforms/Fourier.Bluestein.cs
  2. 37
      src/Numerics/IntegralTransforms/Fourier.Naive.cs
  3. 19
      src/Numerics/IntegralTransforms/Fourier.Options.cs
  4. 20
      src/Numerics/IntegralTransforms/Fourier.RadixN.cs
  5. 6
      src/Numerics/IntegralTransforms/FourierOptions.cs
  6. 14
      src/Numerics/IntegralTransforms/Hartley.Naive.cs
  7. 18
      src/Numerics/IntegralTransforms/Hartley.Options.cs
  8. 14
      src/Numerics/IntegralTransforms/Transform.cs
  9. 12
      src/Numerics/Numerics.csproj
  10. 19
      src/UnitTests/IntegralTransformsTests/FourierTest.cs
  11. 12
      src/UnitTests/IntegralTransformsTests/HartleyTest.cs
  12. 31
      src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
  13. 52
      src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
  14. 11
      src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

28
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs → src/Numerics/IntegralTransforms/Fourier.Bluestein.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -31,7 +31,7 @@
using System; using System;
using MathNet.Numerics.Threading; using MathNet.Numerics.Threading;
namespace MathNet.Numerics.IntegralTransforms.Algorithms namespace MathNet.Numerics.IntegralTransforms
{ {
#if !NOSYSNUMERICS #if !NOSYSNUMERICS
@ -41,21 +41,21 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <summary> /// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT). /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary> /// </summary>
public partial class DiscreteFourierTransform public static partial class Fourier
{ {
/// <summary> /// <summary>
/// Generate the bluestein sequence for the provided problem size. /// Generate the bluestein sequence for the provided problem size.
/// </summary> /// </summary>
/// <param name="n">Number of samples.</param> /// <param name="n">Number of samples.</param>
/// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns> /// <returns>Bluestein sequence exp(I*Pi*k^2/N)</returns>
private static Complex[] BluesteinSequence(int n) static Complex[] BluesteinSequence(int n)
{ {
double s = Constants.Pi / n; double s = Constants.Pi/n;
var sequence = new Complex[n]; var sequence = new Complex[n];
for (int k = 0; k < sequence.Length; k++) for (int k = 0; k < sequence.Length; k++)
{ {
double t = s * (k * k); double t = s*(k*k);
sequence[k] = new Complex(Math.Cos(t), Math.Sin(t)); sequence[k] = new Complex(Math.Cos(t), Math.Sin(t));
} }
@ -66,7 +66,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// Convolution with the bluestein sequence (Parallel Version). /// Convolution with the bluestein sequence (Parallel Version).
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void BluesteinConvolutionParallel(Complex[] samples) static void BluesteinConvolutionParallel(Complex[] samples)
{ {
int n = samples.Length; int n = samples.Length;
Complex[] sequence = BluesteinSequence(n); Complex[] sequence = BluesteinSequence(n);
@ -97,7 +97,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
// Build and transform padded sequence a_k = x_k * exp(-I*Pi*k^2/N) // Build and transform padded sequence a_k = x_k * exp(-I*Pi*k^2/N)
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
a[i] = sequence[i].Conjugate() * samples[i]; a[i] = sequence[i].Conjugate()*samples[i];
} }
Radix2(a, -1); Radix2(a, -1);
@ -110,10 +110,10 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
Radix2Parallel(a, 1); Radix2Parallel(a, 1);
var nbinv = 1.0 / m; var nbinv = 1.0/m;
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
samples[i] = nbinv * sequence[i].Conjugate() * a[i]; samples[i] = nbinv*sequence[i].Conjugate()*a[i];
} }
} }
@ -121,7 +121,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// Swap the real and imaginary parts of each sample. /// Swap the real and imaginary parts of each sample.
/// </summary> /// </summary>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void SwapRealImaginary(Complex[] samples) static void SwapRealImaginary(Complex[] samples)
{ {
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
@ -161,7 +161,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public void BluesteinForward(Complex[] samples, FourierOptions options) public static void BluesteinForward(Complex[] samples, FourierOptions options)
{ {
Bluestein(samples, SignByOptions(options)); Bluestein(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples); ForwardScaleByOptions(options, samples);
@ -172,10 +172,10 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public void BluesteinInverse(Complex[] samples, FourierOptions options) public static void BluesteinInverse(Complex[] samples, FourierOptions options)
{ {
Bluestein(samples, -SignByOptions(options)); Bluestein(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples); InverseScaleByOptions(options, samples);
} }
} }
} }

37
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs → src/Numerics/IntegralTransforms/Fourier.Naive.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // 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 // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -28,10 +28,11 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.IntegralTransforms.Algorithms using System;
using MathNet.Numerics.Threading;
namespace MathNet.Numerics.IntegralTransforms
{ {
using System;
using Threading;
#if !NOSYSNUMERICS #if !NOSYSNUMERICS
using Complex = System.Numerics.Complex; using Complex = System.Numerics.Complex;
@ -40,7 +41,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <summary> /// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT). /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary> /// </summary>
public partial class DiscreteFourierTransform public static partial class Fourier
{ {
/// <summary> /// <summary>
/// Naive generic DFT, useful e.g. to verify faster algorithms. /// Naive generic DFT, useful e.g. to verify faster algorithms.
@ -54,20 +55,20 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
var spectrum = new Complex[samples.Length]; var spectrum = new Complex[samples.Length];
CommonParallel.For(0, samples.Length, (u, v) => CommonParallel.For(0, samples.Length, (u, v) =>
{
for (int i = u; i < v; i++)
{ {
for (int i = u; i < v; i++) var wk = w0*i;
var sum = Complex.Zero;
for (var n = 0; n < samples.Length; n++)
{ {
var wk = w0*i; var w = n*wk;
var sum = Complex.Zero; sum += samples[n]*new Complex(Math.Cos(w), Math.Sin(w));
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;
} }
});
spectrum[i] = sum;
}
});
return spectrum; return spectrum;
} }
@ -78,7 +79,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="timeSpace">Time-space sample vector.</param> /// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns> /// <returns>Corresponding frequency-space vector.</returns>
public Complex[] NaiveForward(Complex[] timeSpace, FourierOptions options) public static Complex[] NaiveForward(Complex[] timeSpace, FourierOptions options)
{ {
var frequencySpace = Naive(timeSpace, SignByOptions(options)); var frequencySpace = Naive(timeSpace, SignByOptions(options));
ForwardScaleByOptions(options, frequencySpace); ForwardScaleByOptions(options, frequencySpace);
@ -91,7 +92,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="frequencySpace">Frequency-space sample vector.</param> /// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns> /// <returns>Corresponding time-space vector.</returns>
public Complex[] NaiveInverse(Complex[] frequencySpace, FourierOptions options) public static Complex[] NaiveInverse(Complex[] frequencySpace, FourierOptions options)
{ {
var timeSpace = Naive(frequencySpace, -SignByOptions(options)); var timeSpace = Naive(frequencySpace, -SignByOptions(options));
InverseScaleByOptions(options, timeSpace); InverseScaleByOptions(options, timeSpace);

19
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs → src/Numerics/IntegralTransforms/Fourier.Options.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -28,9 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.IntegralTransforms.Algorithms using System;
namespace MathNet.Numerics.IntegralTransforms
{ {
using System;
#if !NOSYSNUMERICS #if !NOSYSNUMERICS
using Complex = System.Numerics.Complex; using Complex = System.Numerics.Complex;
@ -39,7 +40,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <summary> /// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT). /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary> /// </summary>
public partial class DiscreteFourierTransform public static partial class Fourier
{ {
/// <summary> /// <summary>
/// Extract the exponent sign to be used in forward transforms according to the /// Extract the exponent sign to be used in forward transforms according to the
@ -47,7 +48,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <returns>Fourier series exponent sign.</returns> /// <returns>Fourier series exponent sign.</returns>
private static int SignByOptions(FourierOptions options) static int SignByOptions(FourierOptions options)
{ {
return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1; return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1;
} }
@ -57,7 +58,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void ForwardScaleByOptions(FourierOptions options, Complex[] samples) static void ForwardScaleByOptions(FourierOptions options, Complex[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling || if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling) (options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
@ -65,7 +66,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
return; return;
} }
var scalingFactor = Math.Sqrt(1.0 / samples.Length); var scalingFactor = Math.Sqrt(1.0/samples.Length);
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
samples[i] *= scalingFactor; samples[i] *= scalingFactor;
@ -77,14 +78,14 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void InverseScaleByOptions(FourierOptions options, Complex[] samples) static void InverseScaleByOptions(FourierOptions options, Complex[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling) if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
{ {
return; return;
} }
var scalingFactor = 1.0 / samples.Length; var scalingFactor = 1.0/samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling) if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{ {
scalingFactor = Math.Sqrt(scalingFactor); scalingFactor = Math.Sqrt(scalingFactor);

20
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs → src/Numerics/IntegralTransforms/Fourier.RadixN.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // 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 // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -32,7 +32,7 @@ using System;
using MathNet.Numerics.Properties; using MathNet.Numerics.Properties;
using MathNet.Numerics.Threading; using MathNet.Numerics.Threading;
namespace MathNet.Numerics.IntegralTransforms.Algorithms namespace MathNet.Numerics.IntegralTransforms
{ {
#if !NOSYSNUMERICS #if !NOSYSNUMERICS
@ -42,7 +42,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <summary> /// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT). /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
/// </summary> /// </summary>
public partial class DiscreteFourierTransform public static partial class Fourier
{ {
/// <summary> /// <summary>
/// Radix-2 Reorder Helper Method /// Radix-2 Reorder Helper Method
@ -136,12 +136,12 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
var size = levelSize; var size = levelSize;
CommonParallel.For(0, size, (u, v) => CommonParallel.For(0, size, (u, v) =>
{
for (int i = u; i < v; i++)
{ {
for (int i = u; i < v; i++) Radix2Step(samples, exponentSign, size, i);
{ }
Radix2Step(samples, exponentSign, size, i); });
}
});
} }
} }
@ -151,7 +151,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/> /// <exception cref="ArgumentException"/>
public void Radix2Forward(Complex[] samples, FourierOptions options) public static void Radix2Forward(Complex[] samples, FourierOptions options)
{ {
Radix2Parallel(samples, SignByOptions(options)); Radix2Parallel(samples, SignByOptions(options));
ForwardScaleByOptions(options, samples); ForwardScaleByOptions(options, samples);
@ -163,7 +163,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <exception cref="ArgumentException"/> /// <exception cref="ArgumentException"/>
public void Radix2Inverse(Complex[] samples, FourierOptions options) public static void Radix2Inverse(Complex[] samples, FourierOptions options)
{ {
Radix2Parallel(samples, -SignByOptions(options)); Radix2Parallel(samples, -SignByOptions(options));
InverseScaleByOptions(options, samples); InverseScaleByOptions(options, samples);

6
src/Numerics/IntegralTransforms/FourierOptions.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -28,10 +28,10 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using System;
namespace MathNet.Numerics.IntegralTransforms namespace MathNet.Numerics.IntegralTransforms
{ {
using System;
/// <summary> /// <summary>
/// Fourier Transform Convention /// Fourier Transform Convention
/// </summary> /// </summary>

14
src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Naive.cs → src/Numerics/IntegralTransforms/Hartley.Naive.cs

@ -28,15 +28,15 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.IntegralTransforms.Algorithms using System;
{ using MathNet.Numerics.Threading;
using System;
using Threading;
namespace MathNet.Numerics.IntegralTransforms
{
/// <summary> /// <summary>
/// Fast (FHT) Implementation of the Discrete Hartley Transform (DHT). /// Fast (FHT) Implementation of the Discrete Hartley Transform (DHT).
/// </summary> /// </summary>
public partial class DiscreteHartleyTransform public static partial class Hartley
{ {
/// <summary> /// <summary>
/// Naive generic DHT, useful e.g. to verify faster algorithms. /// Naive generic DHT, useful e.g. to verify faster algorithms.
@ -73,7 +73,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="timeSpace">Time-space sample vector.</param> /// <param name="timeSpace">Time-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param> /// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding frequency-space vector.</returns> /// <returns>Corresponding frequency-space vector.</returns>
public double[] NaiveForward(double[] timeSpace, HartleyOptions options) public static double[] NaiveForward(double[] timeSpace, HartleyOptions options)
{ {
var frequencySpace = Naive(timeSpace); var frequencySpace = Naive(timeSpace);
ForwardScaleByOptions(options, frequencySpace); ForwardScaleByOptions(options, frequencySpace);
@ -86,7 +86,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// <param name="frequencySpace">Frequency-space sample vector.</param> /// <param name="frequencySpace">Frequency-space sample vector.</param>
/// <param name="options">Hartley Transform Convention Options.</param> /// <param name="options">Hartley Transform Convention Options.</param>
/// <returns>Corresponding time-space vector.</returns> /// <returns>Corresponding time-space vector.</returns>
public double[] NaiveInverse(double[] frequencySpace, HartleyOptions options) public static double[] NaiveInverse(double[] frequencySpace, HartleyOptions options)
{ {
var timeSpace = Naive(frequencySpace); var timeSpace = Naive(frequencySpace);
InverseScaleByOptions(options, timeSpace); InverseScaleByOptions(options, timeSpace);

18
src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Options.cs → src/Numerics/IntegralTransforms/Hartley.Options.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -28,21 +28,21 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.IntegralTransforms.Algorithms using System;
{
using System;
namespace MathNet.Numerics.IntegralTransforms
{
/// <summary> /// <summary>
/// Fast (FHT) Implementation of the Discrete Hartley Transform (DHT). /// Fast (FHT) Implementation of the Discrete Hartley Transform (DHT).
/// </summary> /// </summary>
public partial class DiscreteHartleyTransform public static partial class Hartley
{ {
/// <summary> /// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options. /// Rescale FFT-the resulting vector according to the provided convention options.
/// </summary> /// </summary>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void ForwardScaleByOptions(HartleyOptions options, double[] samples) static void ForwardScaleByOptions(HartleyOptions options, double[] samples)
{ {
if ((options & HartleyOptions.NoScaling) == HartleyOptions.NoScaling || if ((options & HartleyOptions.NoScaling) == HartleyOptions.NoScaling ||
(options & HartleyOptions.AsymmetricScaling) == HartleyOptions.AsymmetricScaling) (options & HartleyOptions.AsymmetricScaling) == HartleyOptions.AsymmetricScaling)
@ -50,7 +50,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
return; return;
} }
var scalingFactor = Math.Sqrt(1.0 / samples.Length); var scalingFactor = Math.Sqrt(1.0/samples.Length);
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
samples[i] *= scalingFactor; samples[i] *= scalingFactor;
@ -62,14 +62,14 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
/// </summary> /// </summary>
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
/// <param name="samples">Sample Vector.</param> /// <param name="samples">Sample Vector.</param>
private static void InverseScaleByOptions(HartleyOptions options, double[] samples) static void InverseScaleByOptions(HartleyOptions options, double[] samples)
{ {
if ((options & HartleyOptions.NoScaling) == HartleyOptions.NoScaling) if ((options & HartleyOptions.NoScaling) == HartleyOptions.NoScaling)
{ {
return; return;
} }
var scalingFactor = 1.0 / samples.Length; var scalingFactor = 1.0/samples.Length;
if ((options & HartleyOptions.AsymmetricScaling) != HartleyOptions.AsymmetricScaling) if ((options & HartleyOptions.AsymmetricScaling) != HartleyOptions.AsymmetricScaling)
{ {
scalingFactor = Math.Sqrt(scalingFactor); scalingFactor = Math.Sqrt(scalingFactor);

14
src/Numerics/IntegralTransforms/Transform.cs

@ -4,7 +4,7 @@
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// //
// Copyright (c) 2009-2010 Math.NET // Copyright (c) 2009-2014 Math.NET
// //
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
@ -28,8 +28,6 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using MathNet.Numerics.IntegralTransforms.Algorithms;
namespace MathNet.Numerics.IntegralTransforms namespace MathNet.Numerics.IntegralTransforms
{ {
@ -42,15 +40,13 @@ namespace MathNet.Numerics.IntegralTransforms
/// </summary> /// </summary>
public static class Transform public static class Transform
{ {
private static readonly DiscreteFourierTransform DFT = new DiscreteFourierTransform();
/// <summary> /// <summary>
/// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors. /// Applies the forward Fast Fourier Transform (FFT) to arbitrary-length sample vectors.
/// </summary> /// </summary>
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void FourierForward(Complex[] samples) public static void FourierForward(Complex[] samples)
{ {
DFT.BluesteinForward(samples, FourierOptions.Default); Fourier.BluesteinForward(samples, FourierOptions.Default);
} }
/// <summary> /// <summary>
@ -60,7 +56,7 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public static void FourierForward(Complex[] samples, FourierOptions options) public static void FourierForward(Complex[] samples, FourierOptions options)
{ {
DFT.BluesteinForward(samples, options); Fourier.BluesteinForward(samples, options);
} }
/// <summary> /// <summary>
@ -69,7 +65,7 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param> /// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void FourierInverse(Complex[] samples) public static void FourierInverse(Complex[] samples)
{ {
DFT.BluesteinInverse(samples, FourierOptions.Default); Fourier.BluesteinInverse(samples, FourierOptions.Default);
} }
/// <summary> /// <summary>
@ -79,7 +75,7 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public static void FourierInverse(Complex[] samples, FourierOptions options) public static void FourierInverse(Complex[] samples, FourierOptions options)
{ {
DFT.BluesteinInverse(samples, options); Fourier.BluesteinInverse(samples, options);
} }
} }
} }

12
src/Numerics/Numerics.csproj

@ -371,14 +371,14 @@
<Compile Include="Distributions\IContinuousDistribution.cs" /> <Compile Include="Distributions\IContinuousDistribution.cs" />
<Compile Include="Distributions\IDiscreteDistribution.cs" /> <Compile Include="Distributions\IDiscreteDistribution.cs" />
<Compile Include="Distributions\IUnivariateDistribution.cs" /> <Compile Include="Distributions\IUnivariateDistribution.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteHartleyTransform.Naive.cs" /> <Compile Include="IntegralTransforms\Hartley.Naive.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteHartleyTransform.Options.cs" /> <Compile Include="IntegralTransforms\Hartley.Options.cs" />
<Compile Include="IntegralTransforms\HartleyOptions.cs" /> <Compile Include="IntegralTransforms\HartleyOptions.cs" />
<Compile Include="GlobalizationHelper.cs" /> <Compile Include="GlobalizationHelper.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteFourierTransform.Options.cs" /> <Compile Include="IntegralTransforms\Fourier.Options.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteFourierTransform.Bluestein.cs" /> <Compile Include="IntegralTransforms\Fourier.Bluestein.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteFourierTransform.Naive.cs" /> <Compile Include="IntegralTransforms\Fourier.Naive.cs" />
<Compile Include="IntegralTransforms\Algorithms\DiscreteFourierTransform.RadixN.cs" /> <Compile Include="IntegralTransforms\Fourier.RadixN.cs" />
<Compile Include="IntegralTransforms\Transform.cs" /> <Compile Include="IntegralTransforms\Transform.cs" />
<Compile Include="IntegralTransforms\FourierOptions.cs" /> <Compile Include="IntegralTransforms\FourierOptions.cs" />
<Compile Include="Integration\DoubleExponentialTransformation.cs" /> <Compile Include="Integration\DoubleExponentialTransformation.cs" />

19
src/UnitTests/IntegralTransformsTests/FourierTest.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET //
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -27,7 +31,6 @@
using System; using System;
using MathNet.Numerics.Distributions; using MathNet.Numerics.Distributions;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.IntegralTransforms.Algorithms;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
@ -60,8 +63,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2); var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
// real-odd transforms to imaginary odd // real-odd transforms to imaginary odd
var dft = new DiscreteFourierTransform(); var spectrum = Fourier.NaiveForward(samples, FourierOptions.Matlab);
var spectrum = dft.NaiveForward(samples, FourierOptions.Matlab);
// all real components must be zero // all real components must be zero
foreach (var c in spectrum) foreach (var c in spectrum)
@ -94,12 +96,11 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
public void Radix2ThrowsWhenNotPowerOfTwo() public void Radix2ThrowsWhenNotPowerOfTwo()
{ {
var samples = Generate.RandomComplex(0x7F, GetUniform(1)); var samples = Generate.RandomComplex(0x7F, GetUniform(1));
var dft = new DiscreteFourierTransform();
Assert.Throws(typeof (ArgumentException), () => dft.Radix2Forward(samples, FourierOptions.Default)); Assert.Throws(typeof (ArgumentException), () => Fourier.Radix2Forward(samples, FourierOptions.Default));
Assert.Throws(typeof (ArgumentException), () => dft.Radix2Inverse(samples, FourierOptions.Default)); Assert.Throws(typeof (ArgumentException), () => Fourier.Radix2Inverse(samples, FourierOptions.Default));
Assert.Throws(typeof (ArgumentException), () => DiscreteFourierTransform.Radix2(samples, -1)); Assert.Throws(typeof (ArgumentException), () => Fourier.Radix2(samples, -1));
Assert.Throws(typeof (ArgumentException), () => DiscreteFourierTransform.Radix2Parallel(samples, -1)); Assert.Throws(typeof (ArgumentException), () => Fourier.Radix2Parallel(samples, -1));
} }
} }
} }

12
src/UnitTests/IntegralTransformsTests/HartleyTest.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET //
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -27,7 +31,6 @@
using System; using System;
using MathNet.Numerics.Distributions; using MathNet.Numerics.Distributions;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.IntegralTransforms.Algorithms;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
@ -80,7 +83,6 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(HartleyOptions.NoScaling, FourierOptions.NoScaling)] [TestCase(HartleyOptions.NoScaling, FourierOptions.NoScaling)]
public void NaiveMatchesDft(HartleyOptions hartleyOptions, FourierOptions fourierOptions) public void NaiveMatchesDft(HartleyOptions hartleyOptions, FourierOptions fourierOptions)
{ {
var dht = new DiscreteHartleyTransform();
var samples = Generate.Random(0x80, GetUniform(1)); var samples = Generate.Random(0x80, GetUniform(1));
VerifyMatchesDft( VerifyMatchesDft(
@ -88,13 +90,13 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
5, 5,
false, false,
s => Transform.FourierForward(s, fourierOptions), s => Transform.FourierForward(s, fourierOptions),
s => dht.NaiveForward(s, hartleyOptions)); s => Hartley.NaiveForward(s, hartleyOptions));
VerifyMatchesDft( VerifyMatchesDft(
samples, samples,
5, 5,
true, true,
s => Transform.FourierInverse(s, fourierOptions), s => Transform.FourierInverse(s, fourierOptions),
s => dht.NaiveInverse(s, hartleyOptions)); s => Hartley.NaiveInverse(s, hartleyOptions));
} }
} }
} }

31
src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET //
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -26,7 +30,6 @@
using MathNet.Numerics.Distributions; using MathNet.Numerics.Distributions;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.IntegralTransforms.Algorithms;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
@ -58,16 +61,14 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Matlab)] [TestCase(FourierOptions.Matlab)]
public void FourierNaiveIsReversible(FourierOptions options) public void FourierNaiveIsReversible(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x80, GetUniform(1)); var samples = Generate.RandomComplex(0x80, GetUniform(1));
var work = new Complex[samples.Length]; var work = new Complex[samples.Length];
samples.CopyTo(work, 0); samples.CopyTo(work, 0);
work = dft.NaiveForward(work, options); work = Fourier.NaiveForward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6)); Assert.IsFalse(work.ListAlmostEqual(samples, 6));
work = dft.NaiveInverse(work, options); work = Fourier.NaiveInverse(work, options);
AssertHelpers.ListAlmostEqual(samples, work, 12); AssertHelpers.ListAlmostEqual(samples, work, 12);
} }
@ -79,16 +80,14 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Matlab)] [TestCase(FourierOptions.Matlab)]
public void FourierRadix2IsReversible(FourierOptions options) public void FourierRadix2IsReversible(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x8000, GetUniform(1)); var samples = Generate.RandomComplex(0x8000, GetUniform(1));
var work = new Complex[samples.Length]; var work = new Complex[samples.Length];
samples.CopyTo(work, 0); samples.CopyTo(work, 0);
dft.Radix2Forward(work, options); Fourier.Radix2Forward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6)); Assert.IsFalse(work.ListAlmostEqual(samples, 6));
dft.Radix2Inverse(work, options); Fourier.Radix2Inverse(work, options);
AssertHelpers.ListAlmostEqual(samples, work, 12); AssertHelpers.ListAlmostEqual(samples, work, 12);
} }
@ -100,16 +99,14 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.Matlab)] [TestCase(FourierOptions.Matlab)]
public void FourierBluesteinIsReversible(FourierOptions options) public void FourierBluesteinIsReversible(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x7FFF, GetUniform(1)); var samples = Generate.RandomComplex(0x7FFF, GetUniform(1));
var work = new Complex[samples.Length]; var work = new Complex[samples.Length];
samples.CopyTo(work, 0); samples.CopyTo(work, 0);
dft.BluesteinForward(work, options); Fourier.BluesteinForward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6)); Assert.IsFalse(work.ListAlmostEqual(samples, 6));
dft.BluesteinInverse(work, options); Fourier.BluesteinInverse(work, options);
AssertHelpers.ListAlmostEqual(samples, work, 10); AssertHelpers.ListAlmostEqual(samples, work, 10);
} }
@ -121,16 +118,14 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(HartleyOptions.AsymmetricScaling)] [TestCase(HartleyOptions.AsymmetricScaling)]
public void HartleyNaiveIsReversible(HartleyOptions options) public void HartleyNaiveIsReversible(HartleyOptions options)
{ {
var dht = new DiscreteHartleyTransform();
var samples = Generate.Random(0x80, GetUniform(1)); var samples = Generate.Random(0x80, GetUniform(1));
var work = new double[samples.Length]; var work = new double[samples.Length];
samples.CopyTo(work, 0); samples.CopyTo(work, 0);
work = dht.NaiveForward(work, options); work = Hartley.NaiveForward(work, options);
Assert.IsFalse(work.ListAlmostEqual(samples, 6)); Assert.IsFalse(work.ListAlmostEqual(samples, 6));
work = dht.NaiveInverse(work, options); work = Hartley.NaiveInverse(work, options);
AssertHelpers.ListAlmostEqual(samples, work, 12); AssertHelpers.ListAlmostEqual(samples, work, 12);
} }

52
src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET //
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -27,7 +31,6 @@
using System; using System;
using MathNet.Numerics.Distributions; using MathNet.Numerics.Distributions;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.IntegralTransforms.Algorithms;
using NUnit.Framework; using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
@ -78,20 +81,19 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.NumericalRecipes)] [TestCase(FourierOptions.NumericalRecipes)]
public void FourierRadix2MatchesNaiveOnRealSine(FourierOptions options) public void FourierRadix2MatchesNaiveOnRealSine(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2); var samples = Generate.PeriodicMap(16, w => new Complex(Math.Sin(w), 0), 16, 1.0, Constants.Pi2);
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
12, 12,
s => dft.NaiveForward(s, options), s => Fourier.NaiveForward(s, options),
s => dft.Radix2Forward(s, options)); s => Fourier.Radix2Forward(s, options));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
12, 12,
s => dft.NaiveInverse(s, options), s => Fourier.NaiveInverse(s, options),
s => dft.Radix2Inverse(s, options)); s => Fourier.Radix2Inverse(s, options));
} }
/// <summary> /// <summary>
@ -103,20 +105,19 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.NumericalRecipes)] [TestCase(FourierOptions.NumericalRecipes)]
public void FourierRadix2MatchesNaiveOnRandom(FourierOptions options) public void FourierRadix2MatchesNaiveOnRandom(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x80, GetUniform(1)); var samples = Generate.RandomComplex(0x80, GetUniform(1));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveForward(s, options), s => Fourier.NaiveForward(s, options),
s => dft.Radix2Forward(s, options)); s => Fourier.Radix2Forward(s, options));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveInverse(s, options), s => Fourier.NaiveInverse(s, options),
s => dft.Radix2Inverse(s, options)); s => Fourier.Radix2Inverse(s, options));
} }
/// <summary> /// <summary>
@ -128,20 +129,19 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.NumericalRecipes)] [TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRealSineNonPowerOfTwo(FourierOptions options) public void FourierBluesteinMatchesNaiveOnRealSineNonPowerOfTwo(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.PeriodicMap(14, w => new Complex(Math.Sin(w), 0), 14, 1.0, Constants.Pi2); var samples = Generate.PeriodicMap(14, w => new Complex(Math.Sin(w), 0), 14, 1.0, Constants.Pi2);
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
12, 12,
s => dft.NaiveForward(s, options), s => Fourier.NaiveForward(s, options),
s => dft.BluesteinForward(s, options)); s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
12, 12,
s => dft.NaiveInverse(s, options), s => Fourier.NaiveInverse(s, options),
s => dft.BluesteinInverse(s, options)); s => Fourier.BluesteinInverse(s, options));
} }
/// <summary> /// <summary>
@ -153,20 +153,19 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.NumericalRecipes)] [TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRandomPowerOfTwo(FourierOptions options) public void FourierBluesteinMatchesNaiveOnRandomPowerOfTwo(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x80, GetUniform(1)); var samples = Generate.RandomComplex(0x80, GetUniform(1));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveForward(s, options), s => Fourier.NaiveForward(s, options),
s => dft.BluesteinForward(s, options)); s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveInverse(s, options), s => Fourier.NaiveInverse(s, options),
s => dft.BluesteinInverse(s, options)); s => Fourier.BluesteinInverse(s, options));
} }
/// <summary> /// <summary>
@ -178,19 +177,18 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
[TestCase(FourierOptions.NumericalRecipes)] [TestCase(FourierOptions.NumericalRecipes)]
public void FourierBluesteinMatchesNaiveOnRandomNonPowerOfTwo(FourierOptions options) public void FourierBluesteinMatchesNaiveOnRandomNonPowerOfTwo(FourierOptions options)
{ {
var dft = new DiscreteFourierTransform();
var samples = Generate.RandomComplex(0x7F, GetUniform(1)); var samples = Generate.RandomComplex(0x7F, GetUniform(1));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveForward(s, options), s => Fourier.NaiveForward(s, options),
s => dft.BluesteinForward(s, options)); s => Fourier.BluesteinForward(s, options));
VerifyMatchesNaiveComplex( VerifyMatchesNaiveComplex(
samples, samples,
10, 10,
s => dft.NaiveInverse(s, options), s => Fourier.NaiveInverse(s, options),
s => dft.BluesteinInverse(s, options)); s => Fourier.BluesteinInverse(s, options));
} }
} }
} }

11
src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com // http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET //
// Copyright (c) 2009-2014 Math.NET
//
// Permission is hereby granted, free of charge, to any person // Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation // obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without // files (the "Software"), to deal in the Software without
@ -12,8 +14,10 @@
// copies of the Software, and to permit persons to whom the // copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following // Software is furnished to do so, subject to the following
// conditions: // conditions:
//
// The above copyright notice and this permission notice shall be // The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software. // included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -27,7 +31,6 @@
using System.Linq; using System.Linq;
using MathNet.Numerics.Distributions; using MathNet.Numerics.Distributions;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
using MathNet.Numerics.IntegralTransforms.Algorithms;
using MathNet.Numerics.Statistics; using MathNet.Numerics.Statistics;
using NUnit.Framework; using NUnit.Framework;
@ -91,12 +94,10 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
samples.CopyTo(work, 0); samples.CopyTo(work, 0);
// Default -> Symmetric Scaling // Default -> Symmetric Scaling
var dht = new DiscreteHartleyTransform(); work = Hartley.NaiveForward(work, HartleyOptions.Default);
work = dht.NaiveForward(work, HartleyOptions.Default);
var frequencySpaceEnergy = (from s in work select s*s).Mean(); var frequencySpaceEnergy = (from s in work select s*s).Mean();
Assert.AreEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12); Assert.AreEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12);
} }
} }
} }

Loading…
Cancel
Save