当前位置: 首页 > news >正文

C#实现快速傅里叶变换(FFT)

1、FFT类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading.Tasks;namespace DFT_FFTApp.Utils
{public class FFT{/// <summary>/// FFT/// </summary>/// <param name="xL"></param>/// <returns></returns>public static double[] ButterflyFFT(List<double> xL){int len = xL.Count;if (len == 0){return null;}double[] data_r = new double[len];double[] data_i = new double[len];for (int i = 0; i < len; i++){data_r[i] = xL[i];}double[] fft_r = new double[data_r.Length];double[] fft_i = new double[data_r.Length];double[] result = new double[data_r.Length];BF_FFT(ref data_r, ref data_i, ref fft_r, ref fft_i);GetMod(ref fft_r, ref fft_i, ref result);return result;}/// <summary>/// FFT算法/// </summary>/// <param name="data_r"></param>/// <param name="data_i"></param>/// <param name="result_r"></param>/// <param name="result_i"></param>public static void BF_FFT(ref double[] data_r, ref double[] data_i, ref double[] result_r, ref double[] result_i){if (data_r.Length == 0 || data_i.Length == 0 || data_r.Length != data_i.Length)return;int len = data_r.Length;double[] X_r = new double[len];double[] X_i = new double[len];for (int i = 0; i < len; i++)//将源数据复制副本,避免影响源数据的安全性{X_r[i] = data_r[i];X_i[i] = data_i[i];}DataSort(ref X_r, ref X_i);//位置重排double WN_r, WN_i;//旋转因子int M = (int)(Math.Log(len) / Math.Log(2));//蝶形图级数for (int l = 0; l < M; l++){int space = (int)Math.Pow(2, l);int num = space;//旋转因子个数double temp1_r, temp1_i, temp2_r, temp2_i;for (int i = 0; i < num; i++){int p = (int)Math.Pow(2, M - 1 - l);//同一旋转因子有p个蝶WN_r = Math.Cos(2 * Math.PI / len * p * i);WN_i = -Math.Sin(2 * Math.PI / len * p * i);for (int j = 0, n = i; j < p; j++, n += (int)Math.Pow(2, l + 1)){temp1_r = X_r[n];temp1_i = X_i[n];temp2_r = X_r[n + space];temp2_i = X_i[n + space];//为蝶形的两个输入数据作副本,对副本进行计算,避免数据被修改后参加下一次计算X_r[n] = temp1_r + temp2_r * WN_r - temp2_i * WN_i;X_i[n] = temp1_i + temp2_i * WN_r + temp2_r * WN_i;X_r[n + space] = temp1_r - temp2_r * WN_r + temp2_i * WN_i;X_i[n + space] = temp1_i - temp2_i * WN_r - temp2_r * WN_i;}}}result_r = X_r;result_i = X_i;}/// <summary>/// 对原数据组进行重排/// </summary>/// <param name="data_r"></param>/// <param name="data_i"></param>public static void DataSort(ref double[] data_r, ref double[] data_i){if (data_r.Length == 0 || data_i.Length == 0 || data_r.Length != data_i.Length)return;int len = data_r.Length;int[] count = new int[len];int M = (int)(Math.Log(len) / Math.Log(2));double[] temp_r = new double[len];double[] temp_i = new double[len];for (int i = 0; i < len; i++){temp_r[i] = data_r[i];temp_i[i] = data_i[i];}for (int l = 0; l < M; l++){int space = (int)Math.Pow(2, l);int add = (int)Math.Pow(2, M - l - 1);for (int i = 0; i < len; i++){if ((i / space) % 2 != 0)count[i] += add;}}for (int i = 0; i < len; i++){data_r[i] = temp_r[count[i]];data_i[i] = temp_i[count[i]];}}/// <summary>/// 求模/// </summary>/// <param name="complex_r"></param>/// <param name="complex_i"></param>/// <param name="mod"></param>public static void GetMod(ref double[] complex_r, ref double[] complex_i, ref double[] mod){if (complex_r.Length == 0 || complex_i.Length == 0 || complex_r.Length != complex_i.Length)return;for (int i = 0; i < complex_r.Length; i++)mod[i] = Math.Sqrt(complex_r[i] * complex_r[i] + complex_i[i] * complex_i[i]);}}
}

2、应用

private void DFTInitialize(){List<double> list = GetCaseData(128);double[] res = FFT.ButterflyFFT(list);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;}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Redis集群搭建以及用idea连接集群
  • 基于Python的机器学习系列(18):梯度提升分类(Gradient Boosting Classification)
  • RabbitMQ练习(Remote procedure call (RPC))
  • 筛法求欧拉函数
  • 问:说一下Java中数组的实例化方式有哪些?
  • Java-数据结构-包装类和认识泛型 !!!∑(゚Д゚ノ)ノ
  • Java Stream流式编程
  • 小程序自定义组件配合插槽和组件传值
  • 重生之我们在ES顶端相遇第11 章 - 深入自定义语言分词器
  • centos 系统yum 安装 mariadb
  • 书生大模型实战营基础(3)——LangGPT结构化提示词编写实践
  • C#基础(2)枚举
  • Linux系统安装MySQL8.0
  • ES6更新的内容中什么是proxy
  • 力扣8.29
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【React系列】如何构建React应用程序
  • 【附node操作实例】redis简明入门系列—字符串类型
  • classpath对获取配置文件的影响
  • CSS相对定位
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • Promise初体验
  • Redux系列x:源码分析
  • springMvc学习笔记(2)
  • 彻底搞懂浏览器Event-loop
  • 你真的知道 == 和 equals 的区别吗?
  • 如何学习JavaEE,项目又该如何做?
  • 微服务框架lagom
  • 微信开源mars源码分析1—上层samples分析
  • 我看到的前端
  • 原生js练习题---第五课
  • 怎么把视频里的音乐提取出来
  • 通过调用文摘列表API获取文摘
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • #android不同版本废弃api,新api。
  • (145)光线追踪距离场柔和阴影
  • (7) cmake 编译C++程序(二)
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (南京观海微电子)——COF介绍
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (一)WLAN定义和基本架构转
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)大型网站的系统架构
  • (转)我也是一只IT小小鸟
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .Net MVC4 上传大文件,并保存表单
  • .net 按比例显示图片的缩略图
  • .net 调用php,php 调用.net com组件 --
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • /proc/stat文件详解(翻译)
  • ::before和::after 常见的用法
  • ?php echo ?,?php echo Hello world!;?
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600