Browse Source

FFT: simplify rescaling logic

spatial
Christoph Ruegg 9 years ago
parent
commit
7614be2ee6
  1. 97
      src/Numerics/Providers/FourierTransform/ManagedFourierTransformProvider.cs

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

@ -27,7 +27,6 @@
// </copyright> // </copyright>
using System; using System;
using MathNet.Numerics.IntegralTransforms;
using Complex = System.Numerics.Complex; using Complex = System.Numerics.Complex;
@ -72,17 +71,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
{ {
ForwardScaleByOptions(FourierOptions.Default, samples); HalfRescale(samples);
break; break;
} }
case FourierTransformScaling.ForwardScaling: case FourierTransformScaling.ForwardScaling:
{ {
InverseScaleByOptions(FourierOptions.AsymmetricScaling | FourierOptions.InverseExponent, samples); FullRescale(samples);
break;
}
default:
{
ForwardScaleByOptions(FourierOptions.NoScaling, samples);
break; break;
} }
} }
@ -96,17 +90,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
{ {
ForwardScaleByOptions(FourierOptions.Default, samples); HalfRescale(samples);
break; break;
} }
case FourierTransformScaling.ForwardScaling: case FourierTransformScaling.ForwardScaling:
{ {
InverseScaleByOptions(FourierOptions.AsymmetricScaling | FourierOptions.InverseExponent, samples); FullRescale(samples);
break;
}
default:
{
ForwardScaleByOptions(FourierOptions.NoScaling, samples);
break; break;
} }
} }
@ -120,17 +109,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
{ {
InverseScaleByOptions(FourierOptions.Default, spectrum); HalfRescale(spectrum);
break; break;
} }
case FourierTransformScaling.BackwardScaling: case FourierTransformScaling.BackwardScaling:
{ {
InverseScaleByOptions(FourierOptions.AsymmetricScaling, spectrum); FullRescale(spectrum);
break;
}
default:
{
InverseScaleByOptions(FourierOptions.NoScaling, spectrum);
break; break;
} }
} }
@ -144,17 +128,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
{ {
case FourierTransformScaling.SymmetricScaling: case FourierTransformScaling.SymmetricScaling:
{ {
InverseScaleByOptions(FourierOptions.Default, spectrum); HalfRescale(spectrum);
break; break;
} }
case FourierTransformScaling.BackwardScaling: case FourierTransformScaling.BackwardScaling:
{ {
InverseScaleByOptions(FourierOptions.AsymmetricScaling, spectrum); FullRescale(spectrum);
break;
}
default:
{
InverseScaleByOptions(FourierOptions.NoScaling, spectrum);
break; break;
} }
} }
@ -303,19 +282,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
} }
/// <summary> /// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options. /// Fully rescale the FFT result.
/// </summary> /// </summary>
/// <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, Complex32[] samples) private static void FullRescale(Complex32[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling || var scalingFactor = (float)1.0 / samples.Length;
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
var scalingFactor = (float)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;
@ -323,19 +295,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
} }
/// <summary> /// <summary>
/// Rescale FFT-the resulting vector according to the provided convention options. /// Fully rescale the FFT result.
/// </summary> /// </summary>
/// <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) private static void FullRescale(Complex[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling || var scalingFactor = 1.0 / samples.Length;
(options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
{
return;
}
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;
@ -343,23 +308,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
} }
/// <summary> /// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options. /// Half rescale the FFT result (e.g. for symmetric transforms).
/// </summary> /// </summary>
/// <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, Complex32[] samples) private static void HalfRescale(Complex32[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling) var scalingFactor = (float)Math.Sqrt(1.0 / samples.Length);
{
return;
}
var scalingFactor = (float)1.0 / samples.Length;
if ((options & FourierOptions.AsymmetricScaling) != FourierOptions.AsymmetricScaling)
{
scalingFactor = (float)Math.Sqrt(scalingFactor);
}
for (int i = 0; i < samples.Length; i++) for (int i = 0; i < samples.Length; i++)
{ {
samples[i] *= scalingFactor; samples[i] *= scalingFactor;
@ -367,23 +321,12 @@ namespace MathNet.Numerics.Providers.FourierTransform
} }
/// <summary> /// <summary>
/// Rescale the iFFT-resulting vector according to the provided convention options. /// Fully rescale the FFT result (e.g. for symmetric transforms).
/// </summary> /// </summary>
/// <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) private static void HalfRescale(Complex[] samples)
{ {
if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling) var scalingFactor = Math.Sqrt(1.0 / samples.Length);
{
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++) for (int i = 0; i < samples.Length; i++)
{ {
samples[i] *= scalingFactor; samples[i] *= scalingFactor;

Loading…
Cancel
Save