|
|
|
@ -30,6 +30,7 @@ |
|
|
|
using System; |
|
|
|
using MathNet.Numerics.Distributions; |
|
|
|
using MathNet.Numerics.IntegralTransforms; |
|
|
|
using MathNet.Numerics.Providers.FourierTransform; |
|
|
|
using NUnit.Framework; |
|
|
|
|
|
|
|
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests |
|
|
|
@ -69,6 +70,24 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests |
|
|
|
AssertHelpers.AlmostEqual(spectrumNaive, spectrumFast, maximumErrorDecimalPlaces); |
|
|
|
} |
|
|
|
|
|
|
|
static void VerifyInplace( |
|
|
|
Complex[] samples, |
|
|
|
int maximumErrorDecimalPlaces, |
|
|
|
FourierOptions options, |
|
|
|
Action<Complex[], FourierOptions> expected, |
|
|
|
Action<Complex[], FourierOptions> actual) |
|
|
|
{ |
|
|
|
var spectrumExpected = new Complex[samples.Length]; |
|
|
|
samples.CopyTo(spectrumExpected, 0); |
|
|
|
expected(spectrumExpected, options); |
|
|
|
|
|
|
|
var spectrumActual = new Complex[samples.Length]; |
|
|
|
samples.CopyTo(spectrumActual, 0); |
|
|
|
actual(spectrumActual, options); |
|
|
|
|
|
|
|
AssertHelpers.AlmostEqual(spectrumExpected, spectrumActual, maximumErrorDecimalPlaces); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Fourier Radix2XX matches naive on real sine.
|
|
|
|
/// </summary>
|
|
|
|
@ -144,6 +163,57 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests |
|
|
|
Verify(samples, 10, options, Fourier.NaiveInverse, Fourier.BluesteinInverse); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Fourier bluestein matches providers on random power of two.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="options">Fourier options.</param>
|
|
|
|
[TestCase(FourierOptions.Default)] |
|
|
|
[TestCase(FourierOptions.NoScaling)] |
|
|
|
[TestCase(FourierOptions.AsymmetricScaling)] |
|
|
|
[TestCase(FourierOptions.InverseExponent)] |
|
|
|
[TestCase(FourierOptions.InverseExponent | FourierOptions.NoScaling)] |
|
|
|
[TestCase(FourierOptions.InverseExponent | FourierOptions.AsymmetricScaling)] |
|
|
|
public void FourierBluesteinMatchesProvider_Random_Arbitrary(FourierOptions options) |
|
|
|
{ |
|
|
|
var samples = Generate.RandomComplex(0x7F, GetUniform(1)); |
|
|
|
|
|
|
|
VerifyInplace(samples, 10, options, Fourier.Forward, Fourier.BluesteinForward); |
|
|
|
VerifyInplace(samples, 10, options, Fourier.Inverse, Fourier.BluesteinInverse); |
|
|
|
} |
|
|
|
|
|
|
|
[Test] |
|
|
|
public void AlgorithmsMatchProvider_PowerOfTwo_Large() |
|
|
|
{ |
|
|
|
// 65536 = 2^16
|
|
|
|
const FourierOptions options = FourierOptions.NoScaling; |
|
|
|
var samples = Generate.RandomComplex(65536, GetUniform(1)); |
|
|
|
var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); |
|
|
|
|
|
|
|
Verify(samples, 10, options, (a, b) => provider, Fourier.Radix2Forward); |
|
|
|
Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); |
|
|
|
} |
|
|
|
|
|
|
|
[Test] |
|
|
|
public void AlgorithmsMatchProvider_Arbitrary_Large() |
|
|
|
{ |
|
|
|
// 30870 = 2*3*3*5*7*7*7
|
|
|
|
const FourierOptions options = FourierOptions.NoScaling; |
|
|
|
var samples = Generate.RandomComplex(30870, GetUniform(1)); |
|
|
|
var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); |
|
|
|
|
|
|
|
Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); |
|
|
|
} |
|
|
|
|
|
|
|
[Test] |
|
|
|
public void AlgorithmsMatchProvider_Arbitrary_Large_GH286() |
|
|
|
{ |
|
|
|
const FourierOptions options = FourierOptions.NoScaling; |
|
|
|
var samples = Generate.RandomComplex(46500, GetUniform(1)); |
|
|
|
var provider = Control.FourierTransformProvider.Forward(samples, FourierTransformScaling.NoScaling); |
|
|
|
|
|
|
|
Verify(samples, 10, options, (a, b) => provider, Fourier.BluesteinForward); |
|
|
|
} |
|
|
|
|
|
|
|
[Test, Explicit("Long-Running")] |
|
|
|
public void AlgorithmsMatchNaive_PowerOfTwo_Large() |
|
|
|
{ |
|
|
|
|