using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnitTestSharp; using Azimuth.DenseLinearAlgebra; using Azimuth.FastFourierTransform; namespace Azimuth.UnitTests.FastFourierTransform { public class FastFourierTransformTests : TestFixture { public class BitReverseTests : TestFixture { public void x16() { var arr = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }); FFT.ReverseBitPermutation(arr, 4); var expected = new DenseVector(new Scalar[] { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, }); CheckEqual(expected, arr); } public unsafe void UnmanagedArray() { int length = 16; var buffer = stackalloc byte[DenseVector.RequiredSizeForLength(length)]; var arr = DenseVector.ConstructFromNativePointer(buffer, length); var assignmentValues = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }); arr.Assignment(assignmentValues); FFT.ReverseBitPermutation(arr, 4); var expected = new DenseVector(new Scalar[] { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15, }); CheckEqual(expected, arr); } } public class TransformTests : TestFixture { public void x10000000() { var real = new DenseVector(new Scalar[] { 1, 0, 0, 0, 0, 0, 0, 0, }); var imag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, 0, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 1, 1, 1, 1, 1, 1, 1, 1, }); var expectedImag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, 0, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x01234567() { var real = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, }); var imag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, 0, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var sqr2 = Math.Sqrt(2); var expectedReal = new DenseVector(new Scalar[] { 28, -4, -4, -4, -4, -4, -4, -4, }); var expectedImag = new DenseVector(new Scalar[] { 0, 4 * (1 + sqr2), 4, 4 * (sqr2 - 1), 0, -4*(sqr2 - 1), -4, -4 * (1 + sqr2), }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x16() { var real = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, }); var imag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }); var fft = new FFT(4); fft.Transform(ref real, ref imag); var sqr2 = Math.Sqrt(2); var expectedReal = new DenseVector(new Scalar[] { 120, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, }); var expectedImag = new DenseVector(new Scalar[] { 0, 40.218715937006785, 8 * (1 + sqr2), 11.972846101323906, 8, 5.345429103354382, 3.3137084989847576, 1.5912989390372658, 0, -1.5912989390372587, -3.313708498984756, -5.3454291033543875, -8.000000000000002, -11.972846101323908, -8 * (1 + sqr2), -40.218715937006785, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void InverseTransform() { var real = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }); var imag = new DenseVector(new Scalar[] { 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, }); var expectedReal = real.Clone(); var expectedImag = imag.Clone(); var fft = new FFT(5); fft.Transform(ref real, ref imag); //imag.Negate(); fft.Transform(ref imag, ref real); real.Scale(1 / 32.0); imag.Scale(1.0 / 32.0); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x32() { var real = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }); var imag = new DenseVector(32); var fft = new FFT(5); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 496.000000000000000, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, }); var expectedImag = new DenseVector(new Scalar[] { 0.0000000000000, 162.4507262017418, 80.4374318740136, 52.7449313430131, 38.6274169979695, 29.9338945886302, 23.9456922026478, 19.4960564094076, 16.0000000000000, 13.1308606532586, 10.6908582067088, 8.5521781752127, 6.6274169979695, 4.8535469377175, 3.1825978780745, 1.5758624537146, 0.0000000000000, -1.5758624537146, -3.1825978780745, -4.8535469377175, -6.6274169979695, -8.5521781752127, -10.6908582067088, -13.1308606532586, -16.0000000000000, -19.4960564094076, -23.9456922026478, -29.9338945886302, -38.6274169979695, -52.7449313430131, -80.4374318740136, -162.4507262017418, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x32_WithImag() { var real = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }); var imag = new DenseVector(new Scalar[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }); var fft = new FFT(5); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 496.000000000000000, -178.450726201741759, -96.437431874013569, -68.744931343013135, -54.627416997969519, -45.933894588630231, -39.945692202647827, -35.496056409407615, -32.000000000000000, -29.130860653258566, -26.690858206708779, -24.552178175212667, -22.627416997969522, -20.853546937717478, -19.182597878074528, -17.575862453714631, -16.000000000000000, -14.424137546285369, -12.817402121925474, -11.146453062282522, -9.372583002030478, -7.447821824787334, -5.309141793291220, -2.869139346741435, 0.000000000000000, 3.496056409407618, 7.945692202647823, 13.933894588630228, 22.627416997969522, 36.744931343013128, 64.437431874013569, 146.450726201741759, }); var expectedImag = new DenseVector(new Scalar[] { 496.000000000000000, 146.450726201741759, 64.437431874013569, 36.744931343013128, 22.627416997969522, 13.933894588630228, 7.945692202647825, 3.496056409407618, 0.000000000000000, -2.869139346741433, -5.309141793291220, -7.447821824787334, -9.372583002030478, -11.146453062282523, -12.817402121925472, -14.424137546285369, -16.000000000000000, -17.575862453714631, -19.182597878074525, -20.853546937717478, -22.627416997969522, -24.552178175212667, -26.690858206708782, -29.130860653258566, -32.000000000000000, -35.496056409407615, -39.945692202647827, -45.933894588630231, -54.627416997969519, -68.744931343013135, -96.437431874013569, -178.450726201741759, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x1() { var real = new DenseVector(new Scalar[] { 2, }); var imag = new DenseVector(new Scalar[] { -3, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 2 }); var expectedImag = new DenseVector(new Scalar[] { -3 }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x1_Inverse() { var real = new DenseVector(new Scalar[] { 2, }); var imag = new DenseVector(new Scalar[] { -3, }); var fft = new FFT(3); fft.InverseTransform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 2 }); var expectedImag = new DenseVector(new Scalar[] { -3 }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x2() { var real = new DenseVector(new Scalar[] { 2, -3, }); var imag = new DenseVector(new Scalar[] { 3, 4, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { -1, 5, }); var expectedImag = new DenseVector(new Scalar[] { 7, -1, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x2_Inverse() { var real = new DenseVector(new Scalar[] { 2, -3, }); var imag = new DenseVector(new Scalar[] { 3, 4, }); var fft = new FFT(3); fft.InverseTransform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { -1/2.0, 5/2.0, }); var expectedImag = new DenseVector(new Scalar[] { 7/2.0, -1/2.0, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x3() { var real = new DenseVector(new Scalar[] { 2, -3, 1, }); var imag = new DenseVector(new Scalar[] { 3, 4, 5, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 0, 2.13397459621556, 3.86602540378444, }); var expectedImag = new DenseVector(new Scalar[] { 12, 1.96410161513775, -4.96410161513775, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x3_Inverse() { var real = new DenseVector(new Scalar[] { 2, -3, 1, }); var imag = new DenseVector(new Scalar[] { 3, 4, 5, }); var fft = new FFT(3); fft.InverseTransform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 0, 1.288675134594813, 0.711324865405187, }); var expectedImag = new DenseVector(new Scalar[] { 4, -1.654700538379252, .654700538379251 }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x4() { var real = new DenseVector(new Scalar[] { 2, -3, 1, 2, }); var imag = new DenseVector(new Scalar[] { 3, 4, 5, -1, }); var fft = new FFT(3); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 2, 6, 4, -4, }); var expectedImag = new DenseVector(new Scalar[] { 11, 3, 5, -7, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x4_Inverse() { var real = new DenseVector(new Scalar[] { 2, -3, 1, 2, }); var imag = new DenseVector(new Scalar[] { 3, 4, 5, -1, }); var fft = new FFT(3); fft.InverseTransform(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 0.5, -1, 1, 1.5, }); var expectedImag = new DenseVector(new Scalar[] { 2.75, -1.75, 1.25, .75, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x64() { var real = new DenseVector(64); var imag = new DenseVector(64); real.Flush(1); var fft = new FFT(7); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(64); var expectedImag = new DenseVector(64); expectedReal[0] = 64; CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } public void x128() { var real = new DenseVector(128); var imag = new DenseVector(128); real.Flush(1); var fft = new FFT(7); fft.Transform(ref real, ref imag); var expectedReal = new DenseVector(128); var expectedImag = new DenseVector(128); expectedReal[0] = 128; CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } } public class ChirpZTests : TestFixture { public void x1000000() { var real = new DenseVector(new Scalar[] { 1, 0, 0, 0, 0, 0, 0, }); var imag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, }); var fft = new FFT(4); fft.ChirpZ(ref real, ref imag); var expectedReal = new DenseVector(new Scalar[] { 1, 1, 1, 1, 1, 1, 1, }); var expectedImag = new DenseVector(new Scalar[] { 0, 0, 0, 0, 0, 0, 0, }); CheckEqual(expectedReal, real); CheckEqual(expectedImag, imag); } } } }