【嵌入式经验积累】C语言实现傅里叶变换

文章目录

  • C 语言实现离散傅利叶变换(DFT)代码如下:
  • C 语言实现快速傅利叶变换(FFT),代码如下:
  • 分裂基快速傅利叶变换代码如下。
  • 实序列快速傅利叶变换(一),代码如下:
  • 实序列快速傅利叶变换(二),代码如下:
  • Chirp Z 变换,代码如下:

算法笔记

C 语言实现离散傅利叶变换(DFT)代码如下:

/*********************************************************************************************************
* 函数名称: DFT
* 函数功能: 离散傅利叶变换(DFT)
* 输入参数: x:双精度实型一维数组,长度为 n。存放要变换数据的实部。
*            y:双精度实型一维数组,长度为 n。存放要变换数据的虚部。
*            a:双精度实型一维数组,长度为 n。存放变换结果的实部。
*            b:双精度实型一维数组,长度为 n。存放变换结果的虚部。
*            n:整形变量。数据长度
*            sign:整形变量。当 sign=1 时,子函数 DFT() 计算离散傅利叶正变换;当 sign=-1 时,做反变换
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月14日
* 注    意:
*********************************************************************************************************/
void DFT(double* x, double* y, double* a, double* b, int n, int sign)
{int i, k;double c, d, q, w, s;q = 6.28318530718 / (double)n;for (k = 0; k < n; k++){w = k * q;a[k] = b[k] = 0.0;for (i = 0; i < n; i++){d = i * w;c = cos(d);s = sin(d) * sign;a[k] += c * x[i] + s * y[i];b[k] += c * y[i] - s * x[i];}}if (sign == -1){c = 1.0 / (double)n;for (k = 0; k < n; k++){a[k] = c * a[k];b[k] = c * b[k];}}
}

C 语言实现快速傅利叶变换(FFT),代码如下:

/*********************************************************************************************************
* 函数名称: FFT
* 函数功能: 快速傅利叶变换
* 输入参数: x:双精度实型一维数组,长度为 n。开始时存放要变换数据的实部,最后存放变换结果的实部。
*            y:双精度实型一维数组,长度为 n。开始时存放要变换数据的虚部,最后存放变换结果的虚部。
*            n:整形变量。数据长度。必须是 2 的整数次幂,即 n=2^m 。
*            sign:整形变量。当 sign=1 时,子函数 FFT() 计算离散傅利叶正变换;当 sign=-1 时,做反变换
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月14日
* 注    意:
*********************************************************************************************************/
void FFT(double* x, double* y, int n, int sign)
{int i, j, k, l, m, n1, n2;double c, c1, e, s, s1, t, tr, ti;for (j = 1, i = 1; i < 16; i++){m = i;j = 2 * j;if (j == n){break;}}n1 = n - 1;for (j = 0, i = 0; i < n1; i++){if (i < j){tr = x[j];ti = y[j];x[j] = x[i];y[j] = y[i];x[i] = tr;y[i] = ti;}k = n / 2;while (k < (j + 1)){j = j - k;k = k / 2;}j = j + k;}n1 = 1;for (l = 1; l <= m; l++){n1 = 2 * n1;n2 = n1 / 2;e = 3.14159265359 / n2;c = 1.0;s = 0.0;c1 = cos(e);s1 = -sign * sin(e);for (j = 0; j < n2; j++){for (i = j; i < n; i += n1){k = i + n2;tr = c * x[k] - s * y[k];ti = c * y[k] + s * x[k];x[k] = x[i] - tr;y[k] = y[i] - ti;x[i] = x[i] + tr;y[i] = y[i] + ti;}t = c;c = c * c1 - s * s1;s = t * s1 + s * c1;}}if (sign == -1){for (i = 0; i < n; i++){x[i] /= n;y[i] /= n;}}
}

分裂基快速傅利叶变换代码如下。

/*********************************************************************************************************
* 函数名称: SRFFT
* 函数功能: 分裂基快速傅利叶变换
* 输入参数: x:双精度实型一维数组,长度为 n。开始时存放要变换数据的实部,最后存放变换结果的实部。
*            y:双精度实型一维数组,长度为 n。开始时存放要变换数据的虚部,最后存放变换结果的虚部。
*            n:整形变量。数据长度。必须是 2 的整数次幂,即 n=2^m 。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月18日
* 注    意:
*********************************************************************************************************/
void SRFFT(double* x, double* y, int n)
{int i, j, k, m, i1, i2, i3, n1, n2, n4, id, is;double a, e, a3, r1, r2;double s1, s2, s3, cc1, cc3, ss1, ss3;for (j = 1, i = 1; i < 16; i++){m = i;j = 2 * j;if (j == n){break;}}n2 = 2 * n;for (k = 1; k < m; k++){n2 = n2 / 2;n4 = n2 / 4;e = 6.28318530718 / n2;a = 0;for (j = 0; j < n4; j++){a3 = 3 * a;cc1 = cos(a);ss1 = sin(a);cc3 = cos(a3);ss3 = sin(a3);a = ((double)j + 1.0) * e;is = j;id = 2 * n2;do{for (i = is; i < (n - 1); i = i + id){i1 = i + n4;i2 = i1 + n4;i3 = i2 + n4;r1 = x[i] - x[i2];x[i] = x[i] + x[i2];r2 = x[i1] - x[i3];x[i1] = x[i1] + x[i3];s1 = y[i] - y[i2];y[i] = y[i] + y[i2];s2 = y[i1] - y[i3];y[i1] = y[i1] + y[i3];s3 = r1 - s2;r1 = r1 + s2;s2 = r2 - s1;r2 = r2 + s1;x[i2] = r1 * cc1 - s2 * ss1;y[i2] = -s2 * cc1 - r1 * ss1;x[i3] = s3 * cc3 + r2 * ss3;y[i3] = r2 * cc3 - s3 * ss3;}is = 2 * id - n2 + j;id = 4 * id;}while(is < (n - 1));}}is = 0;id = 4;do{for (i = is; i < n; i = i + id){i1 = i + 1;r1 = x[i];r2 = y[i];x[i] = r1 + x[i1];y[i] = r2 + y[i1];x[i1] = r1 - x[i1];y[i1] = r2 - y[i1];}is = 2 * id - 2;id = 4 * id;}while(is < (n - 1));n1 = n - 1;for (j = 0, i = 0; i < n1; i++){if (i < j){r1 = x[j];s1 = y[j];x[j] = x[i];y[j] = y[i];x[i] = r1;y[i] = s1;}k = n / 2;while (k < (j + 1)){j = j - k;k = k / 2;}j = j + k;}
}

实序列快速傅利叶变换(一),代码如下:

/*********************************************************************************************************
* 函数名称: RFFT
* 函数功能: 实序列快速傅利叶变换(一)
* 输入参数: x:双精度实型一维数组,长度为 n。开始时存放要变换的实数据,最后存放变换结果的前 (n/2)+1 个值。
*               存储顺序为:[Re(0),Re(1),...,Re(n/2),Im((n/2)-1),...,Im(1)]。
*               其中 Re(0)=X(0),Re(n/2)=X(n/2)。根据 X(k) 的共轭对称性,很容易写出后半部分的值
*            n:整形变量。数据长度。必须是 2 的整数次幂,即 n=2^m 。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月18日
* 注    意:
*********************************************************************************************************/
void RFFT(double* x, double n)
{int i, j, k, m, i1, i2, i3, i4, n1, n2, n4;double a, e, cc, ss, xt, t1, t2;for (j = 1, i = 1; i < 16; i++){m = i;j = 2 * j;if (j == n){break;}}n1 = n - 1;for (j = 0, i = 0; i < n1; i++){if (i < j){xt = x[j];x[j] = x[i];x[i] = xt;}k = n / 2;while (k < (j + 1)){j = j - k;k = k / 2;}j = j + k;}for (i = 0; i < n; i += 2){xt = x[i];x[i] = xt + x[i + 1];x[i + 1] = xt - x[i + 1];}n2 = 1;for (k = 2; k <= m; k++){n4 = n2;n2 = 2 * n4;n1 = 2 * n2;e = 6.28318530718 / n1;for (i = 0; i < n; i += n1){xt = x[i];x[i] = xt + x[i + n2];x[i + n2] = xt - x[i + n2];x[i + n2 + n4] = -x[i + n2 + n4];a = e;for (j = 1; j <= (n4 - 1); j++){i1 = i + j;i2 = i - j + n2;i3 = i + j + n2;i4 = i - j + n1;cc = cos(a);ss = sin(a);a = a + e;t1 = cc * x[i3] + ss * x[i4];t2 = ss * x[i3] - cc * x[i4];x[i4] = x[i2] - t2;x[i3] = -x[i2] - t2;x[i2] = x[i1] - t1;x[i1] = x[i1] + t1;}}}
}

实序列快速傅利叶变换(二),代码如下:

/*********************************************************************************************************
* 函数名称: RLFFT
* 函数功能: 实序列快速傅利叶变换(二)
* 输入参数: x:双精度实型一维数组,长度为 n。开始时存放要变换的实数据,最后存放变换结果的前 (n/2)+1 个值。
*               存储顺序为:[Re(0),Re(1),...,Re(n/2),Im((n/2)-1),...,Im(1)]。
*               其中 Re(0)=X(0),Re(n/2)=X(n/2)。根据 X(k) 的共轭对称性,很容易写出后半部分的值
*            n:整形变量。数据长度。必须是 2 的整数次幂,即 n=2^m 。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月18日
* 注    意:
*********************************************************************************************************/
void RLFFT(double* x, int n)
{int i, n1;double a, c, e, s, fr, fi, gr, gi, *f, *g;f = malloc((n / 2) * sizeof(double));g = malloc((n / 2) * sizeof(double));n1 = n/ 2;e = 3.141592653589793 / n1;for (i = 0; i < n1; i++){f[i] = x[2 * i];g[i] = x[2 * i + 1];}FFT(f, g, n1, 1);x[0] = f[0] + g[0];x[n1] = f[0] - g[0];for (i = 1; i < n1; i++){fr = (f[i] + f[n1 - i]) / 2;fi = (g[i] - g[n1 - i]) / 2;gr = (g[n1 - i] + g[i]) / 2;gi = (f[n1 - i] - f[i]) / 2;a = i * e;c = cos(a);s = sin(a);x[i] = fr + c * gr + s * gi;x[n - i] = fi + c * gi - s * gr;}free(f);free(g);
}

Chirp Z 变换,代码如下:

#include "math.h"
#include "stdlib.h"
#include "malloc.h"
/*********************************************************************************************************
* 函数名称: CZT
* 函数功能: Chirp Z 变换
* 输入参数: xr:双精度实型一维数组,其长度大于或等于(n + m - 1),且是 2 的 整数次幂。
*                开始时存放输入数据的实部,最后存放变换结果的实部。
*            xi:双精度实型一维数组,其长度大于或等于(n + m - 1),且是 2 的 整数次幂。
*                开始时存放输入数据的虚部,最后存放变换结果的虚部。
*            n:整形变量。输入数据的长度。
*            m:整形变量。输出数据的长度,即频率采样点数。
*            f1:双精度实型变量。起始数字频率,单位为 Hz-s。
*            f2:双精度实型变量。终止数字频率。单位为 Hz-s。
* 输出参数: void
* 返 回 值: void
* 创建日期: 2023年08月29日
* 注    意: 
*********************************************************************************************************/
void CZT(double* xr, double* xi, int n, int m, double f1, double f2)
{int i, j, n1, n2, len;double e, t, ar, ai, ph, pi, tr, ti, *wr, *wr1, *wi, *wi1;len = n + m - 1;for (j = 1, i = 1; i < 16; i++){j = 2 * j;if (j >= len){len = j;break;}}wr = malloc(len * sizeof(double));wi = malloc(len * sizeof(double));wr1 = malloc(len * sizeof(double));wi1 = malloc(len * sizeof(double));pi = 3.14159265358979;ph = 2.0 * pi * (f2 - f1)/(m - 1);n1 = (n >= m)? n:m;for (i = 0; i < n1; i++){e = ph * i * i / 2.0;wr[i] = cos(e);wi[i] = sin(e);wr1[i] = wr[i];wi1[i] = -wi[i];}n2 = len - n + 1;for (i = m; i < n2; i++){wr[i] = 0.0;wi[i] = 0.0;}for (i = n2; i < len; i++){j = len - i;wr[i] = wr[j];wi[i] = wi[j];}FFT(wr, wi, len, 1);ph = -2.0 * pi * f1;for (i = 0; i < n; i++){e = ph * i;ar = cos(e);ai = sin(e);tr = ar * wr1[i] - ai * wi1[i];ti = ai * wr1[i] + ar * wi1[i];t = xr[i] * tr - xi[i] * ti;xi[i] = xr[i] * ti + xi[i] * tr;xr[i] = t;}for (i = n; i < len; i++){xr[i] = 0.0;xi[i] = 0.0;}FFT(xr, xi, len, 1);for (i = 0; i < len; i++){tr = xr[i] * wr[i] - xi[i] * wi[i];xi[i] = xr[i] * wi[i] + xi[i] * wr[i];xr[i] = tr;}FFT(xr, xi, len, -1);for (i = 0; i < m; i++){tr = xr[i] * wr1[i] - xi[i] * wi1[i];xi[i] = xr[i] * wi1[i] + xi[i] * wr1[i];xr[i] = tr;}free(wr);free(wi);free(wr1);free(wi1);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx 实战指南

Nginx 是一款高性能的开源反向代理服务器,也可用作负载均衡器、Web服务器和缓存服务器。本实战指南将带你深入了解 Nginx 的安装、基础配置、高级配置、最佳实践以及性能调优。 步骤 1: 安装 Nginx Ubuntu sudo apt update sudo apt install nginx CentOS sudo yum insta…

python使用分治算法找出出现次数最多的数字

对于给定的一个长度为n的数组nums&#xff0c;需要找出起重工出现次数大于n/2向下取整的元素&#xff0c;假设给定的数组中一定存在符合给定要求的数&#xff0c;例如给定如下的例子&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 添加图片注…

docker使用http_proxy配置代理

钢铁知识库&#xff0c;一个学习python爬虫、数据分析的知识库。人生苦短&#xff0c;快用python。 在内网服务器中&#xff0c;docker经常需要下载拉取镜像&#xff0c;但由于没有网络要么只能手动导入镜像包&#xff0c;又或者通过http_proxy代理到其它服务器下载。 解决方法…

看书标记【R语言数据分析项目精解:理论、方法、实战 9】

看书标记——R语言 Chapter 9 文本挖掘——点评数据展示策略9.1项目背景、目标和方案9.1.1项目背景9.1.2项目目标9.1.3项目方案1.建立评论文本质量量化指标2.建立用户相似度模型3.对用户评论进行情感性分析 9.2项目技术理论简介9.2.1评论文本质量量化指标模型1.主题覆盖量2.评论…

FA-分配行重分配报错【APP-OFA-48313】

FA-重分配行报错 已存在行只能分多次转移调整 Ref1&#xff1a; APP-OFA-48313 You Cannot Create Identical Distribution Lines with Transfer (Doc ID 336894.1) APPLIES TO: Oracle Assets - Version 11.5.10.0 and later Information in this document applies to any…

Ubuntu20 服务器版磁盘扩容

Ubuntu20 服务器版磁盘扩容 Ubuntu20 服务器版磁盘不够用进可以使用fdisk命令对磁盘进行扩容 本案例中是基于vmware虚拟化环境下&#xff0c;ubuntu服务器按默认磁盘大小16G进行安装后&#xff0c;运行一段时间后发面/分区磁盘空间全部用完&#xff0c;导致服务无法正常运行。基…

计算机网络自顶向下Wireshark labs1-Intro

Wireshark labs1 实验文档&#xff1a;http://www-net.cs.umass.edu/wireshark-labs/Wireshark_Intro_v8.0.pdf 介绍 加深对网络协议的理解通常可以通过观察协议的运行和不断调试协议来大大加深&#xff0c;具体而言&#xff0c;就是观察两个协议实体之间交换的报文序列&…

厨艺学习_

选食用油 https://www.bilibili.com/video/BV1oC4y1u799 葵花籽油&#xff1a;万能 玉米油&#xff1a;有香气 菜籽油&#xff1a;又香气&#xff0c;但芥酸高 对三高不好 对老人不好 花生油&#xff1a;不要清炒蔬菜、不能油炸 大豆油&#xff1a;便宜&#xff0c;高温炒…

长虹智能电视 Q2F系列 ZLS59GiQ2机芯 强制刷机升级方法,及刷机升级数据,维修模式进入方法等

适配机芯&#xff1a;ZLS59GiQ2 适配机型&#xff1a;50Q2F、48Q2E、55Q2E、55Q2F、58Q2F、43Q2F、49Q2F、32Q2F 软件强制升级方法&#xff1a; 1、下载后解压&#xff0c;找到upgrade_ZLS59GiQ2_V1.00XXX.bin 、ZLS59GiQ2_mboot.bin复制到U盘根目录&#xff08;不要有任何…

C++ //练习 2.31 假设已有上一个练习中所做的那些声明,则下面的哪些语句是合法的?请说明顶层const和底层const在每个例子中有何体现。

C Primer&#xff08;第5版&#xff09; 练习 2.31 练习 2.31 假设已有上一个练习中所做的那些声明&#xff0c;则下面的哪些语句是合法的&#xff1f;请说明顶层const和底层const在每个例子中有何体现。 r1 v2; p1 p2; p2 p1; p1 p3; p2 p3;环境&#xff1a;Linux Ubun…

React三大属性

我是南城余&#xff01;阿里云开发者平台专家博士证书获得者&#xff01; 欢迎关注我的博客&#xff01;一同成长&#xff01; 一名从事运维开发的worker&#xff0c;记录分享学习。 专注于AI&#xff0c;运维开发&#xff0c;windows Linux 系统领域的分享&#xff01; 知…

只会 Python 不行,不会 Python 万万不行 。。。

当下的环境大家有目共睹&#xff0c;未来一段时间情况如何&#xff0c;想必不少人心里也清楚&#xff0c;技术人走到中年&#xff0c;难免会焦虑&#xff0c;职场上干得不爽&#xff0c;但是跳槽也不容易&#xff0c;加上不少企业裁员&#xff0c;换个满意的工作更是难上加难。…

数学建模--Radar图绘制

1.Radar图简介 最近在数学建模中碰见需要绘制Radar图(雷达图)的情况来具体分析样本的各个特征之间的得分与优劣关系&#xff0c;这样的情况比较符合雷达图的使用场景&#xff0c;一般来说&#xff0c;雷达图适用于展示多个维度的数据&#xff0c;并在一个平面上直观地呈现出不同…

长虹智能电视ZLS58Gi4X机芯刷机升级方法,附整机USB升级固件数据 U3、1U、U1、U3C、6000i系列等适用

适用机芯&#xff1a;ZLS58Gi4X 适用机型&#xff1a; 40U3、65U3、43A1U、49A1U、55A1U、43C1U、50C1U、43U1、49U1、50U1、55U1、58U1、43U1A、49U1A、50U1A、55U1A、58U1A、43U3C、49U3C、50U3C、55U3C、43Z80U、50Z80U、55Z80U、LED49Z80U、LED55Z80U、UD43D6000i、UD49D…

sql数据库的相关概念与底层介绍

本文中的数据库指的是磁盘数据库。如果有sql语言&#xff08;CRUD&#xff0c;增删改查&#xff09;的使用经验会更容易理解本文的知识点。 数据库与redis的区别 数据库&#xff1a;数据存储长期在磁盘中&#xff0c;小部分频繁需要的数据会被临时提取在内存中。 Redis&…

np.argsort排序问题(关于位次)-含GitHub上在numpy项目下提问的回复-总结可行方案

np.argsort 与获取位相关问题 位次: 数组中的数据在其排序之后的另一个数组中的位置 [1,0,2,3] 中 0的位次是1 1的位次是2 2的位次是3 3的位次是4 这里先直接给出结论&#xff0c;np.argsort()返回的索引排序与实际位次在确实在某些情况下会出现一致&#xff0c;但后来numpy的开…

用pandas实现用前一行的excel的值填充后一行

今天接到一份数据需要分析&#xff0c;数据在一个excel文件里&#xff0c;内容大概形式如下&#xff1a; 后面空的格子里的值就是默认是前面的非空的值&#xff0c;由于数据分析的需要需要对重复的数据进行去重&#xff0c;去重就需要把控的cell的值补上&#xff0c;然后根据几…

HCIP网络的类型

一.网络类型&#xff1a; 点到点 BMA&#xff1a;广播型多路访问 -- 在一个MA网络中同时存在广播&#xff08;泛洪&#xff09;机制 NBMA&#xff1a;非广播型多路访问 -- 在一个MA网络中&#xff0c;没有泛洪机制-----不怎么使用了 MA&#xff1a;多路访问 -- 在一个…

JavaEE 文件操作IO

文件操作&IO 文章目录 文件操作&IO1. 认识文件2. 文件操作2.1 File 类2.2 文件读写2.2.1 FileInputStream2.2.2 FileOutputStream2.2.3 FileReader2.2.4 FileWriter2.2.5 Scanner读取文件 3. 案例练习3.1 案例一3.2 案例二3.3 案例三 在进行文件操作之前&#xff0c;我…

Vue 如何使用WebSocket与服务器建立链接 持续保持通信

WebSocket 浏览器通过JavaScript向服务器发出建立WebSocket链接的请求&#xff0c;链接建立后&#xff0c;客户端和服务器端就可以通过TCP链接直接交互数据。WebSocket链接后可以通过send()方法来向服务器发送数据&#xff0c;并通过onnessage事件来接受服务器返回的数据。 创…