FFT快速傅里叶变换(多项式乘法)

十分简明易懂的FFT(快速傅里叶变换) FFT有什么用 快速傅里叶变换 (fast Fourier transform),即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。快速傅里叶变换是1965年由J.W.库利和T.W.图基提出的。采用这种算法能使计算机计算离散傅里叶变换所需要的乘法次数大为减少,特别是被变换的抽样点数N越多,FFT算法计算量的节省就越显著。 FFT(Fast Fouri... 阅读详情


本文仅供作者本人练习推导FFT,如有侵权请私信我

FFT算法过程

FFT的精髓在于将 n − 1 ( log ⁡ 2 n ∈ N ) n-1(\log_2n\in \N) n−1(log2​n∈N) 次的 n n n 项多项式 A ( x ) A(x) A(x) 在 O ( n log ⁡ n ) O(n\log n) O(nlogn) 的时间(而不是硬算的 O ( n 2 ) O(n^2) O(n2) )内求出其在 n n n 个 n − 1 n-1 n−1 次单位根 ω n − 1 i ( i = 0 , 1 , … , n − 1 ) \omega_{n-1}^i(i=0,1,\dots,n-1) ωn−1i​(i=0,1,…,n−1) 上的取值,也就是将任意多项式O(nlogn)从系数表示法转化为点值表示法

推式子

设 A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n − 1 x n − 1 令 A 0 ( x ) = a 0 + a 2 x + a 4 x 2 + ⋯ + a n 2 − 1 , A 1 ( x ) = a 1 + a 3 x + a 5 x 2 + ⋯ + a n 2 − 1 . 则显然 A ( x ) = A 0 ( x 2 ) + x A 1 ( x 2 ) 将 x = ω n − 1 i 代入 ( 1 ) 有: A ( ω n − 1 i ) = A 0 ( ω n − 1 2 i ) + ω n − 1 i A 1 ( ω n − 1 2 i ) ( ⇒ A ( ω n − 1 i ) = A 0 ( ω ( n − 1 ) / 2 i ) + ω n − 1 i A 1 ( ω ( n − 1 ) / 2 i ) 将 x = ω n − 1 i + ( n − 1 ) / 2 代入 ( 1 ) 有: A ( ω n − 1 i ) = A 0 ( ω ( n − 1 ) / 2 2 i + ( n − 1 ) ) + ω n − 1 i + ( n − 1 ) / 2 A 1 ( ω n − 1 2 i + ( n − 1 ) ) ( ⇒ A ( ω n − 1 i ) = A 0 ( ω ( n − 1 ) / 2 i ) − ω n − 1 i A 1 ( ω ( n − 1 ) / 2 i ) 设A(x)=a_0+a_1x+a_2x^2+\dots+a_{n-1}x^{n-1}\\ 令A_0(x)=a_0+a_2x+a_4x^2+\dots+a^{\frac n2-1},\\ A_1(x)=a_1+a_3x+a_5x^2+\dots+a^{\frac n2-1}.\\ 则显然\begin{equation}A(x)=A_0(x^2)+xA_1(x^2)\end{equation}\\ 将 x=\omega_{n-1}^i 代入 (1)有:\begin{equation}A(\omega_{n-1}^i)=A_0(\omega_{n-1}^{2i})+\omega_{n-1}^{i}A_1(\omega_{n-1}^{2i})(\end{equation}\\ \Rightarrow\begin{equation}A(\omega_{n-1}^i)=A_0(\omega_{(n-1)/2}^i)+\omega_{n-1}^iA_1(\omega_{(n-1)/2}^{i})\end{equation}\\ 将 x=\omega_{n-1}^{i+(n-1)/2}代入 (1)有:\begin{equation}A(\omega_{n-1}^i)=A_0(\omega_{(n-1)/2}^{2i+(n-1)})+\omega_{n-1}^{i+(n-1)/2}A_1(\omega_{n-1}^{2i+(n-1)})(\end{equation}\\ \Rightarrow\begin{equation}A(\omega_{n-1}^i)=A_0(\omega_{(n-1)/2}^i)-\omega_{n-1}^iA_1(\omega_{(n-1)/2}^i)\end{equation} 设A(x)=a0​+a1​x+a2​x2+⋯+an−1​xn−1令A0​(x)=a0​+a2​x+a4​x2+⋯+a2n​−1,A1​(x)=a1​+a3​x+a5​x2+⋯+a2n​−1.则显然A(x)=A0​(x2)+xA1​(x2)​​将x=ωn−1i​代入(1)有:A(ωn−1i​)=A0​(ωn−12i​)+ωn−1i​A1​(ωn−12i​)(​​⇒A(ωn−1i​)=A0​(ω(n−1)/2i​)+ωn−1i​A1​(ω(n−1)/2i​)​​将x=ωn−1i+(n−1)/2​代入(1)有:A(ωn−1i​)=A0​(ω(n−1)/22i+(n−1)​)+ωn−1i+(n−1)/2​A1​(ωn−12i+(n−1)​)(​​⇒A(ωn−1i​)=A0​(ω(n−1)/2i​)−ωn−1i​A1​(ω(n−1)/2i​)​​
注意到
{ A ( ω n − 1 i ) = A 0 ( ω ( n − 1 ) / 2 i ) + ω n − 1 i A 1 ( ω ( n − 1 ) / 2 i ) A ( ω n − 1 i ) = A 0 ( ω ( n − 1 ) / 2 i ) − ω n − 1 i A 1 ( ω ( n − 1 ) / 2 i ) \begin{cases} A(\omega_{n-1}^i)=A_0(\omega_{(n-1)/2}^i)+\omega_{n-1}^iA_1(\omega_{(n-1)/2}^{i})\\ A(\omega_{n-1}^i)=A_0(\omega_{(n-1)/2}^i)-\omega_{n-1}^iA_1(\omega_{(n-1)/2}^i) \end{cases} {A(ωn−1i​)=A0​(ω(n−1)/2i​)+ωn−1i​A1​(ω(n−1)/2i​)A(ωn−1i​)=A0​(ω(n−1)/2i​)−ωn−1i​A1​(ω(n−1)/2i​)​
所以只需要求出 A 0 ( x ) A_0(x) A0​(x) 和 A 1 ( x ) A_1(x) A1​(x) 的各 n / 2 n/2 n/2 个点值就可以得到 A ( x ) A(x) A(x) 的 n n n 个点值。看似求的点值没变,但是只需要进行 log ⁡ n \log n logn 轮操作,所以时间复杂度是低的
附记:此处推式子应该用 n n n 而不是 n − 1 n-1 n−1 的,会更好看……

代码实现

实现代码时,建议使用非递归写法来节省空间和行数
【例题:】O(nlogn)高精度乘法

#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1);
struct Co {
    double Re, Im;
};
Co operator+(Co A, Co B) {return Co{A.Re + B.Re, A.Im + B.Im};}
Co operator-(Co A, Co B) {return Co{A.Re - B.Re, A.Im - B.Im};}
Co operator*(Co A, Co B) {return Co{A.Re*B.Re-A.Im*B.Im, A.Im*B.Re+A.Re*B.Im};}
void FFT(int n, vector<Co> &a, int type);
void init();
string s1, s2, o;
int n, m, lim = 1, lg;
vector<Co> a, b, ans;
vector<int> rev;
int main()
{
    // freopen("D.in", "r", stdin);
    // freopen("D.out", "w", stdout);
    // ios::sync_with_stdio(0);
    // cin.tie(0);
    cin >> s1 >> s2;
    n = s1.size();
    m = s2.size();
    for (int i = n - 1; i >= 0; --i) a.push_back(Co{double(s1[i] - '0'), 0});
    for (int i = m - 1; i >= 0; --i) b.push_back(Co{double(s2[i] - '0'), 0});

    init();
    FFT(lim, a, 1);
    FFT(lim, b, 1);

    for (int i = 0; i < lim; ++i) {
        ans[i] = a[i] * b[i];
    }
    FFT(lim, ans, -1);
    int carry = 0;
    for (int i = 0; i < lim; ++i) {
        int t = (int)(ans[i].Re / lim + 0.5);
        t += carry;
        carry = t / 10;
        t %= 10;
        o += char(t + '0');
    }
    int end = o.size() - 1;
    while (o[end] == '0' && end > 0) --end;
    while (~end) {
        putchar(o[end]);
        --end;
    }
    return 0;
}
void init() {
    while (lim <= n + m) {
        lim <<= 1;
        ++lg;
    }
    rev.resize(lim, 0);
    for (int i = 1; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (lg - 1));
    a.resize(lim, Co{0, 0});
    b.resize(lim, Co{0, 0});
    ans.resize(lim, Co{0, 0});
}
void FFT(int n, vector<Co> &a, int type) {
    // 二进制重排
    for (int i = 1; i < n; ++i) {
        if (i < rev[i]) swap(a[i], a[rev[i]]);
    }
    
    for (int mid = 1; mid < n; mid <<= 1) {
        Co Wn{cos(PI / mid), type * sin(PI / mid)};
        for (int l = 0; l < n; l += (mid << 1)) {
            Co w{1, 0};
            for (int i = 0; i < mid; ++i) {
                Co tmp = w * a[l + mid + i];
                a[l + mid + i] = a[l + i] - tmp; // 新右=左-w*右
                a[l + i] = a[l + i] + tmp; // 新左=左+w*右
                w = w * Wn;
            }
        }
    }
}
快速傅里叶变换(FFT)算法学习 算法的世界多么广大,我们可以将算法大致分为两类:第一类是较为有用的算法:比如一些经典的图算法,像 DFS 和 BFS(深度 / 广度优先算法),这些算法应用在很多方面,他们非常高效, 第二类算法是那些极具美感的算法:例如当我们第一次看到汉诺塔的递归实现算法时的状态,你肯定会觉得这个算法贼牛逼,甚至会被它的美感所震撼到,但这些算法或许并没有那么有用或者高效,不过我们还是会研究它,就像没事干了我们还是会看小说; 这些伟大而精妙的算法会激发我们的灵感,促使我们发散性思考,下面介绍一种同时属于以上两类的算法:快速傅 阅读详情

相关推荐

使用基数快速傅里叶变换(Radix FFT)的快速多项式乘法算法

FFT是一种高效的算法,用于将一个多项式从系数表示转换为点值表示,以便进行快速乘法运算。基数FFT是FFT的一种变体,它将输入多项式分解为多个较小的多项式,并利用递归的方式进行计算。基数FFT的核心思想是将输入多项式分解为两个较小的多项式,然后将它们的点值表示相乘得到结果的点值表示,最后通过逆FFT将结果转换回系数表示。通过利用FFT算法的高效性质,该算法可以显著提高多项式乘法的计算速度,特别是对于大型多项式而言。函数,该函数接受两个多项式的系数作为输入,并返回它们的乘积的系数。最后,我们实现了一个。

DevScript的博客 291

【FFT实战篇】C++实现:利用快速傅里叶变换快速计算(多项式)乘法

快速傅里叶变换FFT全流程解析,洛谷P3803 FFT多项式乘法

GoWilli的优快云 7545

Cocos Creator 3D音频定位实战:从原理到沉浸感实现

3D音频定位是游戏开发中实现沉浸感的关键技术,其核心原理基于HRTF(头部相关传输函数)模型,模拟声音在空间中的传播与双耳感知差异。这项技术通过赋予声音空间坐标、距离衰减和方向属性,将音频从背景元素提升为可交互的环境线索,极大增强了虚拟世界的真实感与玩家的空间认知。在工程实践中,开发者需要深入理解声源、听者、衰减曲线与多普勒效应等基础概念,并合理运用音频池、优先级管理与动态混音等技术手段来平衡效果与性能。对于Cocos Creator开发者而言,无论是使用引擎原生的AudioSource组件构建轻量级方案,

weixin_30972263的博客 291

FTT从入门到自闭

FTT从入门到自闭 0.基本定义 FFT全称(Fast Fourier Transformation) 中文名:快速傅里叶离散变换 作用是能以O(nlogn)O(nlogn)O(nlogn) 计算多项式乘法。 nnn​次多项式:$F(x)=axn+bx{n-1}+cx^{n-2}\dots $ F[i]F[i]F[i]​ 表示F(x)F(x)F(x)的iii次项系数。​ F(x)=∑i=0nF[i]xiF(x)=\sum\limits_{i=0}^n F[i]x^iF(x)=i=0∑n​F[i]xi​ 乘

Harris-H的博客 2475

手把手教你用WF100DPZ数字压力传感器搞定I2C/SPI通信(附完整寄存器解析)

本文详细解析了WF100DPZ数字压力传感器的I2C与SPI通信驱动方法,涵盖硬件连接、寄存器配置、数据读取流程及常见问题排查。该传感器内置24位ADC和出厂校准,通过实战代码演示了如何稳定获取高精度压力与温度数据,帮助开发者快速集成到嵌入式项目中。

weixin_28285943的博客 376

神联动:LSTM+卡尔曼滤波!一区大门轻松开!

近来热度飙升,成为时间序列预测和状态估计等领域的香饽饽,非常好发高区!主要在于:这两者结合,不仅能提高模型预测准确性;还能拓展应用场景,为我们的论文创新提供发挥空间,且当下还在蓝海阶段,还不算卷。具体点说:卡尔曼滤波擅长处理线性状态估计和噪声,能使LSTM更好地适应动态环境的变化,减少噪声干扰,降低预测误差。而LSTM通过捕捉长期依赖关系,擅长处理非线性时间序列,能够弥补卡尔曼滤波在这方面的不足,从而把应用场景从传统的状态估计,延伸到金融预测、工业检测、自动驾驶等任务。

2401_82426425的博客 2208

一文让你秒懂FFT(快速傅里叶变换)

一文带你领略傅里叶变换的魅力

S2191300319的博客 1万+

银河麒麟V10系统下VLC播放器安装全攻略(附3.0.9.2版本离线包下载)

本文详细介绍了在银河麒麟V10操作系统无网络环境下,从零开始编译安装VLC 3.0.9.2播放器的完整攻略。通过构建本地YUM仓库解决依赖问题,提供离线资源包下载,并逐步指导完成编译环境配置、软件编译与安装,帮助用户在国产麒麟系统上成功部署强大的多媒体播放能力。

a2b3c4d5e的博客 1199

快速傅里叶变换(FFT)求解多项式乘法

前提:这里是从数学和算法的角度理解FFT,不涉及信号处理背景知识 已知系数表达式求点值表达式 这里n是2的整数幂,不够要补零。 核心:就是我①式计算前面2/n部分的结果可以保留下来用于计算后面2/n部分②式的计算,这样的话就可以把每个区间每一次进行等分成两份,就可以分成logn次,每次需要计算n次(比如A1(x)公式你看里面最大那一项是),最后时间复杂度就是,这样我们就在时间内得到了点值表达式 这样就可以每计算一个值需要递归logn层,计算n个值所以在 时间内得到了点值表达式.

To be a better man 3166

YOLO26一文弄懂 | YOLO26内容详解、网络结构解读 、yolo26.yaml配置文件详细解读与说明、YOLO26虚拟环境安装、模型训练、验证、推理参数详细解析 | 通俗易懂!入门必看系列!

YOLO26目标检测模型创新与应用指南 本文全面介绍了YOLO26目标检测模型的创新特性、网络结构及实践应用。YOLO26基于四大核心原则设计:简洁性(移除NMS后处理)、部署效率(端到端架构)、训练创新(MuSGD优化器)和任务优化(支持多种视觉任务)。模型包含五种尺寸规格,CPU推理速度提升43%,支持目标检测、实例分割、姿态估计等任务。 文章详细解析了YOLO26的网络结构(Backbone-Neck-Head三部分)和yaml配置文件,提供了从虚拟环境配置到模型训练、验证、推理的完整教程。

Ai缝合怪、助力小伙伴高效发论文 2万+

利用 AI 自动生成 BDD(行为驱动开发)格式的 Gherkin 测试用例

文章摘要 当前BDD测试领域正经历AI驱动的变革浪潮。传统Gherkin用例编写面临四大痛点:语法负担重、场景发现成本高、一致性差和维护困难。2025-2026年,AI生成Gherkin的工具生态快速成熟,主要分为五类:测试管理平台内置AI(如TestRail 10.2)、Jira插件(如AssertThat BDD)、独立AI平台(如PrimeCompass)、CLI工具和研究原型。其中,TestRail实现生成-执行闭环,AssertThat采用多阶段Agent工作流提升质量,PrimeCompass则

ZXSXJ的博客 205

快速傅里叶变换(FFT)及其在多项式乘法中的应用 —— 深入分析与 Python 实现

单位根是指在复平面上均匀分布在单位圆上的点,满足 x^n = 1 的复数点。它们可以表示为:这些点的对称性和周期性使得我们可以通过分治法高效计算傅里叶变换。通过本文,我们深入探讨了如何利用快速傅里叶变换FFT进行高效的多项式乘法。我们从最基本的多项式操作出发,介绍了如何通过单位根和分治法将乘法复杂度从 O(n^2) 降低到 O(n log n)。我们还通过 Python 代码展示了 FFT 和 IFFT 的具体实现,并进行了多项式乘法的示例。FFT 在多项式乘法中的应用只是其众多用途之一。

qq_52010229的博客 2518

常用元器件使用方法3:电平转换芯片74LVC1T45的使用方法

介绍: 74LVC1T45是一个单位双向可控电平转换芯片。   芯片特性: 1、宽供给电压范围:1.65V到5.5V; 2、3.3V时,可输出24mA电流; 3、最大16uA电能损耗; 4、高噪音抑制;   型号:   引脚: VCC(A) 1 A端和DIR电源 GND 2 地 A 3 数据输入/输出 B 4 ...

snmplink的博客 1万+

快速傅里叶变换fft_快速傅里叶变换(FFT)求解多项式乘法

本篇笔记的目的是尽量通过简洁的方式说明FFT算法的过程,各种概念能不用就不用,也不涉及其物理意义,仅仅局限于算法这一块来讨论FFT求解多项式乘法,那么首先明确,多项式是什么,例如下面一个多项式: 这是一个n-1次多项式(最高次项是 ), 是它各项的系数,该多项式也可以写成以下形式: 不过无论是哪种形式,一个多项式都可以通过一组系数所确定,而这组系数所组成的向量也叫做系数向量(例如上面 的系数...

weixin_39754831的博客 2505

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

复数fft的时间复杂度_快速傅里叶变换(FFT)求解多项式乘法

本篇笔记的目的是尽量通过简洁的方式说明FFT算法的过程,各种概念能不用就不用,也不涉及其物理意义,仅仅局限于算法这一块来讨论FFT求解多项式乘法,那么首先明确,多项式是什么,例如下面一个多项式: 这是一个n-1次多项式(最高次项是 ), 是它各项的系数,该多项式也可以写成以下形式: 不过无论是哪种形式,一个多项式都可以通过一组系数所确定,而这组系数所组成的向量也叫做系数向量(例如上面 的系数...

weixin_39960700的博客 840

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

多项式乘法之FFT快速傅里叶变换

写在前面的话: 快速傅里叶应用于多项式,来加速多项式乘法使其复杂度从o()变成o(n()),好了先一步步来,这个算法确实很难,但也不是完全理解不了,只是方式不对。 首先,正常的多项式相乘是: A[n]=+x+++~~+,B[n]=~~; C=A[n]*B[n]=~~ 正常肯定因为这个应该不能再被简化了,但是没有绝对的最简,人们觉得这个复杂度太高,没有艺术美,于是FFT诞生了,多项式再是局...

timeruler的博客 2587

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

fft从多项式乘法到快速傅里叶变换 -二进制反转的分析

fft从多项式乘法到快速傅里叶变换原理可以看下面链接的博文,讲的很好。 http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transform#comment-57922 其中有关为什么要二进制反转有另一种理解方法: 对于上述博文的到的公式: 时: ...

fire_lch316的博客 969

从多项式乘法到FFT:图解快速傅里叶变换的数学之美

本文深入解析了快速傅里叶变换(FFT)的数学原理及其在多项式乘法中的革命性应用。通过图解和算法实现,展示了FFT如何将计算复杂度从O(n²)降至O(n log n),并介绍了逆快速傅立叶变换(IFFT)的关键作用。这些技术在数字信号处理、图像压缩等领域具有广泛应用价值。

quiet的专栏 600

【Learning】多项式乘法与快速傅里叶变换(FFT)

简介:   FFT主要运用于快速卷积,其中一个例子就是如何将两个多项式相乘,或者高精度乘高精度的操作。   显然暴搞是$O(n^2)$的复杂度,然而FFT可以将其将为$O(n lg n)$。   这看起来十分玄学,因为怎么看它们的相乘操作都逃不过$O(n^2)$,FFT是如何再减少复杂度的呢?   讲到FFT就不可避免地出现公式,但实际上它们都是比较容易理解的。    全局思路 ...

weixin_30617797的博客 228

多项式乘法 快速傅里叶变换FFT

简要记录FFT实现原理

上总介的博客 1222

突破多项式乘法瓶颈:OI Wiki快速傅里叶变换(FFT)实战指南

快速傅里叶变换(FFT)是OI领域中处理多项式乘法的核心算法,能将传统O(n²)复杂度优化至O(n log n),彻底突破大规模数据运算的效率瓶颈。本文基于OI Wiki项目[docs/math/poly/fft.md](https://link.gitcode.com/i/a7fa64723a0980ed351c494357e89a21)的权威内容,为你系统讲解FFT的原理、实现与应用。 ##

gitblog_00141的博客 705

FFT与多项式乘法

鉴于网上关于FFT作用的文章并不少,这里尽量少说废话,直接说如何理解和具体实现FFT计算多项式乘法和大整数乘法

Leo_h 1万+

超详细易懂FFT(快速傅里叶变换)及代码实现

前言 昨天学了一晚上,终于搞懂了FFT。希望能写一篇清楚易懂的题解分享给大家,也进一步加深自己的理解。 FFT算是数论中比较重要的东西,听起来就很高深的亚子。但其实学会了(哪怕并不能完全理解),会实现代码,并知道怎么灵活运用 (背板子) 就行。接下来进入正题。 定义 FFT(Fast Fourier Transformation),中文名快速傅里叶变换,是离散傅氏变换的快速算法,它是根据离散傅氏变...

Flag_z的博客 25万+

快速高精度乘法C语言fft,快速傅里叶变换(FFT)与多项式乘法学习笔记 | Bill Yang's Blog...

本文章基于Menci’s Blog进行补充,原文已经讲述得很清楚,有数学基础的同学可以直接看原文。快速傅里叶变换(Fast Fourier Transform,简称FFT),可以在$O(n\log n)$时间内完成离散傅里叶变换(Discrete Fourier Transform,简称DFT),是在数论中常用的加速多项式乘法的计算,常用于快速计算卷积。定义多项式我们将一个多项式$\sum\lim...

weixin_30325875的博客 1145
上一篇: 莫比乌斯反演
peter_code
博客等级 码龄5年 41粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值