在项目中,需要画波形频谱图,因此进行查找,不是很懂相关知识,下列代码主要是针对这篇文章。

http://blog.csdn.net/xcgspring/article/details/4749075

//快速傅里叶变换
/*
入口参数:
inv: =1,傅里叶变换; =-1,逆傅里叶变换
N:输入的点数,为偶数,一般为2的幂次级,2,4,8,16...
k: 满足N=2^k(k>0),实质上k是N个采样数据可以分解为偶次幂和奇次幂的次数
real[]: inv=1时,存放N个采样数据的实部,inv=-1时,存放傅里叶变换的N个实部
imag[]: inv=1时,存放N个采样数据的虚部,inv=-1时,存放傅里叶变换的N个虚部 出口参数:
real[]: inv=1时,返回傅里叶变换的实部,inv=-1时,返回逆傅里叶变换的实部
imag[]: inv=1时,返回傅里叶变换的虚部,inv=-1时,返回逆傅里叶变换的虚部
*/
void FFT::dealFFT(double real[], double imag[], double dSp[], int N, int k, int inv)
{
int i, j, k1, k2, m, step, factor_step;
double temp_real, temp_imag, factor_real, factor_imag;
if (inv != && inv != -)
return; //double *real = new double[N];
//double *imag = new double[N];
//倒序
j = ;
for (i = ; i < N; i++)
{
if (j>i)
{
temp_real = real[j];
real[j] = real[i];
real[i] = temp_real; temp_imag = imag[j];
imag[j] = imag[i];
imag[i] = temp_imag;
}
m = N / ;
while (j >= m&&m != )
{
j -= m;
m >>= ;
}
j += m;
} //蝶形运算
for (i = ; i < k; i++)
{
step = << (i + );
factor_step = N >> (i + ); //旋转因数变化速度 //初始化旋转因子
factor_real = 1.0;
factor_imag = 0.0; for (j = ; j < step / ; j++)
{
for (k1 = j; k1 < N; k1 += step)
{
k2 = k1 + step / ; //蝶形运算的两个输入 /* temp_real = real[k1] + real[k2] * factor_real - imag[k2] * factor_imag;
temp_imag = imag[k1] + real[k2] * factor_imag + imag[k2] * factor_real;
real[k2] = real[k1] - (real[k2] * factor_real - imag[k2] * factor_imag);
imag[k2] = imag[k1] - (real[k2] * factor_imag + imag[k2] * factor_real);
real[k1] = temp_real;
imag[k1] = temp_imag;*/
//上面方法虽然直白,但效率太低,稍微改变结构如下:
temp_real = real[k2] * factor_real - imag[k2] * factor_imag;
temp_imag = real[k2] * factor_imag + imag[k2] * factor_real;
real[k2] = real[k1] - temp_real;
imag[k2] = imag[k1] - temp_imag;
real[k1] = real[k1] + temp_real;
imag[k1] = imag[k1] + temp_imag;
} factor_real = inv*cos(- * PI*(j + )*factor_step / N);
factor_imag = inv*sin(- * PI*(j + )*factor_step / N);
}
} if (inv == -)
{
for (i = ; i <= N - ; i++)
{
real[i] = real[i] / N;
imag[i] = imag[i] / N;
}
}
for (i = ; i<N;i++)
{
dSp[i] = sqrt(real[i] * real[i] + imag[i] * imag[i]);
}
}

一般好像需要进行下转换,即后半部分和前半部分置换,即1234变成3412.

void  FFT::FFTShift(double dp[], int len)
{
for (int i = ; i < len / ; i++)
{
double tmp = dp[i];
dp[i] = dp[i + len / ];
dp[i + len / ] = tmp;
}
}
此时得到的应该是实部和虚部解出来的频谱图的Y轴电压值,一般频谱图Y轴为dB,因此需要进行转换
void FFT::getFFT(double dRe[], double dIm[], double dSp[], int len, int nBits, double dWorkingImpedance)
{
dealFFT(dRe, dIm, dSp, len, nBits, );
FFTShift(dSp,len); //此时得到的应该是实部和虚部解出来的频谱图的Y轴电压值,还需要转换
////dBW = 10lg(电压^2/阻抗);dBm =dBW+30,注意电压单位是V
for (int i = ; i<len; i++)
{
dSp[i] = * log10(dSp[i] * dSp[i] / dWorkingImpedance)+;
}
}
getFFT()输出之后的dp才是要的频谱图Y轴值,频谱图X轴的坐标得到通过以下方式:

//X轴精确度,采样频率/数据个数 = 步长
m_DeltaX_S = m_dataPara.nSampleFrequency / nDataNumOfPage_S;

data_SX[i / ] = m_dataPara.nCenterFrequency + count*m_DeltaX_S - m_dataPara.nWorkingBandWidth/;//中心频率+当前点*步长-带宽/2

在项目中,实际代码如下:

int count = ;
for (int i = ; i < nDataNumOfPage_S * ; i++)
{
if (i % == )
data_SQ[i / ] = data_S[i] * m_DeltaY_S;
else
data_SI[i / ] = data_S[i] * m_DeltaY_S; if (i % == )
{
count++;
data_SX[i / ] = m_dataPara.nCenterFrequency + count*m_DeltaX_S - m_dataPara.nWorkingBandWidth/;
}
}
m_dataPara.nWorkingImpedance = ;
FFT fft;
int nBits = log10(nDataNumOfPage_S) / log10();//因为参数需要是2的N次方
fft.getFFT(data_SQ, data_SI, data_SS, nDataNumOfPage_S, nBits, m_dataPara.nWorkingImpedance); LoadData_S(data_SX, data_SS, nDataNumOfPage_S);
。。。

其他参考文章:

http://blog.sina.com.cn/s/blog_65d639d50101buo1.html

http://blog.csdn.net/hippig/article/details/8778753

http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%8E%92%E8%A1%8C%E6%A6%9C/20151025/365773.html

[C++] 频谱图中 FFT快速傅里叶变换C++实现的更多相关文章

  1. matlab中fft快速傅里叶变换

    视频来源:https://www.bilibili.com/video/av51932171?t=628. 博文来源:https://ww2.mathworks.cn/help/matlab/ref/ ...

  2. OI中的快速傅里叶变换(FFT)

    快速傅里叶变换(FFT)                                                                               ---- LLpp ...

  3. FFT 快速傅里叶变换 学习笔记

    FFT 快速傅里叶变换 前言 lmc,ikka,attack等众多大佬都没教会的我终于要自己填坑了. 又是机房里最后一个学fft的人 早背过圆周率50位填坑了 用处 多项式乘法 卷积 \(g(x)=a ...

  4. 「学习笔记」FFT 快速傅里叶变换

    目录 「学习笔记」FFT 快速傅里叶变换 啥是 FFT 呀?它可以干什么? 必备芝士 点值表示 复数 傅立叶正变换 傅里叶逆变换 FFT 的代码实现 还会有的 NTT 和三模数 NTT... 「学习笔 ...

  5. CQOI2018 九连环 打表找规律 fft快速傅里叶变换

    题面: CQOI2018九连环 分析: 个人认为这道题没有什么价值,纯粹是为了考算法而考算法. 对于小数据我们可以直接爆搜打表,打表出来我们可以观察规律. f[1~10]: 1 2 5 10 21 4 ...

  6. FFT —— 快速傅里叶变换

    问题: 已知A[], B[], 求C[],使: 定义C是A,B的卷积,例如多项式乘法等. 朴素做法是按照定义枚举i和j,但这样时间复杂度是O(n2). 能不能使时间复杂度降下来呢? 点值表示法: 我们 ...

  7. FFT快速傅里叶变换算法

    1.FFT算法概要: FFT(Fast Fourier Transformation)是离散傅氏变换(DFT)的快速算法.即为快速傅氏变换.它是根据离散傅氏变换的奇.偶.虚.实等特性,对离散傅立叶变换 ...

  8. FFT快速傅里叶变换

    FFT太玄幻了,不过我要先膜拜HQM,实在太强了 1.多项式 1)多项式的定义 在数学中,由若干个单项式相加组成的代数式叫做多项式.多项式中的每个单项式叫做多项式的项,这些单项式中的最高项次数,就是这 ...

  9. 浅谈FFT(快速傅里叶变换)

    本文主要简单写写自己在算法竞赛中学习FFT的经历以及一些自己的理解和想法. FFT的介绍以及入门就不赘述了,网上有许多相关的资料,入门的话推荐这篇博客:FFT(最详细最通俗的入门手册),里面介绍得很详 ...

随机推荐

  1. codeforce Gym 100203I I WIN (网络流)

    把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能 ...

  2. 数据库_7_SQL基本操作——表操作

    SQL基本操作——表操作 建表的过程就是声明列的过程. 表与字段是密不可分的. 一.新增数据表 create table [if not exists] 表名( 字段名字 数据类型, 字段名字 数据类 ...

  3. ios之coredata(二)

    上面一篇文章介绍了coredata的有关基本概念,由于大部分是参考别人文章中的内容,所以感觉有点虚,而且估计也是比较难以理解,下面这篇文章通俗一点说说学习coredata后的一些理解,然后给出一个简单 ...

  4. 控制器生命周期方法(LifeCycle)

    1.init方法: 在init方法中实例化必要的对象(遵从LazyLoad思想) ‍init方法中初始化ViewController本身   2.loadView方法:    当view需要被展示而它 ...

  5. OpenWrt 路由器如何让 lan 口主机获得 ipv6 网络访问 -- 知乎

    本文转自知乎: OpenWrt 路由器如何让 lan 口主机获得 ipv6 网络访问? - mistforest的回答 - 知乎https://www.zhihu.com/question/29667 ...

  6. Springboot(二)-application.yml默认的配置项以及读取自定义配置

    写在前面 ===== spring-boot 版本:2.0.0.RELEASE ===== 读取自定义配置 1.配置文件:sys.properties supply.place=云南 supply.c ...

  7. JS获取单选框checked的value方法

    ; var obj = document.getElementsByTagName("input"); document.getElementById('gender').oncl ...

  8. perl中foreach(二)

    本文和大家重点讨论一下Perl foreach命令的用法,Perl foreach循环中控制变量的值会被Perl自动保存和恢复.当循环进行时,是没有办法改变其值的.循环结束时,变量的值会回到循环开始前 ...

  9. 《零基础入门学习Python》【第一版】视频课后答案第003讲

    测试题答案: 0. 以下哪个变量的命名不正确?为什么? (A) MM_520 (B) _MM520_ (C) 520_MM (D) _520_MM(C)选项不正确,因为 Python 中的变量名不能以 ...

  10. ERROR! The server quit without updating PID file (/usr/local/var/mysql/bogon.pid).

    本文转载自http://www.jb51.net/article/48625.htm 今天网站web页面提交内容到数据库,发现出错了,一直提交不了,数找了下原因,发现数据写不进去!第一反应,重启mys ...