diff --git a/src/Managed.UnitTests/IntegralTransformsTests/DftTest.cs b/src/Managed.UnitTests/IntegralTransformsTests/DftTest.cs
new file mode 100644
index 00000000..cf1e4b1f
--- /dev/null
+++ b/src/Managed.UnitTests/IntegralTransformsTests/DftTest.cs
@@ -0,0 +1,246 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
+{
+ using System;
+ using MbUnit.Framework;
+ using IntegralTransforms;
+ using IntegralTransforms.Algorithms;
+
+ [TestFixture]
+ public class DftTest
+ {
+ private static Random _random = new Random();
+
+ private static Complex[] ProvideSamples(int count)
+ {
+ var samples = new Complex[count];
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = Complex.WithRealImaginary(
+ 1 - (2 * _random.NextDouble()),
+ 1 - (2 * _random.NextDouble()));
+ }
+
+ return samples;
+ }
+
+ [Test]
+ public void NaiveTransformsRealSineCorrectly()
+ {
+ var realSine = new Complex[16];
+ for (int i = 0; i < realSine.Length; i++)
+ {
+ realSine[i] = Math.Sin(i / 8.0 * Constants.Pi);
+ }
+
+ // real-odd transforms to imaginary odd
+ var dft = new DiscreteFourierTransform();
+ var spectrum = dft.NaiveForward(realSine, FourierOptions.Matlab);
+
+ // all real components must be zero
+ foreach (var c in spectrum)
+ {
+ Assert.AreApproximatelyEqual(0, c.Real, 1e-12, "real");
+ }
+
+ // all imaginary components except second and last musth be zero
+ for(int i = 0; i dft.Radix2Forward(samples, FourierOptions.Default));
+
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => dft.Radix2Inverse(samples, FourierOptions.Default));
+ }
+
+ [Test]
+ public void BluesteinMatchesNaiveOnRealSine()
+ {
+ var realSine = new Complex[14];
+ for (int i = 0; i < realSine.Length; i++)
+ {
+ realSine[i] = Math.Sin(i / 7.0 * Constants.Pi);
+ }
+
+ // real-odd transforms to imaginary odd
+ var dft = new DiscreteFourierTransform();
+ var spectrumNaive = dft.NaiveForward(realSine, FourierOptions.Matlab);
+
+ var spectrumBluestein = new Complex[realSine.Length];
+ realSine.CopyTo(spectrumBluestein, 0);
+ dft.BluesteinForward(spectrumBluestein, FourierOptions.Matlab);
+
+ AssertHelpers.AlmostEqualList(spectrumNaive, spectrumBluestein, 1e-12);
+ }
+
+ [Test]
+ public void BluesteinMatchesNaiveOnRandomPowerOfTwo()
+ {
+ var samples = ProvideSamples(0x80);
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ var dft = new DiscreteFourierTransform();
+ var spectrumNaive = dft.NaiveForward(samples, FourierOptions.Matlab);
+ dft.BluesteinForward(work, FourierOptions.Matlab);
+
+ AssertHelpers.AlmostEqualList(spectrumNaive, work, 1e-12);
+ }
+
+ [Test]
+ public void BluesteinMatchesNaiveOnRandomNonPowerOfTwo()
+ {
+ var samples = ProvideSamples(0x7F);
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ var dft = new DiscreteFourierTransform();
+ var spectrumNaive = dft.NaiveForward(samples, FourierOptions.Matlab);
+ dft.BluesteinForward(work, FourierOptions.Matlab);
+
+ AssertHelpers.AlmostEqualList(spectrumNaive, work, 1e-12);
+ }
+
+ [Test]
+ [Row(FourierOptions.Default)]
+ [Row(FourierOptions.Matlab)]
+ public void BluesteinIsReversible(FourierOptions options)
+ {
+ var samples = ProvideSamples(0x7FFF);
+ var work = new Complex[samples.Length];
+ samples.CopyTo(work, 0);
+
+ var dft = new DiscreteFourierTransform();
+ dft.BluesteinForward(work, options);
+
+ Assert.IsFalse(work.AlmostEqualListWithError(samples, 1e-12));
+
+ dft.BluesteinInverse(work, options);
+
+ AssertHelpers.AlmostEqualList(samples, work, 1e-12);
+ }
+ }
+}
diff --git a/src/Managed.UnitTests/Managed.UnitTests.csproj b/src/Managed.UnitTests/Managed.UnitTests.csproj
index ed40e357..d987d51d 100644
--- a/src/Managed.UnitTests/Managed.UnitTests.csproj
+++ b/src/Managed.UnitTests/Managed.UnitTests.csproj
@@ -64,6 +64,7 @@
+
diff --git a/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
new file mode 100644
index 00000000..2fd90d99
--- /dev/null
+++ b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
@@ -0,0 +1,175 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.IntegralTransforms.Algorithms
+{
+ using System;
+ using NumberTheory;
+ using Threading;
+
+ ///
+ /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
+ ///
+ public partial class DiscreteFourierTransform
+ {
+ ///
+ /// Generate the bluestein sequence for the provided problem size.
+ ///
+ /// Number of samples.
+ /// Bluestein sequence exp(I*Pi*k^2/N)
+ private static Complex[] BluesteinSequence(int n)
+ {
+ double s = Constants.Pi / n;
+ var sequence = new Complex[n];
+
+ for (int k = 0; k < sequence.Length; k++)
+ {
+ double t = s * (k * k);
+ sequence[k] = Complex.WithRealImaginary(Math.Cos(t), Math.Sin(t));
+ }
+
+ return sequence;
+ }
+
+ ///
+ /// Convolution with the bluestein sequence.
+ ///
+ /// Sample Vector.
+ private static void BluesteinConvolution(Complex[] samples)
+ {
+ int n = samples.Length;
+ Complex[] sequence = BluesteinSequence(n);
+
+ // Padding to power of two >= 2N–1 so we can apply Radix-2 FFT.
+ int m = ((n << 1) - 1).CeilingToPowerOfTwo();
+ Complex[] b = new Complex[m];
+ Complex[] a = new Complex[m];
+
+ Parallel.Invoke(
+ () =>
+ {
+ // Build and transform padded sequence b_k = exp(I*Pi*k^2/N)
+ for (int i = 0; i < n; i++)
+ {
+ b[i] = sequence[i];
+ }
+
+ for (int i = m - n + 1; i < b.Length; i++)
+ {
+ b[i] = sequence[m - i];
+ }
+
+ Radix2(b, -1);
+ },
+ () =>
+ {
+ // Build and transform padded sequence a_k = x_k * exp(-I*Pi*k^2/N)
+ for (int i = 0; i < samples.Length; i++)
+ {
+ a[i] = sequence[i].Conjugate * samples[i];
+ }
+
+ Radix2(a, -1);
+ });
+
+ for (int i = 0; i < a.Length; i++)
+ {
+ a[i] *= b[i];
+ }
+
+ Radix2(a, 1);
+
+ var nbinv = 1.0 / m;
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = nbinv * sequence[i].Conjugate * a[i];
+ }
+ }
+
+ ///
+ /// Swap the real and imaginary parts of each sample.
+ ///
+ /// Sample Vector.
+ private static void SwapRealImaginary(Complex[] samples)
+ {
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] = Complex.WithRealImaginary(samples[i].Imaginary, samples[i].Real);
+ }
+ }
+
+ ///
+ /// Bluestein generic DFT, useful e.g. to verify faster algorithms.
+ ///
+ /// Time-space sample vector.
+ /// Fourier series exponent sign.
+ internal static void Bluestein(Complex[] samples, int exponentSign)
+ {
+ int n = samples.Length;
+ if (n.IsPowerOfTwo())
+ {
+ Radix2(samples, exponentSign);
+ return;
+ }
+
+ if (exponentSign == 1)
+ {
+ SwapRealImaginary(samples);
+ }
+
+ BluesteinConvolution(samples);
+
+ if (exponentSign == 1)
+ {
+ SwapRealImaginary(samples);
+ }
+ }
+
+ ///
+ /// Bluestein forward FFT for arbitrary sample vectors.
+ ///
+ /// Sample vector, where the FFT is evaluated in place.
+ /// Fourier Transform Convention Options.
+ public void BluesteinForward(Complex[] samples, FourierOptions options)
+ {
+ Bluestein(samples, SignByOptions(options));
+ ForwardScaleByOptions(options, samples);
+ }
+
+ ///
+ /// Bluestein inverse FFT for arbitrary sample vectors.
+ ///
+ /// Sample vector, where the FFT is evaluated in place.
+ /// Fourier Transform Convention Options.
+ public void BluesteinInverse(Complex[] samples, FourierOptions options)
+ {
+ Bluestein(samples, -SignByOptions(options));
+ InverseScaleByOptions(options, samples);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
new file mode 100644
index 00000000..b5ba03f8
--- /dev/null
+++ b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
@@ -0,0 +1,95 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.IntegralTransforms.Algorithms
+{
+ using System;
+ using Threading;
+
+ ///
+ /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
+ ///
+ public partial class DiscreteFourierTransform
+ {
+ ///
+ /// Naive generic DFT, useful e.g. to verify faster algorithms.
+ ///
+ /// Time-space sample vector.
+ /// Fourier series exponent sign.
+ /// Corresponding frequency-space vector.
+ internal static Complex[] Naive(Complex[] samples, int exponentSign)
+ {
+ double w0 = exponentSign * 2 * Constants.Pi / samples.Length;
+ var spectrum = new Complex[samples.Length];
+
+ Parallel.For(
+ 0,
+ samples.Length,
+ k =>
+ {
+ double wk = w0 * k;
+ Complex sum = Complex.Zero;
+ for (int n = 0; n < samples.Length; n++)
+ {
+ double w = n * wk;
+ sum += samples[n] * Complex.WithRealImaginary(Math.Cos(w), Math.Sin(w));
+ }
+
+ spectrum[k] = sum;
+ });
+
+ return spectrum;
+ }
+
+ ///
+ /// Naive forward DFT, useful e.g. to verify faster algorithms.
+ ///
+ /// Time-space sample vector.
+ /// Fourier Transform Convention Options.
+ /// Corresponding frequency-space vector.
+ public Complex[] NaiveForward(Complex[] timeSpace, FourierOptions options)
+ {
+ var frequencySpace = Naive(timeSpace, SignByOptions(options));
+ ForwardScaleByOptions(options, frequencySpace);
+ return frequencySpace;
+ }
+
+ ///
+ /// Naive inverse DFT, useful e.g. to verify faster algorithms.
+ ///
+ /// Frequency-space sample vector.
+ /// Fourier Transform Convention Options.
+ /// Corresponding time-space vector.
+ public Complex[] NaiveInverse(Complex[] frequencySpace, FourierOptions options)
+ {
+ var timeSpace = Naive(frequencySpace, -SignByOptions(options));
+ InverseScaleByOptions(options, timeSpace);
+ return timeSpace;
+ }
+ }
+}
diff --git a/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs
new file mode 100644
index 00000000..bff00a96
--- /dev/null
+++ b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs
@@ -0,0 +1,93 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.IntegralTransforms.Algorithms
+{
+ using System;
+
+ ///
+ /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
+ ///
+ public partial class DiscreteFourierTransform
+ {
+ ///
+ /// Extract the exponent sign to be used in forward transforms according to the
+ /// provided convention options.
+ ///
+ /// Fourier Transform Convention Options.
+ /// Fourier series exponent sign.
+ private static int SignByOptions(FourierOptions options)
+ {
+ return (options & FourierOptions.InverseExponent) == FourierOptions.InverseExponent ? 1 : -1;
+ }
+
+ ///
+ /// Rescale FFT-the resulting vector according to the provided convention options.
+ ///
+ /// Fourier Transform Convention Options.
+ /// Sample Vector.
+ private static void ForwardScaleByOptions(FourierOptions options, Complex[] samples)
+ {
+ if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling ||
+ (options & FourierOptions.AsymmetricScaling) == FourierOptions.AsymmetricScaling)
+ {
+ return;
+ }
+
+ var scalingFactor = Math.Sqrt(1.0 / samples.Length);
+ for (int i = 0; i < samples.Length; i++)
+ {
+ samples[i] *= scalingFactor;
+ }
+ }
+
+ ///
+ /// Rescale the iFFT-resulting vector according to the provided convention options.
+ ///
+ /// Fourier Transform Convention Options.
+ /// Sample Vector.
+ private static void InverseScaleByOptions(FourierOptions options, Complex[] samples)
+ {
+ if ((options & FourierOptions.NoScaling) == FourierOptions.NoScaling)
+ {
+ 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++)
+ {
+ samples[i] *= scalingFactor;
+ }
+ }
+ }
+}
diff --git a/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
new file mode 100644
index 00000000..6f170db6
--- /dev/null
+++ b/src/Managed/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
@@ -0,0 +1,137 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.IntegralTransforms.Algorithms
+{
+ using System;
+ using NumberTheory;
+ using Properties;
+
+ ///
+ /// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
+ ///
+ public partial class DiscreteFourierTransform
+ {
+ ///
+ /// Radix-2 Reorder Helper Method
+ ///
+ /// Sample type
+ /// Sample vector
+ private static void Radix2Reorder(T[] samples)
+ {
+ int j = 0;
+ for (int i = 0; i < samples.Length - 1; i++)
+ {
+ if (i < j)
+ {
+ T temp = samples[i];
+ samples[i] = samples[j];
+ samples[j] = temp;
+ }
+
+ int m = samples.Length;
+
+ do
+ {
+ m >>= 1;
+ j ^= m;
+ } while ((j & m) == 0);
+ }
+ }
+
+ ///
+ /// Radix-2 Step Helper Method
+ ///
+ /// Sample vector.
+ /// Fourier series exponent sign.
+ /// Level Group Size.
+ /// Index inside of the level.
+ private static void Radix2Step(Complex[] samples, int exponentSign, int levelSize, int k)
+ {
+ // Twiddle Factor
+ double exponent = (exponentSign * k) * Constants.Pi / levelSize;
+ Complex w = Complex.WithRealImaginary(Math.Cos(exponent), Math.Sin(exponent));
+
+ int step = levelSize << 1;
+ for (int i = k; i < samples.Length; i += step)
+ {
+ Complex ai = samples[i];
+ Complex t = w * samples[i + levelSize];
+ samples[i] = ai + t;
+ samples[i + levelSize] = ai - t;
+ }
+ }
+
+ ///
+ /// Radix-2 generic FFT for power-of-two sample vectors.
+ ///
+ /// Sample vector, where the FFT is evaluated in place.
+ /// Fourier series exponent sign.
+ ///
+ internal static void Radix2(Complex[] samples, int exponentSign)
+ {
+ if (!samples.Length.IsPowerOfTwo())
+ {
+ throw new ArgumentException(Resources.ArgumentPowerOfTwo);
+ }
+
+ Radix2Reorder(samples);
+ for (int levelSize = 1; levelSize < samples.Length; levelSize *= 2)
+ {
+ for (int k = 0; k <= levelSize - 1; k++)
+ {
+ Radix2Step(samples, exponentSign, levelSize, k);
+ }
+ }
+ }
+
+ ///
+ /// Radix-2 forward FFT for power-of-two sample vectors.
+ ///
+ /// Sample vector, where the FFT is evaluated in place.
+ /// Fourier Transform Convention Options.
+ ///
+ public void Radix2Forward(Complex[] samples, FourierOptions options)
+ {
+ Radix2(samples, SignByOptions(options));
+ ForwardScaleByOptions(options, samples);
+ }
+
+ ///
+ /// Radix-2 inverse FFT for power-of-two sample vectors.
+ ///
+ /// Sample vector, where the FFT is evaluated in place.
+ /// Fourier Transform Convention Options.
+ ///
+ public void Radix2Inverse(Complex[] samples, FourierOptions options)
+ {
+ Radix2(samples, -SignByOptions(options));
+ InverseScaleByOptions(options, samples);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Managed/IntegralTransforms/FourierOptions.cs b/src/Managed/IntegralTransforms/FourierOptions.cs
new file mode 100644
index 00000000..ef1b3c29
--- /dev/null
+++ b/src/Managed/IntegralTransforms/FourierOptions.cs
@@ -0,0 +1,73 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+//
+// Copyright (c) 2009 Math.NET
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+namespace MathNet.Numerics.IntegralTransforms
+{
+ using System;
+
+ ///
+ /// Fourier Transform Convention
+ ///
+ [Flags]
+ public enum FourierOptions
+ {
+ // FLAGS:
+
+ ///
+ /// Inverse integrand exponent (forward: positive sign; inverse: negative sign).
+ ///
+ InverseExponent = 0x01,
+
+ ///
+ /// Only scale by 1/N in the inverse direction; No scaling in forward direction.
+ ///
+ AsymmetricScaling = 0x02,
+
+ ///
+ /// Don't scale at all (neither on forward nor on inverse transformation).
+ ///
+ NoScaling = 0x04,
+
+ // USABILITY POINTERS:
+
+ ///
+ /// Universal; Symmetric scaling and common exponent (used in Maple).
+ ///
+ Default = 0,
+
+ ///
+ /// Only scale by 1/N in the inverse direction; No scaling in forward direction (used in Matlab). [= AsymmetricScaling]
+ ///
+ Matlab = AsymmetricScaling,
+
+ ///
+ /// Inverse integrand exponent; No scaling at all (used in all Numerical Recipes based implementations). [= InverseExponent | NoScaling]
+ ///
+ NumericalRecipes = InverseExponent | NoScaling
+ }
+}
diff --git a/src/Managed/Managed.csproj b/src/Managed/Managed.csproj
index 7c53c4f8..2f88b753 100644
--- a/src/Managed/Managed.csproj
+++ b/src/Managed/Managed.csproj
@@ -55,6 +55,11 @@
+
+
+
+
+
diff --git a/src/Native.UnitTests/Native.UnitTests.csproj b/src/Native.UnitTests/Native.UnitTests.csproj
index b08f8b58..ef565cd1 100644
--- a/src/Native.UnitTests/Native.UnitTests.csproj
+++ b/src/Native.UnitTests/Native.UnitTests.csproj
@@ -74,6 +74,9 @@
DistributionTests\Continuous\NormalTests.cs
+
+ IntegralTransformsTests\DftTest.cs
+
IntegrationTests\IntegrationTest.cs
diff --git a/src/Native/Native.csproj b/src/Native/Native.csproj
index 6064b589..07e467e3 100644
--- a/src/Native/Native.csproj
+++ b/src/Native/Native.csproj
@@ -71,6 +71,21 @@
Distributions\IDistribution.cs
+
+ IntegralTransforms\Algorithms\DiscreteFourierTransform.Bluestein.cs
+
+
+ IntegralTransforms\Algorithms\DiscreteFourierTransform.Naive.cs
+
+
+ IntegralTransforms\Algorithms\DiscreteFourierTransform.Options.cs
+
+
+ IntegralTransforms\Algorithms\DiscreteFourierTransform.RadixN.cs
+
+
+ IntegralTransforms\FourierOptions.cs
+
Integration\Algorithms\DoubleExponentialTransformation.cs