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://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
// obtaining a copy of this software and associated documentation
@ -28,6 +28,7 @@
// </copyright>
using System;
using MathNet.Numerics.Providers.FourierTransform;
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>
public static void Forward(Complex[] samples)
{
BluesteinForward(samples, FourierOptions.Default);
Control.FourierTransformProvider.ForwardInplace(samples, FourierTransformScaling.SymmetricScaling);
}
/// <summary>
@ -56,7 +57,23 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param>
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>
@ -65,7 +82,7 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="samples">Sample vector, where the FFT is evaluated in place.</param>
public static void Inverse(Complex[] samples)
{
BluesteinInverse(samples, FourierOptions.Default);
Control.FourierTransformProvider.BackwardInplace(samples, FourierTransformScaling.SymmetricScaling);
}
/// <summary>
@ -75,7 +92,27 @@ namespace MathNet.Numerics.IntegralTransforms
/// <param name="options">Fourier Transform Convention Options.</param>
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>

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

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

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

@ -26,6 +26,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System.Collections;
using MathNet.Numerics.IntegralTransforms;
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.
/// Verification may still fail if available, but it will certainly fail if unavailable.
/// </summary>
public virtual bool IsAvailable()
public bool IsAvailable()
{
return true;
}
@ -49,26 +50,49 @@ namespace MathNet.Numerics.Providers.FourierTransform
/// <summary>
/// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
/// </summary>
public virtual void InitializeVerify()
public void InitializeVerify()
{
}
public override string ToString()
public string ToString()
{
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];
complexTimeSpace.Copy(work);
@ -76,26 +100,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
return work;
}
public virtual Complex[] Backward(Complex[] complexFrequenceSpace, FourierTransformScaling scaling)
public Complex[] Backward(Complex[] complexFrequenceSpace, FourierTransformScaling scaling)
{
Complex[] work = new Complex[complexFrequenceSpace.Length];
complexFrequenceSpace.Copy(work);
BackwardInplace(work, scaling);
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;
}
private double ForwardScaling(FourierTransformScaling scaling, int length)
static double ForwardScaling(FourierTransformScaling scaling, int length)
{
switch (scaling)
{
case FourierTransformScaling.SymmetricScaling:
return Math.Sqrt(1.0/length);
case FourierTransformScaling.ForwardScaling:
return 1.0/length;
default:
return 1.0;
}
}
private double BackwardScaling(FourierTransformScaling scaling, int length)
static double BackwardScaling(FourierTransformScaling scaling, int length)
{
switch (scaling)
{
case FourierTransformScaling.SymmetricScaling:
return Math.Sqrt(1.0/length);
case FourierTransformScaling.AsymmetricScaling:
case FourierTransformScaling.BackwardScaling:
return 1.0/length;
default:
return 1.0;

2
src/UnitTests/FourierTransformProviderTests/FourierTransformProviderTests.cs

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

Loading…
Cancel
Save