N点复数FFT计算2N点实数FFT

2 篇文章 1 订阅
订阅专栏

概述

一般来讲,不考虑效率的时候,实数作2N点FFT时可以将虚部设为0,直接调用2N点FFT的程序。但最近在公司读之前的代码,读了快一个月没读懂,最后还是前辈讲了之后才发现利用了N点FFT计算2N点实数FFT这个技巧,在这里做个简单的分享。

算法原理

首先贴上教材里对这个方法的说明:

 

注意,教材这里讲对称性时认为X(N)=X(0)

代码实现

首先将输入的实数序列分奇偶项,奇数项作实部,偶数项作虚部构造一个复数序列。(Complex是自己写的复数类)。

    //将2N点的实数变换为N点的复数
    vector<Complex> vin(input_len);
    for (i = 0; i < input_len; i++)
    {
        
        vin[i].real = realsig[2 * i];
        vin[i].image = realsig[2 * i + 1];
    }

这里realsig就是输入的实数信号,S16表示16位有符号数,换成int\double之类的都可以。

做完FFT按教材上的公式进行转换,注意下面的三目运算符的目的是使得x(N)=x(0)

    FFT(vin);
    vector<Complex> vout(input_len);
    for (int i = 0; i < input_len; i++)
    {
        Complex XN_K = i ? vin[input_len - i] : vin[0];
        XN_K.conj();
        double er = 2;
        Complex fuj(0, -1 / 2);
        Complex X1 = (vin[i]+XN_K) ;
        X1 = X1 / er;
        Complex X2 =  (vin[i] - XN_K)* fuj;
        Complex W2N_K(cos(-pi / input_len * i), sin(-pi / input_len * i));
        vout[i] =  W2N_K * X2+X1;

    }

这样,vout中就是实数2N点FFT的前N个结果。至于后N个值可用上面书上的公式得到。

将结果在matlab中对比,当N=1024时结果如下:

 可见C中结果正好是实数2048点FFT的前半部分。

完整代码

为方便大家使用,我把整个完整代码贴在下面。

#include<iostream>
using namespace std;

#include<vector>

#include<fstream>
#include<string>
class Complex
{
public:
    double real;
    double image;
    Complex operator+(Complex& x);
    Complex operator-(Complex& x);
    Complex operator*(Complex& x);
    
    friend Complex operator/(Complex&c,double& x);
    Complex(double r = 0, double i = 0);
    void conj();
    double amp();
};

Complex Complex::operator+(Complex& x)
{
    Complex ans = *this;
    ans.real += x.real;
    ans.image += x.image;
    return ans;


}

Complex Complex::operator-(Complex& x)
{
    Complex ans = *this;
    ans.real -= x.real;
    ans.image -= x.image;
    return ans;
}

Complex Complex::operator*(Complex& x)
{
    Complex ans;
    ans.real = real * x.real - image * x.image;
    ans.image = real * x.image + image * x.real;
    return ans;
}

Complex::Complex(double r, double i)
{
    real = r;
    image = i;
}

double Complex::amp()
{
    return sqrt(real * real + image * image);
};



void Complex::conj()
{
    this->image = -this->image;
}

Complex operator/(Complex& c, double& x)
{
    Complex ans;
    ans.real = c.real / x;
    ans.image = c.image / x;
    return ans;
}

void FFT(vector<Complex>& A)
{
    int m = A.size();
    if (m <= 1)
        return;
    int i = 0;
    vector<Complex> even(m / 2);
    vector<Complex> odd(m / 2);
    for (i = 0; i < m - 1; i += 2)
    {
        odd[i >> 1] = A[i + 1];
        even[i >> 1] = A[i];
    }
    FFT(odd);
    FFT(even);
    for (int k = 0; k < m / 2; k++)
    {
        Complex t = Polar(1, -2 * pi * k / m) * odd[k];
        A[k] = even[k] + t;
        A[k + m / 2] = even[k] - t;
    }
}

void fin(string path, vector<S16>& v)
{
    //从文件中读取数据到v中
    //v为空
    ifstream infile;   //输入流
    string path1 = path;
    infile.open(path1, ios::in);
    cout << "isopen:" << infile.is_open() << endl;

    int m = 0;
    if (infile.is_open())
    {
        string s;
        while (getline(infile, s))
        {
            int num = stod(s);  //放缩
            v.push_back(num);
            m++;
            if (m > 2048)
                break;
        }

    }
    infile.close();
}


int main()
{

    write_twiddle(9);

    int i;

    S32 Stage_N = 5;
    int realN = Stage_N * 2;
    ifstream infile;   //输入流
    string path1 = "../FFTx.txt";
    string pathin2 = "../matlab_fftimagin.txt";
    vector<int> realsig;  //实数信号

    fin(path1, realsig);
    
    int input_len = 1<<(2* Stage_N);
    //将2N点的实数变换为N点的复数(即1024点的实数切换成512点复数)
    vector<Complex> vin(input_len);
    for (i = 0; i < input_len; i++)
    {
        
        vin[i].real = realsig[2 * i];
        vin[i].image = realsig[2 * i + 1];
    }
    FFT(vin);
    vector<Complex> vout(input_len);
    for (int i = 0; i < input_len; i++)
    {
        Complex XN_K = i ? vin[input_len - i] : vin[0];
        XN_K.conj();
        double er = 2;
        Complex fuj(0, -1 / 2);
        Complex X1 = (vin[i]+XN_K) ;
        X1 = X1 / er;
        Complex X2 =  (vin[i] - XN_K)* fuj;
        Complex W2N_K(cos(-pi / input_len * i), sin(-pi / input_len * i));
        vout[i] =  W2N_K * X2+X1;

    }
}

其实公司代码不长这样,这里只是为了方便理解写了复数类,FFT也是自己写的一个极低效率版本。如有错误还请指出。

实验二:fft算法的matlab实现_C语言系列之FFT算法实现
weixin_39973410的博客
12-03 2665
0x10 序言 长文预警,详细介绍FFT算法的编程原理和C实现,并在文章的最后附上了本文的所有源代码。0x11 速览1)FFT背后的数学原理2)码位倒序3)蝶形运算设计4)利用复数FFT编写复数IFT,实数FFT实数IFFT5)总结0x20 FFT背后的数学原理01前言本文阅读前提知识准备:已经初步了解傅里叶变换。傅里叶变换公式: 本文不刨根问底,只讲跟FFT编程相关必须知道的知识,相...
2N实数序列为 N=64。用一个复数FFT程序,一次算出,并绘出。
林洋洋博客
11-20 7971
2N实数序列为 N=64。用一个复数FFT程序,一次算出,并绘出。 试利用MATLAB编程完成计算,绘出相应图形。并与理论计算相比较,说明实验结果的原因。
几个FFT的公式(4):利用1个N复数FFT,计算2个N实数FFT
weixin_47365352的博客
01-17 729
实数FFT复数FFT
最新发布
qq_51274880的博客
07-14 353
例如当采样为8192时,最大幅度值位置大于中心4096时,频率计算为:(最大幅度值位置 - 8192)*采样率/8192,最大幅度值位置小于中心4096时,频率计算为:最大幅度值位置*采样率/8192。输入时域数据为实数时:单一频率的时域信号比如cos和sin在复频域表现为正负对称的两个复数频率.,得出的频谱图是对称的。例如当采样为8192时,关于中心4096对称,求频率时,只需处理0~4096区间的最大幅度值的位置,频率计算为:最大幅度值位置*采样率/8192,
实数复数FFT
我的博客
05-25 7866
实数FFT复数FFTFFT是DFT的快速算法,从时域转换到实数FFT复数FFT中的实数复数是相对与输入数据而言,从上面两张图中可以看出: N复数FFT需要时域的N实数和N虚数(一般设置为0),经FFT转换后,频域得到N实数和N的虚数(因为前后两部分是共轭对称,所以有效数据只有N/2+1个实数和N/2+1个虚数)。 N实数FFT只需要时域N实数,经FFT转换后,得到频域N/2+1个实数和N/2+1个虚数。 另外N复数FFT可以实现2N实数FFT: clear all
几个FFT的公式(2):利用N复数FFT,计算2N实数FFT
weixin_47365352的博客
01-17 728
利用N复数序列求2个N实数序列的快速傅里叶变换
坚持学习
10-14 641
利用N复数序列求2个N实数序列的快速傅里叶变换
FFT算法的应用【数字信号处理三】
zgr957254329的博客
04-05 3147
FFT算法的应用一、用N复数FFT计算2N实数序列二、已知Z变换,计算NIFFT与序列 一、用N复数FFT计算2N实数序列 N=64; n=0:N-1; n1=2*n; n2=2*n+1; n3=0:2*N-1; xn1=cos(2*pi*7*n1/N)+1/2*cos(2*pi*19*n1/N); xn2=cos(2*pi*7*n2/N)+1/2*cos(2*pi*19*n2/N); xn3=cos(2*pi*7*n3/N)+1/2*cos(2*pi*19*n3/N); %构造复数序列
复数fft的时间复杂度_DFT算法FFT算法的优劣分析
weixin_39829307的博客
12-24 2114
一、概述在谐波分析仪中,我们常常提到的两个词语,就是DFT算法FFT算法,那么一款功率分析仪/谐波分析仪采用DFT算法或者FFT算法,用户往往关注的是能否达到所要分析谐波次数的目的,而并未考虑两种算法之间有什么不同,采用相关算法的依据。下面就来介绍一下两种算法的不同以及适用的一些场合。DFT算法,是连续傅里叶变换在时域和频域上都离散的形式,将时域信号的采样变换为在离散时间傅里叶变换频域的采样。F...
复数fft的时间复杂度_1周学FFT——第3天 DFT算法的时间消耗和快速傅里叶变换
weixin_32060735的博客
12-24 1080
考虑DFT的运算公式为:根据上式,可得 的展开式为:其中 。如果根据DFT的 展开式直接编写算法的话,所需的运算次数估算如下:由于 是复数,所以要计算1个 需要进行N次复数乘法,和N-1次复数加法。更进一步,计算N的DFT则需要 次复数乘法和 次复数加法。而1次复数乘法需要分为4次实数乘法和2次实数加法(也可以是2次乘法,2次乘加),1次复数加法需要分为2次实数加法。所以计算1个 需要进行...
NFFT变换
05-22
使用Visual Basic 编写的N快速傅里叶变换学习程序
C#FFT实数实现
04-23
已经包装成了.cs文件。 直接调用fourier.fft(n,input) 输入input数组,直接运算nDFT 返回一个n的数组。
实数FFT算法的设计及其C语言实现
07-30
本人结合自己的实际开发经验,研究了实数FFT算法并给出具体的C语言函数,读者可以直接应用于自己的系统中。
fft_split.m 拆分两个实数序列的FFT:将一个序列x=x1+i*x2的FFT拆分为实数输入序列x1,x2的FFT-matlab开发
06-01
当长度为 2N实数序列的 FFT 仅使用一个长度为 N 的 FFT 计算时,此操作也很有用。 标准 FFT 算法需要复杂的输入序列。 如果只有真实的输入数据可用,计算 FFT 的最简单方法是将输入序列的虚部设置为零,但这会...
FFT结果的物理意义
浩然也空 的专栏
11-17 2973
     原文  FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。虽然很多人都知道FFT是什么,可以用来做什么,怎么去做,但是却不知道FFT之后的结果是什意思、如何决定要使用多少
几个FFT的公式(3):利用2个N实数FFT,计算N复数FFT
weixin_47365352的博客
01-17 685
这个公式看起来有复杂,是因为N实数FFT的结果只计算了N/2,而不是N
C语言编程求实数和,求:实数序列的FFT变换C语言程序代码?
weixin_35029593的博客
05-18 354
1. /*程序说明:2. 如果序列x(n)是实数,那么其傅立叶变换X(k)一般是复数,但其实部是偶对称,虚部是奇对称,即3. X(k)具有如下共轭对称性:X(0)和X(N/2)都是实数,且有X(k)=X*(N-k), 1<=k<=N/2-14. 在计算离散傅立叶变换时,利用这种共轭对称性,我们就可以不必计算与存储X(k)(N/2+1<=k<=N-1)5. 以及X(0)...
2N实序列的FFT, MATLAB CODE
goudahai的专栏
09-26 3769
2N实序列的FFT 空间 function X = fft_2N(x) % 计算长度为2N的实序列的FFT % John G.Proakis,数字信号处理,第四版 % Define variables: %   x       --- Input real vector of length 2*N(power o
实数fft复数fft
09-07
实数FFT复数FFTFFT(快速傅里叶变换)的两种变体。 实数FFT是指将实数序列转换为频域表示的快速傅里叶变换。实数FFT的输入是一个实数序列,经过变换后得到一个包含实数和虚数的频域表示。在实数FFT中,频谱具有对称性,因此只需要计算一半的频谱即可得到完整的结果。实数FFT计算速度较快,其中的原因是先计算N/2复数FFT,然后利用频谱的对称性重塑数据,得到半个FFT频谱即可。 复数FFT是指将复数序列转换为频域表示的快速傅里叶变换。复数FFT的输入是一个复数序列,经过变换后得到一个包含实数和虚数的频域表示。在复数FFT中,频谱包含了N个实数和N个虚数,其中前后两部分是共轭对称的,因此有效数据只有N/2 + 1个实数和N/2 + 1个虚数。复数FFT还可以用于实现两个N实数序列的FFT计算。 总结起来,实数FFT是将实数序列转换为频域表示的快速傅里叶变换,而复数FFT是将复数序列转换为频域表示的快速傅里叶变换。它们的计算方法和结果略有不同,但都可以用于频域分析和信号处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>
写文章

热门文章

  • N点复数FFT计算2N点实数FFT 3323
  • FFTW入门(1):环境搭建 1981

分类专栏

  • 数字信号处理 2篇

最新评论

  • N点复数FFT计算2N点实数FFT

    witcherlucas: 不同在哪呢 ,应该是一样的啊

  • FFTW入门(1):环境搭建

    qq_53376809: 在生成lib时转路径拒绝访问

  • N点复数FFT计算2N点实数FFT

    被拨动的弦: 为什么这种方法的结果和直接在2N实序列的虚部补零并应用FFT算出的一半频率会有些不同

  • N点复数FFT计算2N点实数FFT

    会开车的凉拖鞋: 谢谢

  • N点复数FFT计算2N点实数FFT

    witcherlucas: 《数字信号处理》第三版--高西全等著

大家在看

  • 电商导购平台的动态扩展与缩容策略 1966
  • 【系统架构设计师】论文模板:快速写好一篇架构设计师论文
  • pandas库中pd.DataFrame._append()的初次尝试 22
  • Java基于SpringBoot的特色农产品交易系统 微信小程序+Vue[毕业设计]
  • 最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本) 2269

最新文章

  • FFTW入门(1):环境搭建
2022年2篇

目录

目录

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家坚固的玻璃钢雕塑枣庄商场美陈合肥特色玻璃钢雕塑云南玻璃钢马雕塑定制江苏仿石头玻璃钢花盆创意玻璃钢摆件雕塑淮南玻璃钢花盆白银人物玻璃钢雕塑湖南玻璃钢景观雕塑厂餐饮玻璃钢浮雕景观雕塑定做徐州商场美陈公司连云港玻璃钢雕塑工程福建秋季商场美陈采购淮北十二生肖玻璃钢雕塑湖南玻璃钢几何雕塑玻璃钢室外镂空雕塑生产厂家上饶步行街玻璃钢雕塑优势安阳玻璃钢卡通雕塑定做厂家河北装饰商场美陈多少钱山西泡沫玻璃钢雕塑洛阳玻璃钢雕塑订做杭州玻璃钢雕塑定西仿真人物玻璃钢雕塑选择一款好的玻璃钢雕塑青海景区玻璃钢雕塑云南玻璃钢雕塑设计公司多少钱西藏玻璃钢艺术雕塑大理市玻璃钢雕塑设计价格表福建玻璃钢花盆生产厂家郑州商场美陈仿真花树香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化