实序列快速傅里叶变换(一)

一、功能

计算实序列的快速傅里叶变换。

二、方法简介

实序列\(x(n)\)的离散傅立叶变换为
\[
X(k)=\sum_{n=0}^{N-1}x(n)W_{N}^{nk} \ , \ k=0,1,...,N-1
\]
上式可用复序列FFT算法进行计算。但考虑到\(x(n)\)是实数,为进一步提高计算效率,需要对按时间抽取的基2复序列FFT算法进行一定的修改。

如果序列\(x(n)\)是实数,那么其傅立叶变换\(X(k)\)一般是复数,但其实部是偶对称,虚部是奇对称,即\(X(k)\)具有如下共辄对称性: \(X(0)\)和\(X(N/2)\)都是实数,且有
\[
X(k)=X^{*}(N-k) \ , \ 1 \leqslant k \leqslant \frac{N}{2} - 1
\]
在计算离散傅立叶变换时,利用这种共辄对称性,我们就可以不必计算与存储\(X(k)(N/2 + 1 \leqslant k \leqslant N — 1)\)以及\(X(0)\)和\(X(N/2)\)的虚部,而仅需计算\(X(0)\)到\(X(N/2)\)即可。此处我们选择的是计算\(X(0)\)到\(X(N/4)\)和\(X(N/2)\)到\(X(3N/4)\), 这样做可以恰好利用复序列FFT 算法的前\((N/4)+1\)个复数蝶形。这就是按时间抽取的基2实序列FFT算法,它比复序列FFT算法大约可减少一半的运算量和存储量。

三、使用方法

是用C语言实现实序列快速傅里叶变换的方法如下:

/************************************
    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。
************************************/
#include "math.h"

void rfft(double *x, int n)
{
    int i, j, k, m, il, i2, i3, i4, nl, n2, n4;
    double a, e, cc, ss, xt, tl, 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 / nl;
        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;
            }
        }
    }
}

原文地址:https://www.cnblogs.com/liam-ji/p/11742458.html

时间: 2024-08-30 16:37:21

实序列快速傅里叶变换(一)的相关文章

研究傅里叶变换的一本好书&lt;&lt;快速傅里叶变换及其C程序&gt;&gt;

快速傅里叶变换及其C程序 <快速傅里叶变换及其C程序>是中国科学技术大学出版社出版的.本书系统地介绍了傅里叶变换的理论和技术,内容包括傅里叶变换(FT)的定义.存在条件及其性质,离散傅里叶变换(DFT)的定义.性质及由离散引起的频谱混叠和渗漏,快速傅里叶变换(FFT)算法的基本原理和复序列基2算法及其实用程序,并以此为基础,给出了实序列DFT.正弦变换.余弦变换.傅里叶级数.谱函数近似.功率谱估计.卷积和相关等的快速算法和实用程序,给出了 2D—DFT的行列算法.二维实序列2D—DFT的行列算

[学习笔记] 多项式与快速傅里叶变换(FFT)基础

引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积(或者多项式乘法/高精度乘法), 而代码量却非常小. 博主一年半前曾经因COGS的一道叫做"神秘的常数 $\pi$"的题目而去学习过FFT, 但是基本就是照着板子打打完并不知道自己在写些什么鬼畜的东西OwO 不过...博主这几天突然照着算法导论自己看了一遍发现自己似乎突然意识到了什么OwO然后就打了一道板子题还1A了OwO再加上午考试差点AK

快速傅里叶变换FFT

快速傅里叶变换FFT DFT是信号分析与处理中的一种重要变换.但直接计算DFT的计算量与变换区间长度N的平方成正比,当N较大时,计算量太大,直接用DFT算法进行谱分析和信号的实时处理是不切实际的. 1.直接计算DFT 长度为N的有限长序列x(n)的DFT为: 2.减少运算量的思路和方法 思路:N点DFT的复乘次数等于N2.把N点DFT分解为几个较短的DFT,可使乘法次数大大减少.另外,旋转因子WmN具有周期性和对称性. (考虑x(n)为复数序列的一般情况,对某一个k值,直接按上式计算X(k)值需

FFT算法实现——基于GPU的基2快速傅里叶变换

最近做一个东西,要用到快速傅里叶变换,抱着蛋疼的心态,自己尝试写了一下,遇到一些问题. 首先看一下什么叫做快速傅里叶变换(FFT)(来自Wiki): 快速傅里叶变换(英语:Fast Fourier Transform, FFT),是离散傅里叶变换的快速算法,也可用于计算离散傅里叶变换的逆变换.快速傅里叶变换有广泛的应用,如数字信号处理.计算大整数乘法.求解偏微分方程等等. 对于复数串行,离散傅里叶变换公式为: 直接变换的计算复杂度是O(n^2).快速傅里叶变换可以计算出与直接计算相同的结果,但只

51Nod 快速傅里叶变换题集选刷

打开51Nod全部问题页面,在右边题目分类中找到快速傅里叶变换,然后按分值排序,就是本文的题目顺序. 1.大数乘法问题 这个……板子就算了吧. 2.美妙的序列问题 长度为n的排列,且满足从中间任意位置划分为两个非空数列后,左边的最大值>右边的最小值.问这样的排列有多少个%998244353. 多组询问,n,T<=100000. 题解:经过分析可知,不合法的排列一定存在这样一种划分: 我们考虑答案=f[i]=i!-不合法排列个数. 形如 2 1 3 4 6 5 这种排列,会有三种划分方式不合法(

【转】快速傅里叶变换(FFT)详解

目录 前言 多项式 系数表示法 点值表示法 复数 向量 圆的弧度制 平行四边形定则 复数 运算法则 单位根 单位根的性质 快速傅里叶变换 快速傅里叶逆变换 理论总结 递归实现 迭代实现 本文只讨论FFT在信息学奥赛中的应用 文中内容均为个人理解,如有错误请指出,不胜感激 回到顶部 前言 先解释几个比较容易混淆的缩写吧 DFT:离散傅里叶变换->O(n2)O(n2)计算多项式乘法 FFT:快速傅里叶变换->O(n?log(n)O(n?log?(n)计算多项式乘法 FNTT/NTT:快速傅里叶变换

傅里叶变换通俗解释及快速傅里叶变换的python实现

通俗理解傅里叶变换,先看这篇文章傅里叶变换的通俗理解! 接下来便是使用python进行傅里叶FFT-频谱分析: 一.一些关键概念的引入 1.离散傅里叶变换(DFT) 离散傅里叶变换(discrete Fourier transform) 傅里叶分析方法是信号分析的最基本方法,傅里叶变换是傅里叶分析的核心,通过它把信号从时间域变换到频率域,进而研究信号的频谱结构和变化规律.但是它的致命缺点是:计算量太大,时间复杂度太高,当采样点数太高的时候,计算缓慢,由此出现了DFT的快速实现,即下面的快速傅里叶

素因子快速傅里叶变换

一.功能 用素因子分解算法计算复序列的离散傅里叶变换.序列的长度是数集{2,3,4,5,7,8,9,16}中的一个或几个素因子的乘机. 二.方法简介 序列\(x(n)\)的离散傅里叶变换为 \[ X(k)=\sum_{n=0}^{N-1}x(n)W_{N}^{nk}, \ k=0,1,...,N-1 \] 若\(N\)可分解为两两互素因子的乘积,即 \[ N=N_{1}\cdot N_{2}\cdot ...\cdot N_{M}, \ (N_{i},N_{j})=1 \ (i\neq j) \

FFT(快速傅里叶变换)

FFT(快速傅里叶变换) 前置知识 \(1.复数\) \(2.单位根\) \(3.循环结构\) \(4.C++\) 1.复数 \(定义:形如a+bi的数,其中i^2=-1\) \(计算:1.(a+bi)+(c+di)=(a+c)+(b+d)i\) \(\ \ \ \ \ \ \ \ \ \ \ 2.(a+bi)-(c+di)=(a-c)+(b-d)i\) \(\ \ \ \ \ \ \ \ \ \ \ 3.(a+bi)(c+di)=(ac-bd)+(ad+bc)i\) \(向量表示法\) \(用