// Генерация вектора фич private Vector GenFeature() { ComplexVector cV = Furie.fft(points); double k, cP1, cP2; Complex kR; if (!_isScale) { cP1 = cV[0].Magnitude; cP2 = cV[cV.N - 1].Magnitude; k = Math.Sqrt(cP1 * cP1 + cP2 * cP2); cV /= k; } if (!_isRot) { cP1 = cV[0].Phase; cP2 = cV[cV.N - 1].Phase; kR = Complex.Exp(new Complex(0, 1) * (cP2 - cP1) / 2.0); cV *= kR; } if (!_isMove) { cV[0] = 0; } cV = cV.CutAndZero(n); Vector modules = cV.MagnitudeToVector(); Vector phases = cV.PhaseToVector(); return(phases);//Vector.Concatinate(new Vector[]{modules, phases}); }
private void button3_Click(object sender, EventArgs e) // Обратное преобразование Фурье 2**M { k1 = Convert.ToInt32(textBox4.Text); k2 = Convert.ToInt32(textBox5.Text); if (Form1.zComplex[k1] == null) { MessageBox.Show("zComplex[0] == NULL"); return; } int m = 1; int n = Form1.zComplex[k1].width; int nn = 2; for (int i = 1; ; i++) { nn = nn * 2; if (nn > n) { n = nn / 2; m = i; break; } } MessageBox.Show("n = " + Convert.ToString(n) + " m = " + Convert.ToString(m)); ZComplexDescriptor rez = new ZComplexDescriptor(n, n); rez = Furie.InverseFourierTransform(Form1.zComplex[k1], m); Form1.zComplex[k2] = rez; Complex_pictureBox(k2); //OnFurieM(k1, k2); Close(); }
/// <summary> /// Быстрое кепстральное преобразование /// </summary> /// <param name="signal">Сигнал</param> /// <returns></returns> public static Vector FKT(ComplexVector signal) { ComplexVector spectr = Furie.fft(signal); Vector Aspectr = MathFunc.ln(spectr.MagnitudeToVector().TransformVector(x => x * x)); return(Furie.fft(Aspectr).RealToVector() / Aspectr.N); }
/// <summary> /// Передискретизация сигнала /// (повышение частоты дискретизации в целое число раз) /// </summary> /// <param name="inp">Входной вектор</param> /// <param name="fd">Старая частота дискретизации</param> /// <param name="newfd">Новая частота дикретизации</param> /// <returns>Вектор тойже длительности, что и входной, /// но с более высокой частотой дискретизации</returns> public static Vector Perediscr(Vector inp, int fd, int newfd) { int k = newfd / fd; ComplexVector inputSpectr = Furie.fft(inp); int len = inp.N * (k - 1), lenFull = inp.N * k; int i = 0; ComplexVector cV = new ComplexVector(lenFull); int end = inp.N / 2; for (; i < end; i++) { cV[i] = inputSpectr[i]; } end = lenFull - inp.N / 2; for (; i < end; i++) { cV[i] = new System.Numerics.Complex(0, 0); } for (int j = inp.N / 2; i < lenFull; i++) { cV[i] = inputSpectr[j]; } return(Furie.ifft(cV).RealToVector()); }
/// <summary> /// Относительная ошибка по энергии спектра /// </summary> /// <param name="real">Реальный</param> /// <param name="approcs">Аппроксимированный</param> /// <returns></returns> public static double PowerError(Vector real, Vector approcs) { double realSpE = Functions.Integral(Furie.DPF(real).MagnitudeToVector()).DataInVector[real.N - 1], appSpE = Functions.Integral(Furie.DPF(approcs).MagnitudeToVector()).DataInVector[real.N - 1]; return((realSpE > appSpE) ? (realSpE / appSpE) * (realSpE / appSpE) : (appSpE / realSpE) * (appSpE / realSpE)); }
/// <summary> /// Возвращает суммарные амплитуды в формантах /// </summary> /// <param name="inp">Входной вектор</param> /// <returns>Вектор амплитуд</returns> public Vector GetAmplFreq(Vector inp) { Furie fft = new Furie(inp.N); Vector vect = fft.GetSpectr(inp, WindowForFFT.BlackmanWindow); GetIntervalData(vect.N * 2); return(iD.GetVect(Functions.Summ, vect)); }
/// <summary> /// Реализация простого фильтра /// </summary> /// <param name="st">Вектор сигнала</param> /// <param name="kw">АЧХ</param> /// <returns>Фильтрованный сигнал</returns> public static Vector Filter(Vector st, Vector kw) { Vector newSt = st.CutAndZero(Functions.NextPow2(st.N)); Vector newKw = kw.CutAndZero(newSt.N / 2); newKw = newKw.AddSimmetr(); //newKw.Visual(); ComplexVector Sw = Furie.fft(newSt); Sw = Sw * newKw; newSt = Furie.ifft(Sw).RealToVector(); return(newSt.CutAndZero(st.N));//newSt.N; }
/// <summary> /// Выделение первой гармоники по столбцам /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button18_Click(object sender, EventArgs e) { k1 = Convert.ToInt32(textBox4.Text); k2 = Convert.ToInt32(textBox5.Text); if (Form1.zArrayDescriptor[k1] == null) { MessageBox.Show("Furie 256 zArrayDescriptor[" + k1 + "] == NULL"); return; } int nx = Form1.zArrayDescriptor[k1].width; //int ny = Form1.zArrayDescriptor[0].height; int m = 8; int ny = 256; ZArrayDescriptor rez = new ZArrayDescriptor(nx, ny); // Рабочий массив Complex[] resultArray1 = new Complex[ny]; Complex[] resultArray2 = new Complex[ny]; for (int j = 0; j < ny; j++) { resultArray2[j] = new Complex(0.0, 0.0); } for (int i = 0; i < nx; i++) // Фаза == 0 { for (int j = 0; j < ny; j++) { resultArray1[j] = new Complex(Form1.zArrayDescriptor[k1].array[i, j], 0.0); } resultArray1 = Furie.GetFourierTransform(resultArray1, m); resultArray2[1] = resultArray1[1]; resultArray2[ny - 1] = resultArray1[ny - 1]; resultArray1 = Furie.GetInverseFourierTransform(resultArray2, m); for (int j = 0; j < ny; j++) { rez.array[i, j] = resultArray1[j].Real; } //resultArray1[j].Magnitude; } Form1.zArrayDescriptor[k2] = rez; VisualRegImage(k2); Close(); }
/// <summary> /// Порождения вейвлетов /// </summary> /// <param name="wavelet">Порождающая функция</param> /// <param name="scales">Масштабы</param> /// <param name="n">Размерность входа</param> public PerentWavelet(Func <double, Vector> wavelet, Vector scales, int n) { fur = new Furie(n); scals = scales.Copy(); waveletSpectrs = new ComplexVector[scales.N]; Vector wavReal; std = new Vector(scales.N); for (int i = 0; i < waveletSpectrs.Length; i++) { wavReal = wavelet(scales[i]).Revers(); wavReal -= Statistic.ExpectedValue(wavReal); //wavReal *= scales[i]; waveletSpectrs[i] = fur.FFT(wavReal); waveletSpectrs[i] /= wavReal.N; std[i] = Statistic.Std(wavReal); } }
/// <summary> /// Сигнал сопряженный по Гильберту /// </summary> /// <param name="st">Исходный сигнал</param> public static Vector ConjugateToTheHilbert(Vector st) { ComplexVector cv = Furie.DPF(st); Complex j = new Complex(0, 1); int n1 = st.N / 2, n2 = st.N; //cv.RealToVector().Visual(); for (int i = 0; i < n1; i++) { cv.DataInVector[i] = cv.DataInVector[i] * (-j); } for (int i = n1; i < n2; i++) { cv.DataInVector[i] = cv.DataInVector[i] * j; } cv = Furie.ODPF(cv); return(cv.RealToVector()); }
/// <summary> /// Реализация колебательного контура /// </summary> /// <param name="st">Вектор сигнала</param> /// <param name="Q">Добротность</param> /// <param name="f0">Резонансная частота</param> /// <param name="fd">Частота дискретизации</param> /// <returns>Фильтрованный сигнал</returns> public static Vector FilterKontur(Vector st, double Q, double f0, int fd) { Vector newSt = st.CutAndZero(Functions.NextPow2(st.N)); Complex j = new Complex(0, 1); ComplexVector Sw = Furie.fft(st); ComplexVector kw = new ComplexVector(Sw.N); Vector f = Signal.Frequency(kw.N, fd); for (int i = 1; i < f.N / 2; i++) { kw[i] = 1.0 / (1 + j * Q * (f[i] / f0 - f0 / f[i])); } for (int i = f.N / 2; i < f.N - 1; i++) { kw[i] = 1.0 / (1 + j * Q * (f[i] / (2 * f0) - (2 * f0) / f[i])); } Sw = Sw * kw; newSt = Furie.ifft(Sw).RealToVector(); return(newSt.CutAndZero(st.N)); }
/// <summary> /// Сигнал сопряженный по Гильберту /// </summary> /// <param name="st">Исходный сигнал</param> public static Vector ConjugateToTheHilbert(Vector st) { Vector stNew = st.CutAndZero(Functions.NextPow2(st.N)); ComplexVector cv = Furie.fft(stNew); Complex j = new Complex(0, 1); int n1 = stNew.N / 2, n2 = stNew.N; for (int i = 0; i < n1; i++) { cv.DataInVector[i] = cv.DataInVector[i] * (-j); } for (int i = n1; i < n2; i++) { cv.DataInVector[i] = cv.DataInVector[i] * j; } cv = Furie.ifft(cv).CutAndZero(st.N); return(cv.RealToVector()); }
/// <summary> /// Быстрое преобразование PSI для четырех сдвигов /// </summary> /// <param name="zArrayPicture"></param> /// <param name="progressBar1"></param> /// <param name="fzz"></param> /// <param name="amplit"></param> /// <returns></returns> public static ZArrayDescriptor ATAN_quick(ZArrayDescriptor[] zArrayDescriptor, ProgressBar progressBar1, double[] fzz, double xmax, double lambda, double d, double amplit) { // 8, 9, 10, 11 -> Complex[1] int w1 = zArrayDescriptor[8].width; int h1 = zArrayDescriptor[8].height; System.Diagnostics.Stopwatch sw = new Stopwatch(); sw.Start(); //MessageBox.Show("width= " + w1 + "height= " + h1); ZComplexDescriptor zComplex_rab = new ZComplexDescriptor(w1, h1); /* * double i_sdv1; //PSI * double i_sdv2; * double i_sdv3; * double i_sdv4; * //double[] i_s = new double[w1]; // Числитель * //double[] i_c = new double[w1]; // Знаменатель * * double k_sin1 = Math.Sin(fzz[0]); * double k_sin2 = Math.Sin(fzz[1]); * double k_sin3 = Math.Sin(fzz[2]); * double k_sin4 = Math.Sin(fzz[3]); * * double k_cos1 = Math.Cos(fzz[0]); * double k_cos2 = Math.Cos(fzz[1]); * double k_cos3 = Math.Cos(fzz[2]); * double k_cos4 = Math.Cos(fzz[3]); * * //double znmt = Math.Abs((k_sin2 - k_sin4) * k_cos1 + (k_sin3 - k_sin1) * k_cos2 + (k_sin4 - k_sin2) * k_cos3 + (k_sin1 - k_sin3) * k_cos4); * double znmt = Math.Abs((k_cos2 - k_cos4) * k_sin1 + (k_cos3 - k_cos1) * k_sin2 + (k_cos4 - k_cos2) * k_sin3 + (k_cos1 - k_cos3) * k_sin4); * znmt = znmt * (2 * amplit); * * progressBar1.Visible = true; * progressBar1.Minimum = 1; * progressBar1.Maximum = w1 - 1; * progressBar1.Value = 1; * progressBar1.Step = 1; * * * * * for (int j = 0; j < h1; j++) * { * for (int i = 0; i < w1; i++) * { * i_sdv1 = zArrayDescriptor[8].array[i, j]; * i_sdv2 = zArrayDescriptor[9].array[i, j]; * i_sdv3 = zArrayDescriptor[10].array[i, j]; * i_sdv4 = zArrayDescriptor[11].array[i, j]; * * double i1 = i_sdv2 - i_sdv4; * double i2 = i_sdv3 - i_sdv1; * double i3 = i_sdv4 - i_sdv2; * double i4 = i_sdv1 - i_sdv3; * * double i_s = i1 * k_sin1 + i2 * k_sin2 + i3 * k_sin3 + i4 * k_sin4; * double i_c = i1 * k_cos1 + i2 * k_sin2 + i3 * k_sin3 + i4 * k_sin4; * * double faza = Math.Atan2(i_c, i_s); // Фаза * //double faza = Math.Atan2(i_s, i_c); * double am = Math.Sqrt(i_s * i_s + i_c * i_c) / znmt; // Амплитуда * * zComplex_rab.array[i, j] = Complex.FromPolarCoordinates(am, faza); * * } * progressBar1.PerformStep(); * } * progressBar1.Value = 1; */ zComplex_rab = ATAN_PSI.ATAN_891011(zArrayDescriptor, progressBar1, fzz, amplit); // PSI //zComplex[1] = zComplex_rab; ZArrayDescriptor zArrayPicture = new ZArrayDescriptor(w1, h1); zComplex_rab = FurieN.FrenelTransformN(zComplex_rab, lambda, d, xmax); // Преобразование Френеля с четным количеством точек for (int i = 0; i < w1; i++) // Амплитуду в главное окно { for (int j = 0; j < h1; j++) { zArrayPicture.array[i, j] = zComplex_rab.array[i, j].Magnitude; } } zArrayPicture = Furie.Invers_Double(zArrayPicture); sw.Stop(); TimeSpan ts = sw.Elapsed; MessageBox.Show("PSI+Frenel Время Минут: " + ts.Minutes + " Время сек: " + ts.Seconds + " Время миллисек: " + ts.Milliseconds); //MessageBox.Show(" Lambda= " + lambda + " d= " + d + " dx= " + xmax); return(zArrayPicture); }
/// <summary> /// Оптимальный (согласованный) фильтр /// </summary> /// <param name="signal"></param> /// <param name="n"></param> public OptimalFilter(Vector signal, int n) { fur = new Furie(n); corFunc = fur.FFT(signal.Revers().CutAndZero(n)) / fur._n; }