klhztrader/KLHZ.Trader.Core.Math/Declisions/Utils/FFT.cs

149 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<float>();
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<float>();
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<double, double, double, double,bool> comparer)
{
var x = new List<double>();
var xIndexes = new List<int>();
var y = new List<double>();
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);
}
}
}