using MathNet.Numerics; using MathNet.Numerics.IntegralTransforms; namespace KLHZ.Trader.Core.Math.Declisions.Utils { public static class FFT { public static void Test() { var da = new List(); for (int i = 0; i < 1000; i++) { da.Add((float)System.Math.Sin(0.01 * i) + (float)System.Math.Cos(0.01 * i)); } var start = da.ToArray(); var arrv = da.Select(d => new Complex32(d, 0)).ToArray(); Fourier.Forward(arrv); Fourier.Inverse(arrv); var res = arrv.Select(a => a.Real).ToArray(); for (int i = 0; i < 1000; i++) { var d = res[i] - start[i]; } } public static void А() { var da = new List(); for (int i = 0; i < 1000; i++) { da.Add((float)System.Math.Sin(0.01 * i) + (float)System.Math.Cos(0.01 * i)); } var start = da.ToArray(); var arrv = da.Select(d => new Complex32(d, 0)).ToArray(); Fourier.Forward(arrv); Fourier.Inverse(arrv); var res = arrv.Select(a => a.Real).ToArray(); for (int i = 0; i < 1000; i++) { var d = res[i] - start[i]; } } public static TimeSpan CaclHarmonycPeriod(TimeSpan signalLength, int signalLengthItems, int harmonyNumber) { var fdiscretisation = signalLengthItems / signalLength.TotalSeconds; var fharm = harmonyNumber * fdiscretisation / signalLengthItems; return TimeSpan.FromSeconds(1 / fharm); } public static double CalcCurrentPhase(Complex32[] spectr, int harmonyNumber) { var item = spectr[harmonyNumber]; return System.Math.Atan(item.Imaginary / item.Real); } public static (double min, double max) CalcPhaseRangeFoxMax(double aSin, double aCos, double initPhase, double level) { return CalcPhaseRange(aSin, aCos,initPhase, level, CheckMaxValue); } public static (double min, double max) CalcPhaseRangeFoxMin(double aSin, double aCos, double initPhase, double level) { return CalcPhaseRange(aSin, aCos, initPhase, level, CheckMinValue); } internal static (double min, double max) CalcPhaseRange(double aSin, double aCos, double initPhase, double level, Func comparer) { var x = new List(); var xIndexes = new List(); var y = new List(); var max = double.MinValue; var min = double.MaxValue; var _2pi = 2 * System.Math.PI; for (double i = 0; i <= 10 * System.Math.PI; i += 0.01) { var df = (((i) / _2pi) % 1) * _2pi; var val = aSin * System.Math.Sin(i + initPhase) + aCos * System.Math.Cos(i + initPhase); if (val > max) { max = val; } if (val < min) { min = val; } x.Add(df); y.Add(val); } int start = -2; int prevI = -2; int end = -2; var drange = -2; var minPhaseTmp = 0d; var maxPhaseTmp = 0d; var minPhase = 0d; var maxPhase = 0d; for (int i = 0; i < y.Count; i++) { if (comparer(y[i],min,max,level)) { if (start < 0) { minPhaseTmp = x[i]; start = i; } } else if (start >= 0 && i - prevI == 1) { end = prevI; maxPhaseTmp = x[end]; var drangeTmp = end - start; if (drangeTmp > drange) { drange = drangeTmp; minPhase = minPhaseTmp; maxPhase = maxPhaseTmp; } start = -2; } prevI = i; } return (minPhase, maxPhase); } internal static bool CheckMaxValue(double val, double min, double max, double relativeValue) { return (val > (1 - relativeValue) * max); } internal static bool CheckMinValue(double val, double min, double max, double relativeValue) { return (val < (1 - relativeValue) * min); } } }