00001 using System;
00002 using System.Diagnostics;
00003 using System.Reflection;
00004
00005 namespace FFT.Test {
00006 using FFT;
00007
00008
00009
00010
00011 public class ComplexTest : UnitTest {
00012
00013 public override void Test(){
00014 AssertEq(new Complex(1,2).Equals(new Complex(1,2)),
00015 true,
00016 "Equality");
00017
00018 AssertEq(new Complex(1,2.000001).Equals(new Complex(1,2)),
00019 false,
00020 "Inequality");
00021
00022 AssertEq(new Complex(1,1),
00023 new Complex(1,1),
00024 "Standard constructor");
00025
00026 AssertEq(Complex.FromPolar(2,Math.PI/3),
00027 new Complex(2*Math.Cos(Math.PI/3),2*Math.Sin(Math.PI/3)),
00028 "Polar constructor");
00029
00030 AssertEq(1,
00031 new Complex(1,0),
00032 "Implicit cast from int");
00033
00034 AssertEq(1.0,
00035 new Complex(1,0),
00036 "Implicit cast from double");
00037
00038 AssertEq(new Complex(1,1).Re,
00039 1.0,
00040 "Real part");
00041
00042 AssertEq(new Complex(1,1).Im,
00043 1.0,
00044 "Imaginary part");
00045
00046 AssertEq(new Complex(3,4).Modulus,
00047 5.0,
00048 "Modulus");
00049
00050 AssertEq(new Complex(1,1).Argument,
00051 Math.PI/4.0,
00052 "Argument");
00053
00054 AssertEq(new Complex(1,1) + new Complex(2,-2),
00055 new Complex(3,-1),
00056 "Addition");
00057
00058 AssertEq(new Complex(3,-1) - new Complex(-1,-2),
00059 new Complex(4,1),
00060 "Subtraction");
00061
00062 AssertEq(new Complex(1,1) * new Complex(2,-1),
00063 new Complex(3,1),
00064 "Multiplication");
00065
00066 AssertEq(new Complex(2,-2) / new Complex(1,1),
00067 new Complex(0,-2),
00068 "Division");
00069
00070 }
00071 }
00072
00073
00074
00075
00076 public class UtilsTest : UnitTest
00077 {
00078 public override void Test()
00079 {
00080 AssertEq(Utils.copy(new int[]{1,2,3}, new int[]{4,5,6,7}),
00081 new int[] {1,2,3,7},
00082 "(1) copy");
00083
00084 AssertEq(Utils.copy(new int[]{1,2,3,4}, new int[]{4,5,6}),
00085 new int[] {1,2,3},
00086 "(2) copy");
00087
00088 int[] dst = {1,2,3};
00089 AssertEq(Utils.copy(new int[] {0,0,0},dst) == dst,
00090 true,
00091 "(3) copy");
00092
00093 AssertEq(Utils.dist(new Complex[] {1,2,3}, new Complex[] {2,1,1}),
00094 Math.Sqrt(6),
00095 "(1) dist");
00096
00097 AssertEq(Utils.dist(new Complex[] {1,2,3}, new Complex[] {2,1}),
00098 Math.Sqrt(2),
00099 "(2) dist");
00100
00101 AssertEq(Utils.dist(new Complex[] {1,2}, new Complex[] {2,1,1}),
00102 Math.Sqrt(2),
00103 "(3) dist");
00104
00105 AssertEq(Utils.Log2(-1),0,"(1) Log2");
00106 AssertEq(Utils.Log2(0),0,"(2) Log2");
00107 AssertEq(Utils.Log2(1),0,"(3) Log2");
00108 AssertEq(Utils.Log2(2),1,"(4) Log2");
00109 AssertEq(Utils.Log2(3),2,"(5) Log2");
00110 AssertEq(Utils.Log2(4),2,"(6) Log2");
00111 AssertEq(Utils.Log2(5),3,"(7) Log2");
00112
00113 AssertEq(Utils.IsPowerOf2(1),true,"(1) IsPowerOf");
00114 AssertEq(Utils.IsPowerOf2(2),true,"(2) IsPowerOf");
00115 AssertEq(Utils.IsPowerOf2(3),false,"(3) IsPowerOf");
00116
00117
00118 AssertEq(Utils.Exp2(0),1,"(1) Exp2");
00119 AssertEq(Utils.Exp2(1),2,"(2) Exp2");
00120 AssertEq(Utils.Exp2(2),4,"(3) Exp2");
00121 }
00122 }
00123
00124
00125
00126
00127 public class DirectConvolutionTest : UnitTest
00128 {
00129 DirectConvolution conv;
00130 public DirectConvolutionTest() {
00131 conv = new DirectConvolution();
00132 }
00133
00134 public override void Test()
00135 {
00136 AssertEq(conv.Convolution(new Complex[]{1,2,3}, new Complex[]{1,2}),
00137 new Complex[]{1,4,7,6},
00138 "Convolution");
00139
00140 AssertEq(conv.ToString(),
00141 "Direct",
00142 "ToString");
00143 }
00144 }
00145
00146
00147
00148
00149 public class PolynomialConvolutionTest : UnitTest
00150 {
00151 PolynomialConvolution conv;
00152 public PolynomialConvolutionTest() {
00153 conv = new PolynomialConvolution();
00154 }
00155
00156 public override void Test()
00157 {
00158
00159 AssertEq(conv.GenerateDomain(3),
00160 new Complex[3] {
00161 Math.Cos(Math.PI/8),
00162 Math.Cos(3*Math.PI/8),
00163 Math.Cos(5*Math.PI/8)
00164 },
00165 "GenerateDomain");
00166
00167 AssertEq(conv.Interpolate(new Complex[3]{-1,0,1}, new Complex[3]{1,3,9}),
00168 new Complex[3]{3,4,2},
00169 "Interpolate");
00170
00171 AssertEq(conv.Evaluate(new Complex[3]{3,4,2}, new Complex[3]{-1,0,1}),
00172 new Complex[3]{1,3,9},
00173 "Evaluate");
00174
00175 AssertEq(conv.PointwiseMultiply(new Complex[3]{1,3,2}, new Complex[3]{4,2,5}),
00176 new Complex[3]{4,6,10},
00177 "PointwiseMultiply");
00178
00179 AssertNearEq(conv.Convolution(new Complex[]{1,2,3}, new Complex[]{1,2}),
00180 new Complex[]{1,4,7,6},
00181 "Convolution");
00182
00183 AssertEq(conv.ToString(),
00184 "Polynomial",
00185 "ToString");
00186
00187 }
00188 }
00189
00190
00191
00192
00193 public class DFTConvolutionTest : UnitTest
00194 {
00195 protected DFTConvolution conv = new DFTConvolution(new MockDFT());
00196
00197 public override void Test()
00198 {
00199 AssertEq(conv.ToString(),
00200 "DFT[Mock]",
00201 "ToString");
00202
00203 AssertNearEq(conv.Convolution(new Complex[]{1,1}, new Complex[]{1}),
00204 new Complex[]{1,1},
00205 "Convolution");
00206
00207 Complex[] a = new Complex[10];
00208 Complex[] b = new Complex[12];
00209 int n = Utils.Exp2(Utils.Log2(a.Length+b.Length-1));
00210 conv.Normalize(ref a, ref b);
00211 AssertEq(a.Length,n,"Normalize (left)");
00212 AssertEq(b.Length,n,"Normalize (right)");
00213
00214 AssertEq(conv.PointwiseMultiply(new Complex[3]{1,3,2}, new Complex[3]{4,2,5}),
00215 new Complex[3]{4,6,10},
00216 "PointwiseMultiply");
00217
00218 }
00219 }
00220
00221
00222
00223
00224 public class MockDFT : IDFT
00225 {
00226 private PolynomialConvolution c = new PolynomialConvolution();
00227 public Complex[] DFT(Complex[] a, int sgn)
00228 {
00229 int n = a.Length;
00230 Complex[] x = new Complex[n];
00231 for (int i = 0; i < n; i++) {
00232 x[i] = Complex.FromPolar(1,sgn*2*i*Math.PI/n);
00233 }
00234
00235 Complex[] y = c.Evaluate(a,x);
00236
00237 if (sgn == -1) {
00238 for (int i = 0; i < n; i++) {
00239 y[i] /= n;
00240 }
00241 }
00242
00243 return y;
00244 }
00245
00246 public Complex[] DFT(Complex[] a)
00247 {
00248 return DFT(a,1);
00249 }
00250
00251 public Complex[] InverseDFT(Complex[] y)
00252 {
00253 return DFT(y,-1);
00254 }
00255
00256 public override string ToString()
00257 {
00258 return "Mock";
00259 }
00260 }
00261
00262
00263
00264
00265 public class RecursiveFFTTest : UnitTest
00266 {
00267 protected RecursiveFFT dft = new RecursiveFFT();
00268 protected MockDFT mft = new MockDFT();
00269
00270 public override void Test()
00271 {
00272 AssertNearEq(dft.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00273 mft.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00274 "DFT");
00275 AssertNearEq(dft.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00276 mft.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00277 "InverseDFT");
00278
00279 AssertEq(dft.ToString(),
00280 "Recursive",
00281 "ToString");
00282 }
00283 }
00284
00285
00286
00287
00288 public class IterativeFFTTest : UnitTest
00289 {
00290 protected IterativeFFT dft = new IterativeFFT();
00291 protected MockDFT mft = new MockDFT();
00292
00293 public override void Test()
00294 {
00295 AssertNearEq(dft.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00296 mft.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00297 "DFT");
00298 AssertNearEq(dft.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00299 mft.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00300 "InverseDFT");
00301
00302 AssertEq(dft.ToString(),
00303 "Iterative",
00304 "ToString");
00305
00306 AssertEq(dft.BitReverseCopy(new Complex[] {0,1,2,3,4,5,6,7}),
00307 new Complex[] {0,4,2,6,1,5,3,7},
00308 "BitReverseCopy");
00309 }
00310 }
00311
00312
00313
00314
00315 public class ParallelFFTTest : UnitTest
00316 {
00317 protected ParallelFFT[] dft = {
00318 new ParallelFFT(0),
00319 new ParallelFFT(1),
00320 new ParallelFFT(2),
00321 new ParallelFFT(3),
00322 new ParallelFFT(4) };
00323 protected MockDFT mft = new MockDFT();
00324
00325 public override void Test()
00326 {
00327 foreach (ParallelFFT d in dft) {
00328 AssertNearEq(d.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00329 mft.DFT(new Complex[]{0,1,2,3,4,5,6,7}),
00330 d + ": DFT");
00331 AssertNearEq(d.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00332 mft.InverseDFT(new Complex[]{0,1,2,3,4,5,6,7}),
00333 d + ": InverseDFT");
00334 AssertEq(d.BitReverseCopy(new Complex[] {0,1,2,3,4,5,6,7}),
00335 new Complex[] {0,4,2,6,1,5,3,7},
00336 d + ": BitReverseCopy");
00337 }
00338 }
00339 }
00340
00341 }