/// <summary> /// Verify matches naive complex. /// </summary> /// <param name="samples">Samples count.</param> /// <param name="maximumError">Maximum error.</param> /// <param name="naive">Naive transform.</param> /// <param name="fast">Fast delegate.</param> private static void VerifyMatchesNaiveComplex( Complex[] samples, double maximumError, Func<Complex[], Complex[]> naive, Action<Complex[]> fast) { var spectrumNaive = naive(samples); var spectrumFast = new Complex[samples.Length]; samples.CopyTo(spectrumFast, 0); fast(spectrumFast); AssertHelpers.AlmostEqualList(spectrumNaive, spectrumFast, maximumError); }
static void Verify( Complex[] samples, int maximumErrorDecimalPlaces, FourierOptions options, Func<Complex[], FourierOptions, Complex[]> naive, Action<Complex[], FourierOptions> fast) { var spectrumNaive = naive(samples, options); var spectrumFast = new Complex[samples.Length]; samples.CopyTo(spectrumFast, 0); fast(spectrumFast, options); AssertHelpers.AlmostEqual(spectrumNaive, spectrumFast, maximumErrorDecimalPlaces); }
/// <summary> /// Возвращает спектр сигнала, вычесленное по быстрому алгоритму фурье /// </summary> /// <param name="input">Массив значений сигнала</param> /// <returns>Массив со значениями спектра сигнала</returns> public static Complex[] FastTransform(Complex[] input) { double log = Math.Log(input.Length, 2); Complex[] x; if (log - Math.Round(log) != 0) { x = new Complex[(int) Math.Pow(2,(int)log + 1)]; input.CopyTo(x, 0); } else { x = (Complex[]) input.Clone(); } Complex[] X; int N = x.Length; if (N == 2) { X = new Complex[2]; X[0] = x[0] + x[1]; X[1] = x[0] - x[1]; } else { Complex[] x_even = new Complex[N / 2]; Complex[] x_odd = new Complex[N / 2]; for (int i = 0; i < N / 2; i++) { x_even[i] = x[2 * i]; x_odd[i] = x[2 * i + 1]; } Complex[] X_even = UnsafeFastTransform(x_even); Complex[] X_odd = UnsafeFastTransform(x_odd); X = new Complex[N]; for (int i = 0; i < N / 2; i++) { X[i] = X_even[i] + Module(i, N) * X_odd[i]; X[i + N / 2] = X_even[i] - Module(i, N) * X_odd[i]; } } return X; }
/// <summary> /// Verify matches naive complex. /// </summary> static void VerifyMatchesNaiveComplex( Complex[] samples, int maximumErrorDecimalPlaces, Func<Complex[], Complex[]> naive, Action<Complex[]> fast) { var spectrumNaive = naive(samples); var spectrumFast = new Complex[samples.Length]; samples.CopyTo(spectrumFast, 0); fast(spectrumFast); AssertHelpers.ListAlmostEqual(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); }
public static Complex[] Furie(Complex[] array) { int m = Convert.ToInt32(Math.Ceiling(Math.Log(array.Length) / Math.Log(2))); // n=2**m int n = Convert.ToInt32( Math.Pow( 2.0, m ) ); //MessageBox.Show(" n = " + n + " m = " + m); Complex[] a = new Complex[n]; array.CopyTo(a, 0); Complex u, w, t; int i, j, ip, l; int n1 = n >> 1; int k = n1; for (i = 0, j = 0; i < n - 1; i++, j = j + k) { if (i < j) { t = a[j]; a[j] = a[i]; a[i] = t; } k = n1; while (k <= j) { j = j - k; k = k >> 1; } } for (l = 1; l <= m; l++) { int ll = Convert.ToInt32( Math.Pow( 2.0, l ) ); int ll1 = ll >> 1; u = new Complex(1.0, 0.0); w = new Complex(Math.Cos(Math.PI / ll1), Math.Sin(Math.PI / ll1)); for (j = 1; j <= ll1; j++) { for (i = j - 1; i < n; i = i + ll) { ip = i + ll1; t = a[ip]*u; a[ip] = a[i] - t; a[i] = a[i] + t; } u = u*w; } } for (i = 0; i < array.Length; i++) { array[i] = a[i] / Math.Sqrt(n); } return array; }