精华内容
下载资源
问答
  • Matlab中快速傅里叶变换FFT结果的物理意义-Matlab中快速傅里叶变换FFT结果的物理意义.doc Matlab中快速傅里叶变换FFT结果的物理意义。 小白级解说, 新手可以看看。:lol
  • MATLAB视频教程详解快速傅里叶变换FFT在MATLAB中的实现-详解快速傅里叶变换FFT在MATLAB中的实现.pdf MATLAB视频教程:详解快速傅里叶变换FFT在MATLAB中的实现,带你全方位理解FFT变换结果
  • 快速傅里叶变换 FFT

    2010-08-31 16:33:41
    快速傅里叶变换, 忘记了来复习一下, 不了解的学习一下 第四章 快速傅里叶变换 FFT 数字信号处理 第四章 PPT课件
  • 快速傅里叶变换FFT

    2019-10-06 04:44:48
    快速傅里叶变换FFT(Fast Fourier Transformation) 本文主要讲述如何使用FFT来实现快速多项式乘法。 多项式的表示 系数表示 对于一个多项式 \[A(x)=\sum_{j=0}^{n-1} a_jx^j\] 向量\(a=(a_0, a_1, ..., a_{n-1})\)为...

    快速傅里叶变换FFT(Fast Fourier Transformation)

    本文主要讲述如何使用FFT来实现快速多项式乘法。

    多项式的表示

    系数表示

    对于一个多项式
    \[A(x)=\sum_{j=0}^{n-1} a_jx^j\]
    向量\(a=(a_0, a_1, ..., a_{n-1})\)为多项式的系数表示。
    利用系数表示时,给出\(x_0\),在\(O(n)\)的时间内可以求出\(A(x_0)\)的值,而且\(A(x)\)的加减法也可以在\(O(n)\)内求出,但乘法则需要\(O(n^2)\)的时间。

    点值表示

    一个多项式\(A(x)\)的点值表示为一个由\(n\)个点值对所组成的集合
    \[\begin{Bmatrix} (x_0, y_0), & (x_1, y_1), & ..., & (x_{n-1}, y_{n-1}) \end{Bmatrix}\]
    使得对\(k=0, 1, 2, ..., n-1\), 所有\(x_k\)各不相同,且\(y_k=A(x_k)\).一个多项式可以有很多不同的点值表示。

    次数界

    如果一个多项式\(A(x)\)的最高次的非零系数为\(a_k\),则称\(A(x)\)的次数为\(k\),记\(degree(A)=k\)。任何严格大于一个多项式次数的整数都是该多项式的次数界。

    定理:对于任意\(n\)个点值对组成的集合,其中\(x_k\)都不同,那么存在唯一的次数界为\(n\)的多项式\(A(x)\),满足\(y_k=A(x_k), k=0, 1, 2, ..., n-1\)

    证明:由线性代数中的范德蒙行列式可证。

    点值表示的优点

    相对于系数表示,点值表示的加减乘法都可以在\(O(n)\)内算出(其中乘法因为当\(x\)一定时,\(y\)值相乘就是之后的\(x\)对应的\(y\)值。

    因为一个多项式的点值表示可以有多种,所以可以选取一些较容易算的值,然后快速把一个多项式从系数表示转化为点值表示,运用点值表示相乘,然后再快速从点值表示转化为系数表示。

    DFT

    因此选择单位复数根作为\(x\),其中\(n\)次单位复数根是满足\(\omega ^n=1\)的复数\(\omega\)\(n\)次单位复数根有\(n\)个:\(\omega_k=e^{2\pi ik/n}, k=0, 1, 2, ..., n-1, \omega_n=e^{2\pi i/n}\)称为主\(n\)次单位根。

    引理1(消去引理):对于任何整数\(n, k \geq 0, d>0, \omega_{dn}^{dk}=\omega_{n}^{k}\),特别地,对于任意偶数\(n>0\),有\(\omega_{n}^{n/2}=\omega_2=-1\)

    证明:\(\omega_{dn}^{dk}=(e^{2\pi i/dn})^{dk}=(e^{2\pi i/n})^k=\omega_n^k\)

    引理2(折半引理):如果\(n>0\)为偶数,那么\(n\)\(n\)次单位复数根的平方的集合就是\(n/2\)\(n/2\)次单位复数根的集合。

    证明:根据消去引理,对任意非负整数\(k\),有\((\omega_n^k)^2=\omega_{n/2}^k\)。注意,如果对于所有\(n\)词单位复数根进行平方,那么获得每个\(n/2\)次单位根正好\(2\)次,因为\((\omega_n^{k+n/2})^2=\omega_n^{2k+n}=\omega_n^{2k}\omega_n^n=\omega_n^{2k}=(\omega_n^k)^2\)

    引理3(求和引理):对任意整数\(n \geq 1\)和不能被\(n\)整除的非负整数\(k\),有\(\sum_{j=0}^{n-1} (\omega_n^k)^j=0\)

    证明:
    \[\sum_{j=0}^{n-1} (\omega_n^k)^j=\frac{(\omega_n^k)^n-1}{\omega_n^k-1}=\frac{(\omega_n^n)^k-1}{\omega_n^k-1}=\frac{0}{\omega_n^k-1}=0\]
    \(k\)不能被\(n\)整除保证分母不为\(0\)


    \[y_k=A(\omega_n^k)=\sum_{j=0}^{n-1} a_j\omega_n^{kj}\]
    \(y=(y_0, y_1, ..., y_{n-1})\)就是系数向量\(a=(a_0, a_1, ..., a_{n-1})\)的离散傅里叶变换(DFT),记为\(y=DFT_n(a)\).

    FFT

    (以下\(n\)默认为\(2\)的幂)
    通过FFT,利用复数单位根的特殊性质,可以在\(O(n log n)\)的时间内算出\(DFT_n(a)\).FFT利用分治策略,采用\(A(x)\)中偶数下标的系数与奇数下标的系数,分别定义两个新的次数界为\(n/2\)的多项式\(A^{[0]}(x), A^{[1]}(x)\):
    \[A^{[0]}(x)=a_0+a_2x+a_4x^2+...+a_{n-2}x^{n/2-1}\]
    \[A^{[1]}(x)=a_1+a_3x+a_5x^2+...+a_{n-1}x^{n/2-1}\]
    \(A(x)=A^{[0]}(x^2)+xA^{[1]}(x^2)\)

    因此\(A(x)\)\(\omega_n^0, \omega_n^1, ..., \omega_n^{n-1}\)的值转换为:

    1. 求次数界为\(n/2\)的多项式\(A^{[0]}(x)\)\(A^{[1]}(x)\)在点\((\omega_n^0)^2, (\omega_n^1)^2, ..., (\omega_n^{n-1})^2\)的值
    2. 根据\(A(x)=A^{[0]}(x^2)+xA^{[1]}(x^2)\)进行整合

    根据折半引理,1中对点求值并不是\(n\)个不同的值,而是\(n/2\)\(n/2\)次单位复数根。即把一个\(n\)个元素的\(DFT_n(a)\)计算划分为两个规模为\(n/2\)个元素的\(DFT_{n/2}\)计算。

    \(n=1\)时,\(y_0=a_0\omega_1^0=a_0\)
    否则设\(y_k^{[0]}=A^{[0]}(\omega_{n/2}^k), y_k^{[1]}=A^{[1]}(\omega_{n/2}^k)\),根据消去引理,有\(y_k^{[0]}=A^{[0]}(\omega_{n}^{2k}), y_k^{[1]}=A^{[1]}(\omega_{n}^{2k})\)


    \[y_k=y_k^{[0]}+\omega_n^ky_k^{[1]}\]
    \[=A^{[0]}(\omega_{n}^{2k})+\omega_n^kA^{[1]}(\omega_{n}^{2k})\]
    \[=A(\omega_n^k)\]

    \[y_{k+(n/2)}=y_k^{[0]}-\omega_n^ky_k^{[1]}\]
    \[=y_k^{[0]}+\omega_n^{k+(n/2)}y_k^{[1]}\]
    \[=A^{[0]}(\omega_{n}^{2k})+\omega_n^{k+(n/2)}A^{[1]}(\omega_{n}^{2k})\]
    \[=A^{[0]}(\omega_{n}^{2k+n})+\omega_n^{k+(n/2)}A^{[1]}(\omega_{n}^{2k+n})\]
    \[=A(\omega_n^{k+(n/2)})\]

    逆运算

    用矩阵表示\(y=V_na\),则\(V_n\)\((k, j)\)处元素为\(\omega_n^{kj}\)。求出\(V_n^{-1}\),则可以求出\(a=DFT_n^{-1}(y)\)

    定理:\(V_n^{-1}\)\((j, k)\)处元素为\(\omega_n^{-kj}/n\)

    证明:考虑\(V_n^{-1}V_n\)中(j, j')处的元素:
    \[[V_n^{-1}V_n]_{jj'}=\sum_{k=0}^{n-1}(\omega_n^{-kj}/n)(\omega_n^{kj'})=\sum_{k=0}^{k(j'-j)}/n\]

    \(j=j'\),则此和为\(1\);否则根据求和引理,此和为\(0\),所以\([V_n^{-1}V_n]\)为单位矩阵。\(a_j=\frac{1}{n}\sum_{k=0}^{n-1}y_k\omega_n^{-kj}\)
    对比DFT:把\(a\)\(y\)互换,用\(\omega_n^{-1}\)替换\(\omega_n\),并将结果除以\(n\)。因此逆运算也可以在\(O(nlogn)\)内完成。

    注意:

    1. 不够\(2\)的幂时要补零
    2. 做完FFT后顺序是乱的,应该按照编号的二进制的翻转对应的十进制进行排序。例如:\(n=8\)
      0 000 000 0
      1 001 100 4
      2 010 010 2
      3 011 110 6
      4 100 001 1
      5 101 101 5
      6 110 011 3
      7 111 111 7

    右边为对应编号

    多项式乘法

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <deque>
    #include <queue>
    #include <vector>
    #include <map>
    #include <complex>
    using namespace std;
    
    typedef complex<double> E;
    const int maxn=int(1e6)+100;
    const double PI=acos(-1);
    
    int n, m;
    int rev[maxn];
    E a[maxn], b[maxn];
    
    void init()
    {
        scanf("%d%d", &n, &m);
        for (int i=0, tmp; i<=n; ++i) 
        {
            scanf("%d", &tmp);
            a[i]=E(tmp, 0);
        }
        for (int i=0, tmp; i<=m; ++i)
        {
            scanf("%d", &tmp);
            b[i]=E(tmp, 0);
        }
        m=n+m;
        for (n=1; n<=m; n<<=1);
    }
    void FFT_init()
    {
        for (int i=0; i<n; ++i)
            for (int j=0; 1<<j<n; ++j)
                rev[i]=(rev[i]<<1) | (i>>j & 1);
    }
    void FFT(E *a, int type)
    {
        for (int i=0; i<=n; ++i)
            if (i<rev[i]) swap(a[i], a[rev[i]]);
        for (int i=2; i<=n; i<<=1)
            for (int j=0; j<n; j+=i)
            {
                E w(cos(2*PI/i), sin(type*2*PI/i)), wn(1, 0);
                for (int k=0; k<i>>1; ++k, wn*=w)
                {
                    E tmp=a[j+k];
                    a[j+k]=a[j+k]+wn*a[j+k+(i>>1)];
                    a[j+k+(i>>1)]=tmp-wn*a[j+k+(i>>1)];
                }
            }
    }
    void solve()
    {
        FFT(a, 1);
        FFT(b, 1);
        for (int i=0; i<n; ++i) a[i]=a[i]*b[i];
        FFT(a, -1);
        for (int i=0; i<=m; ++i)
            printf("%d ", int(a[i].real()/n+0.5));
    }
    int main()
    {
        init();
        FFT_init();
        solve();
        return 0;
    }

    转载于:https://www.cnblogs.com/GerynOhenz/p/4799090.html

    展开全文
  • 快速傅里叶变换fft

    2010-05-07 09:25:23
    快速傅里叶变换fft void InitForFFT() { int i; for ( i=0;i;i++ ) { sin_tab[i]=sin(PI*2*i/SAMPLENUMBER); cos_tab[i]=cos(PI*2*i/SAMPLENUMBER); } }
  • 快速傅里叶变换FFT的笔记,离散的蝶形算法,老外的笔记,值得一看
  • 原创开发,使用Matlab进行离散傅里叶变换DFT(快速傅里叶变换FFT)进行频谱分析、使用Matlab进行利用离散傅里叶逆变换iDFT从频谱恢复时域信号,内含自定义Matlab函数、丰富的演示实例和详细的说明文档,简单易用。
  • 没有调用matlab自带的fft函数,而是自己编写的二维快速傅里叶变换fft程序 matlab平台 没有调用matlab自带的fft函数,而是自己编写的二维快速傅里叶变换fft程序 matlab平台
  • 文章目录傅里叶变换及傅里叶逆变换定义窗函数/矩形脉冲信号的傅里叶变换基于MATLAB的快速傅里叶变换FFT 傅里叶变换及傅里叶逆变换定义 能从时域的非周期连续信号转化到频域非周期连续信号。 窗函数/矩形脉冲...

    傅里叶变换及傅里叶逆变换定义

    能从时域的非周期连续信号转化到频域非周期连续信号。
    在这里插入图片描述

    窗函数/矩形脉冲信号的傅里叶变换

    在这里插入图片描述
    在这里插入图片描述
    结论:

    1. 随着脉冲宽度τ的减小,主叶变得更宽,而且更多的能量被移到更高的频率。则反之。
    2. 当信号脉冲在时间上扩展时,它的变换在频率上压缩。则反之。

    基于MATLAB的快速傅里叶变换FFT

    通过蝶形算法衍生的FFT暂不推导,下面直接给出代码。

    % 功能:简易的快速傅里叶变换FFT
    % 注意:整周期采样的问题,非整周期采样会引起频谱泄露
    %       当NFFT/Fs*f1是整数时,称整周期采样
    
    % 编辑者:lily
    % 日期:2019,4,15
    
    clear;
    clc;
    close all;
    % ======================= input signal ==========================
    f1 = 30;
    fai1 = pi/3;
    Fs = 2^9;
    T =1;      % T = N/Fs 
    t = 0:1/Fs:T-1/Fs;
    N = length(t);
    NFFT = 2^nextpow2(N);%nextpow2(N),靠的最近的2的指数
    x = sin(2*pi*f1*t);
    % ======================= fft ==================================
    deltaF = 1/T;   %  deltaF = dFs/(N-1);%如果是表格或mat文件,推荐用这一种
    vecf = (0:N-1)*deltaF;
    
    % vecf  = linspace(0,Fs,N); 
    % linspace(x1,x2,n) % 生成 n 个点。这些点的间距为 (x2-x1)/(n-1)% 如果数据x是奇数,f=vecf
    
    tic;
    xk = 2*fft(x,NFFT)/N;        
    toc;
    
    Ampli = abs(xk);
    phase = unwrap(angle(xk));
    % =========================== figure ====================================
    figure;
    subplot(3,1,1);plot(t,x);title('信号')
    subplot(3,1,2);plot(vecf,Ampli);title('FFT双边谱')
    subplot(3,1,3);plot(vecf(1:Fs/2+1),Ampli(1:Fs/2+1));title('FFT单边谱')
    
    
    
    展开全文
  • 快速傅里叶变换FFT1

    2013-12-23 15:47:42
    讲解快速傅里叶变换FFT,第一章
  • C#快速傅里叶变换FFT

    热门讨论 2013-08-19 00:42:04
    C#源代码,快速傅里叶变换FFT,计算结果和Matlab相同。
  • 快速傅里叶变换FFT)是一种快速有效率的对DFT的实现。FFT可以被用到加速多项式乘法和两个大整数乘法中。快速傅里叶变换加速多项式乘法,其大致过程是将两个多项式的系数表示通过FFT转化为点值表示(时域到频域)...

    5dd59904522801cf97cd831cd5ed746d.png

    FFT(Fast Fourier Transform)

    离散傅里叶变换(DFT)是来计算多项式在

    个特殊点的值。而
    快速傅里叶变换(FFT)是一种快速有效率的对DFT的实现。FFT可以被用到加速多项式乘法和两个大整数乘法中。快速傅里叶变换加速多项式乘法,其大致过程是将两个多项式的系数表示通过FFT转化为点值表示(时域到频域),然后计算两个多项式点值表示的乘积得到原多项式卷积的点值表示(即乘积多项式系数的FFT变换结果),再将乘积得到的点值表示通过逆离散傅里叶变换(IDFT)就得到了乘积多项式的系数表示。

    多项式的表示

    一个多项式一般有有两种表示方法,系数表示法和点值表示法。系数表示法:

    点值表示法:
    其中
    ,当
    时。这样一个
    次多项式就由在
    个不同点处的取值唯一确定了。证明如下,在一个点处我们有:
    个点处:
    当点互不相同时,对于未知数
    而言,其系数矩阵为范德蒙矩阵,必可逆,故有唯一解,这唯一确定了多项式系数也即唯一确定了多项式。

    快速傅里叶变换

    在复数域内考虑方程

    ,由代数学知识我们知道,它有
    个根,分别为
    ,其中由欧拉公式,
    。 下面来看一下关于
    的性质。基本性质:
    我们挑几个来证明一下,如公式(7):
    公式(8)由公式(7)平方即可证明。再来看一个重要的性质:
    这是因为:
    DFT就是要计算
    在上述
    个根处的取值。如果是朴素的DFT,时间复杂度是
    ,即Horner's method:
    但是现在是一些特殊的点(
    个单位根),由特殊点的性质我们可以去掉很多冗余计算,将时间复杂度降低到
    ,这就是FFT。其思想如下,单位根处的点值表示法:
    现在考察
    ,将奇数项与偶数项分开:
    则可得
    于是
    可以看到计算
    各自只需要
    规模的一半计算量即可得到。这就厉害了,采用Divide and Conquer思想,如果我们已经知道
    分别在
    处的值,可以在常数时间求得
    的值。所以总的时间复杂度为
    ,其中
    是每次分治求对应单位根花费的时间。

    逆离散傅里叶变换

    对一个普通的范德蒙矩阵求逆,时间复杂度是

    ,但是现在我们有一个特殊的范德蒙矩阵:
    它的逆为:
    即原矩阵每个元素的共轭再除以
    ,推导性证明略,下面给一个计算性证明,设上述两个矩阵的乘积矩阵为
    ,则
    可见两矩阵的乘积确为单位阵。这样我们就通过在特殊点处的点值表达式反求出了多项式的系数。 现在考虑两个多项式的乘积
    其中
    由卷积表达式给出
    利用FFT和IDFT可以以
    的时间复杂度得到
    的系数。

    04914718698e51a95d3e2f07757b2500.png

    C++代码实现

    参考资料

    卜东波 算法分析与设计

    展开全文
  • 一维快速傅里叶变换FFT的C++实现,里面是FFT1.cpp函数,用于进行一维数组的FFT。有详细的注释和说明。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,630
精华内容 1,052
关键字:

快速傅里叶变换fft