Browse Source

FFT: activate in Fourier.Forward/Backward, with full option mapping

benchmark-la
Christoph Ruegg 10 years ago
parent
commit
4bad397c44
  1. 47
      src/Numerics/IntegralTransforms/Fourier.cs
  2. 3
      src/Numerics/Providers/FourierTransform/IFourierTransformProvider.cs
  3. 56
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs
  4. 8
      src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs
  5. 2
      src/UnitTests/FourierTransformProviderTests/FourierTransformProviderTests.cs

47
src/Numerics/IntegralTransforms/Fourier.cs

@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com // http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics // http://github.com/mathnet/mathnet-numerics
// //
// Copyright (c) 2009-2015 Math.NET // Copyright (c) 2009-2016 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,6 +28,7 @@
// </copyright> // </copyright>
using System; using System;
using MathNet.Numerics.Providers.FourierTransform;
namespace MathNet.Numerics.IntegralTransforms namespace MathNet.Numerics.IntegralTransforms
{ {
@ -46,7 +47,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 Forward(Complex[] samples) public static void Forward(Complex[] samples)
{ {
BluesteinForward(samples, FourierOptions.Default); Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.SymmetricScaling);
} }
/// <summary> /// <summary>
@ -56,7 +57,23 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public static void Forward(Complex[] samples, FourierOptions options) public static void Forward(Complex[] samples, FourierOptions options)
{ {
BluesteinForward(samples, options); switch (options)
{
case FourierOptions.NoScaling:
case FourierOptions.AsymmetricScaling:
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.NoScaling);
break;
case FourierOptions.InverseExponent:
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.SymmetricScaling);
break;
case FourierOptions.InverseExponent | FourierOptions.NoScaling:
case FourierOptions.InverseExponent | FourierOptions.AsymmetricScaling:
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.NoScaling);
break;
default:
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.SymmetricScaling);
break;
}
} }
/// <summary> /// <summary>
@ -65,7 +82,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 Inverse(Complex[] samples) public static void Inverse(Complex[] samples)
{ {
BluesteinInverse(samples, FourierOptions.Default); Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.SymmetricScaling);
} }
/// <summary> /// <summary>
@ -75,7 +92,27 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param> /// <param name="options">Fourier Transform Convention Options.</param>
public static void Inverse(Complex[] samples, FourierOptions options) public static void Inverse(Complex[] samples, FourierOptions options)
{ {
BluesteinInverse(samples, options); switch (options)
{
case FourierOptions.NoScaling:
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.NoScaling);
break;
case FourierOptions.AsymmetricScaling:
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.BackwardScaling);
break;
case FourierOptions.InverseExponent:
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.SymmetricScaling);
break;
case FourierOptions.InverseExponent | FourierOptions.NoScaling:
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.NoScaling);
break;
case FourierOptions.InverseExponent | FourierOptions.AsymmetricScaling:
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.ForwardScaling);
break;
default:
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.SymmetricScaling);
break;
}
} }
/// <summary> /// <summary>

3
src/Numerics/Providers/FourierTransform/IFourierTransformProvider.cs

@ -38,7 +38,8 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
NoScaling = 0, NoScaling = 0,
SymmetricScaling = 1, SymmetricScaling = 1,
AsymmetricScaling = 2 BackwardScaling = 2,
ForwardScaling = 3
} }
public interface IFourierTransformProvider public interface IFourierTransformProvider

56
src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs

@ -26,6 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
using System.Collections;
using MathNet.Numerics.IntegralTransforms; using MathNet.Numerics.IntegralTransforms;
namespace MathNet.Numerics.Providers.FourierTransform namespace MathNet.Numerics.Providers.FourierTransform
@ -41,7 +42,7 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// Try to find out whether the provider is available, at least in principle. /// Try to find out whether the provider is available, at least in principle.
/// Verification may still fail if available, but it will certainly fail if unavailable. /// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary> /// </summary>
public virtual bool IsAvailable() public bool IsAvailable()
{ {
return true; return true;
} }
@ -49,26 +50,49 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary> /// <summary>
/// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider /// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
/// </summary> /// </summary>
public virtual void InitializeVerify() public void InitializeVerify()
{ {
} }
public override string ToString() public string ToString()
{ {
return "Managed"; return "Managed";
} }
public virtual void ForwardInplace(Complex[] complex, FourierTransformScaling scaling) public void ForwardInplace(Complex[] complex, FourierTransformScaling scaling)
{ {
Fourier.BluesteinForward(complex, Options(scaling)); switch (scaling)
{
case FourierTransformScaling.SymmetricScaling:
Fourier.BluesteinForward(complex, FourierOptions.Default);
break;
case FourierTransformScaling.ForwardScaling:
// Only backward scaling can be expressed with options, hence the double-inverse
Fourier.BluesteinInverse(complex, FourierOptions.AsymmetricScaling | FourierOptions.InverseExponent);
break;
default:
Fourier.BluesteinForward(complex, FourierOptions.NoScaling);
break;
}
} }
public virtual void BackwardInplace(Complex[] complex, FourierTransformScaling scaling) public void BackwardInplace(Complex[] complex, FourierTransformScaling scaling)
{ {
Fourier.BluesteinInverse(complex, Options(scaling)); switch (scaling)
{
case FourierTransformScaling.SymmetricScaling:
Fourier.BluesteinInverse(complex, FourierOptions.Default);
break;
case FourierTransformScaling.BackwardScaling:
Fourier.BluesteinInverse(complex, FourierOptions.AsymmetricScaling);
break;
default:
Fourier.BluesteinInverse(complex, FourierOptions.NoScaling);
break;
}
} }
public virtual Complex[] Forward(Complex[] complexTimeSpace, FourierTransformScaling scaling) public Complex[] Forward(Complex[] complexTimeSpace, FourierTransformScaling scaling)
{ {
Complex[] work = new Complex[complexTimeSpace.Length]; Complex[] work = new Complex[complexTimeSpace.Length];
complexTimeSpace.Copy(work); complexTimeSpace.Copy(work);
@ -76,26 +100,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
return work; return work;
} }
public virtual Complex[] Backward(Complex[] complexFrequenceSpace, FourierTransformScaling scaling) public Complex[] Backward(Complex[] complexFrequenceSpace, FourierTransformScaling scaling)
{ {
Complex[] work = new Complex[complexFrequenceSpace.Length]; Complex[] work = new Complex[complexFrequenceSpace.Length];
complexFrequenceSpace.Copy(work); complexFrequenceSpace.Copy(work);
BackwardInplace(work, scaling); BackwardInplace(work, scaling);
return work; return work;
} }
private FourierOptions Options(FourierTransformScaling scaling)
{
switch (scaling)
{
case FourierTransformScaling.NoScaling:
return FourierOptions.NoScaling;
case FourierTransformScaling.AsymmetricScaling:
return FourierOptions.AsymmetricScaling;
case FourierTransformScaling.SymmetricScaling:
default:
return FourierOptions.Default;
}
}
} }
} }

8
src/Numerics/Providers/FourierTransform/Mkl/MklFourierTransformProvider.cs

@ -152,24 +152,26 @@ namespace MathNet.Numerics.Providers.FourierTransform.Mkl
return work; return work;
} }
private double ForwardScaling(FourierTransformScaling scaling, int length) static double ForwardScaling(FourierTransformScaling scaling, int length)
{ {
switch (scaling) switch (scaling)
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
return Math.Sqrt(1.0/length); return Math.Sqrt(1.0/length);
case FourierTransformScaling.ForwardScaling:
return 1.0/length;
default: default:
return 1.0; return 1.0;
} }
} }
private double BackwardScaling(FourierTransformScaling scaling, int length) static double BackwardScaling(FourierTransformScaling scaling, int length)
{ {
switch (scaling) switch (scaling)
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
return Math.Sqrt(1.0/length); return Math.Sqrt(1.0/length);
case FourierTransformScaling.AsymmetricScaling: case FourierTransformScaling.BackwardScaling:
return 1.0/length; return 1.0/length;
default: default:
return 1.0; return 1.0;

2
src/UnitTests/FourierTransformProviderTests/FourierTransformProviderTests.cs

@ -55,7 +55,7 @@ namespace MathNet.Numerics.UnitTests.FourierTransformProviderTests
// real-odd transforms to imaginary odd // real-odd transforms to imaginary odd
samples.Copy(spectrum); samples.Copy(spectrum);
Control.FourierTransformProvider.ForwardInplace(spectrum, FourierTransformScaling.AsymmetricScaling); Control.FourierTransformProvider.ForwardInplace(spectrum, FourierTransformScaling.BackwardScaling);
// all real components must be zero // all real components must be zero
foreach (var c in spectrum) foreach (var c in spectrum)

Loading…
Cancel
Save