using System.Numerics; namespace BPF { public static class danie { public static Complex[] X; public static Complex[] Y; public static Complex[] FastPFurie; } class Program { static void Main(string[] args) { danie.X = GetDan("exaX.txt"); danie.Y = GetDan("exa.txt"); FFT ff = new FFT(); danie.FastPFurie=FFT.fft(danie.X); Form1 f = new Form1(); f.ShowDialog(); Console.ReadKey(); } public static int n = 0; public static Complex[] GetDan(string fail)//получение данных из файла { n = 0; string s = ""; StreamReader r = new StreamReader(fail); s = r.ReadLine(); n = s.Split(' ').Length; Complex[] matrix = new Complex[n]; string[] l = s.Split(' '); for (int k = 0; k < n; k++) { matrix[k] = Convert.ToDouble(l[k]); } r.Close(); return matrix; } } } 

-

 public class FFT { /// Вычисление поворачивающего модуля e^(-i*2*PI*k/N) private static Complex w(int k, int N) { if (k % N == 0) return 1; double arg = -2 * Math.PI * k / N; return new Complex(Math.Cos(arg), Math.Sin(arg)); } /// Возвращает спектр сигнала /// <param name="x">Массив значений сигнала. Количество значений должно быть степенью 2</param> /// <returns>Массив со значениями спектра сигнала</returns> public static Complex[] fft(Complex[] x) { 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 = fft(x_even); Complex[] X_odd = fft(x_odd); X = new Complex[N]; for (int i = 0; i < N / 2; i++) { X[i] = X_even[i] + w(i, N) * X_odd[i]; X[i + N / 2] = X_even[i] - w(i, N) * X_odd[i]; } } return X; } /// <summary> /// Центровка массива значений полученных в fft (спектральная составляющая при нулевой частоте будет в центре массива) /// </summary> /// <param name="X">Массив значений полученный в fft</param> /// <returns></returns> public static Complex[] nfft(Complex[] X) { int N = X.Length; Complex[] X_n = new Complex[N]; for (int i = 0; i < N / 2; i++) { X_n[i] = X[N / 2 + i]; X_n[N / 2 + i] = X[i]; } return X_n; } } 

The files contain the values ​​of the ecg signal: 26.48 24.743 19.478 18.407 20.252 23.051 21.028 .... etc., these are the values ​​for Y, for X in another file, after transformations, it produces a miracle chart ...

 public Form1() { InitializeComponent(); chart1.Series[0].ChartType = SeriesChartType.Spline; chart2.Series[0].ChartType = SeriesChartType.Spline; } private void button1_Click(object sender, EventArgs e) { foreach (Complex complex in danie.FastPFurie) chart1.Series[0].Points.AddXY(complex.Real, complex.Imaginary); } 

enter image description here

    2 answers 2

    The result of the FFT is an array of complex amplitudes. To take from it the real and imaginary part is meaningless, since only the module carries useful information (from the point of view of signal analysis). Plotting should look something like this:

     for (int i=0; i < danie.FastPFurie.Length; i++) { chart1.Series[0].Points.AddXY(i, Complex.Abs(danie.FastPFurie[i])); } 
    • Already more like, thanks for the help - Valera

    For fft, uniform readings are necessary; an array of Y with a constant step X. The data is entered in the real part, the imaginary is filled with zeros.

    After conversion, you can display the amplitude of the complex numbers. For some purposes, a phase may also be needed.

    And the imaginary and the real part can not only watch everything. Few can do it ©

    For a start, it is worth practicing on clearly understandable data - for example, fill an array with a sine or a sum of several sines with different frequencies - on the amplitude graph there should be large peaks in the number of frequencies (if the frequencies fall in the range), and a bunch of small peaks.