1、DFT函数类
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DFT_FFTApp.Utils
{
public class DFT
{
/// <summary>
/// DFT
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static List<List<double>> DFTNative(List<double> data)
{
int N = data.Count;
List<List<double>> xks = new List<List<double>>();
for (int k = 0; k < N; k++)
{
List<double> xk = DFTPoint(k, data);
xks.Add(xk);
}
GC.Collect();
return xks;
}
/// <summary>
/// 单点DFT
/// </summary>
/// <param name="k"></param>
/// <param name="data"></param>
/// <returns></returns>
public static List<double> DFTPoint(int k, List<double> data)
{
int N = data.Count;
double real = 0;
double image = 0;
for (int n = 0; n < N; n++)
{
real += data[n] * Math.Cos(2 * Math.PI * (k * n) / N);
image -= data[n] * Math.Sin(2 * Math.PI * (k * n) / N);
}
List<double> res = new List<double>() { real, image };
return res;
}
/// <summary>
/// 频域求模
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static List<double> GetMod(List<List<double>> data)
{
List<double> res= new List<double>();
foreach(var x in data)
{
res.Add(Math.Sqrt(x[0] * x[0] + x[1] * x[1]));
}
return res;
}
/// <summary>
/// 频域求相位
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static List<double> GetPhase(List<List<double>> data)
{
List<double> res = new List<double>();
foreach (var x in data)
{
double phase = 0;
if (x[0] == 0)
{
phase = 90;
}
else
{
phase = Math.Atan2(x[1], x[0]);
}
res.Add(phase);
}
return res;
}
}
}
2、应用
csharp
private void DFTApp()
{
List<double> list = GetCaseData(128);
List<List<double>> Xk = DFT.DFTNative(list);
List<double> res = DFT.GetMod(Xk);
foreach (double item in res)
{
Console.WriteLine(item);
}
easyChartX1.Plot(res, 0, 1);
}
/// <summary>
/// 获取时域数据
/// </summary>
/// <param name="points"></param>
/// <returns></returns>
private List<double> GetCaseData(int points)
{
List<double> data = new List<double>();
double w = 2*Math.PI / points;
for(int i = 0; i < points;i++)
{
double d=Math.Sin(w * i);
//Console.WriteLine($"i={i},d={d.ToString("G2")}");
data.Add(d);
}
return data;
}