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

多项式算法1:FFT(快速傅里叶变换) FFT(快速傅里叶变换)算法详解 阅读详情

参考:《算法导论》第 30 章 多项式与快速傅里叶变换

《华章数学译丛-抽象代数基础教程.(美国)Rotman》第 1 章 数论

http://blog.youkuaiyun.com/liangzhaoyang1/article/details/52769839

《叉姐的FFT讲义》


一、概述

两个多项式相乘的简单方法所需的时间为 O(n ^ 2)

快速傅里叶变换(Fast Fourier Transform,FFT)方法可以使多项式相乘的运行时间降低为 O(logn)


二、

1、多项式

关于变量 x 的多项式定义为形式和形式表示的函数 A(x):







2、多项式的系数表示法


3、多项式的点值表示法



3、插值



三、系数形式表示的多项式的快速乘法



四、DFT 与 FFT
















#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define PI acos(-1.0)

const int maxn = 3e5 + 10;

struct Complex {
    double x, y;
    Complex(double _x = 0.0, double _y = 0.0) { x = _x; y = _y; }
    Complex operator - (const Complex &b) const { return Complex(x - b.x, y - b.y); }
    Complex operator + (const Complex &b) const { return Complex(x + b.x, y + b.y); }
    Complex operator * (const Complex &b) const { return Complex(x * b.x - y * b.y, x * b.y + y * b.x); }
};

int poly_A[maxn / 3], poly_B[maxn / 3];
Complex A[maxn], B[maxn], ans_mul[maxn];
int N, M, n = 1;

Complex* fft(Complex a[], int len, int oper);

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d %d", &N, &M);
    REP(i, N + 1) { scanf("%d", &poly_A[i]); }
    REP(i, M + 1) { scanf("%d", &poly_B[i]); }
    while (n < N + M + 2) { n <<= 1; }
    REP(i, N + 1) { A[i] = poly_A[i]; }
    for (int i = N + 1; i < n; ++i) { A[i] = 0; }
    REP(i, M + 1) { B[i] = poly_B[i]; }
    for (int i = M + 1; i < n; ++i) { B[i] = 0; }
    Complex *ans_A = new Complex[n], *ans_B = new Complex[n], *ans = new Complex(n);
    ans_A = fft(A, n, 1); ans_B = fft(B, n, 1);
    REP(i, n) { ans_mul[i] = ans_A[i] * ans_B[i]; }
    ans = fft(ans_mul, n, -1);
    REP(i, n) { ans[i].x /= n; ans[i].y /= n; }
    REP(i, N + M ) { printf("%.0f ", fabs(ans[i].x)); } printf("%.0f\n", fabs(ans[N + M].x));
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}

Complex* fft(Complex a[], int len, int oper) {
    if (len == 1) { return a; }
    Complex omega_n = Complex(cos(oper * 2.0 * PI / len), sin(oper * 2.0 * PI / len));
    Complex omega = Complex(1, 0);
    Complex* a_0 = new Complex[len >> 1];
    Complex* a_1 = new Complex[len >> 1];
    REP(i, len) { (i & 1) ? (a_1[(i - 1) >> 1] = a[i]) : (a_0[i >> 1] = a[i]); }
    Complex *y_0, *y_1;
    y_0 = fft(a_0, len >> 1, oper); y_1 = fft(a_1, len >> 1, oper);
    Complex* y = new Complex[len];
    for (int i = 0; i < (len >> 1); ++i) {
        y[i] = y_0[i] + omega * y_1[i];
        y[i + (len >> 1)] = y_0[i] - omega * y_1[i];
        omega = omega * omega_n;
    }
    return y;
}







UOJ #34. 多项式乘法

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>

using namespace std;

#define REP(i, n) for (int i = 0; i < (n); ++i)
#define PI acos(-1.0)

const int maxn = 3e5 + 10;

struct Complex {
    double x, y;
    Complex(double _x = 0.0, double _y = 0.0) { x = _x; y = _y; }
    Complex operator - (const Complex &b) const { return Complex(x - b.x, y - b.y); }
    Complex operator + (const Complex &b) const { return Complex(x + b.x, y + b.y); }
    Complex operator * (const Complex &b) const { return Complex(x * b.x - y * b.y, x * b.y + y * b.x); }
};

int poly_A[maxn / 3], poly_B[maxn / 3];
Complex A[maxn], B[maxn], ans[maxn];
int N, M, n = 1;

void fft(Complex a[], int len, int oper);

int main() {
#ifdef __AiR_H
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif // __AiR_H
    scanf("%d %d", &N, &M);
    REP(i, N + 1) { scanf("%d", &poly_A[i]); }
    REP(i, M + 1) { scanf("%d", &poly_B[i]); }
    while (n < N + M + 2) { n <<= 1; }
    REP(i, N + 1) { A[i] = poly_A[i]; }
    for (int i = N + 1; i < n; ++i) { A[i] = 0; }
    REP(i, M + 1) { B[i] = poly_B[i]; }
    for (int i = M + 1; i < n; ++i) { B[i] = 0; }
    fft(A, n, 1); fft(B, n, 1);
    REP(i, n) { ans[i] = A[i] * B[i]; }
    fft(ans, n, -1);
    REP(i, N + M) { printf("%.0f ", fabs(ans[i].x)); } printf("%.0f\n", fabs(ans[N + M].x));
#ifdef __AiR_H
    printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
    return 0;
}

void fft(Complex a[], int len, int oper) {
    for (int i = 1, j = 0; i < len - 1; ++i) {
        for (int s = len; ~j & s;) { j ^= s >>= 1; }
        if (i < j) { swap(a[i], a[j]); }
    }
    Complex omega_m, omega, t, u;
    int m, m2;
    for (int d = 0; (1 << d) < len; ++d) {
        m = (1 << d); m2 = m << 1;
        omega_m = Complex(cos(PI / m * oper), sin(PI / m * oper));
        for (int i = 0; i < len; i += m2) {
            omega = Complex(1, 0);
            for (int j = 0; j < m; ++j) {
                u = a[i + j]; t = omega * a[i + j + m];
                a[i + j] = u + t; a[i + j + m] = u - t;
                omega = omega * omega_m;
            }
        }
    }
    if (oper == -1) { REP(i, N + M + 1) { a[i].x /= len; } }
}




《算法导论》第 30 章:多项式与快速傅里叶变换(FFT) 本文深入讲解了多项式与快速傅里叶变换(FFT)的核心内容。FFT通过将时间复杂度从O(n²)降至O(nlogn),极大提升了多项式乘法的效率。文章首先对比了多项式的两种表示法(系数表示和点值表示),详细解析了离散傅里叶变换(DFT)的原理,并重点介绍了FFT的分治优化策略。通过递归和迭代两种实现方式,配合完整的C++代码示例,展示了如何用FFT高效计算多项式乘法。最后还探讨了FFT的并行化思路和实际应用场景。全文逻辑清晰,理论与实践结合,帮助读者透彻理解这一重要算法。 阅读详情

相关推荐

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

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

DevScript的博客 291

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

计算两个n次多项式相乘的最直接方法所需的时间为Θ(n2)\Theta(n^2)Θ(n2),在本文中,我们将讨论快速傅里叶变换(FFT),使得多项式相乘的时间复杂度降为Θ(nlgn)\Theta(nlgn)Θ(nlgn)。 一、多项式的表示 系数表示和点值表示 对于一个次数界为n的多项式A(x)=∑j=0n−1ajxjA(x)=\sum_{j=0}^{n-1}a_{j}x^jA(x)=∑j=0n−1​aj​xj而言,其系数表示是一个由系数组成的向量a=(a0,a1,...,an−1)a=(a_{0},a_{1

m0_73633144的博客 1404

使用 Cholesky 对多项式进行频谱分解:一种对 rho 进行频谱分解的简单方法。 aa*+bqb* 其中 a 和 b 是 dd* 或 reps.dn.dn* 的多项式,其中 reps 是常数。-matlab开发

这对于优化控制或优化过滤问题很有用 使用Cholesky分解进行频谱分解dc.dc*=aarho+bb*.q dcn 是归一化频谱因子使用 Toeplitz 矩阵方法TJMoir 2019 年 12 月我们需要两个多项式 b/a 就像在 ARMAX 方法中一样进行控制。 b 多项式中不包含延迟 - 重要让 m 远大于 a 或 b 多项式长度,例如 12 请注意,如果 q=0,则 a 返回为光谱因子不变(不是其在 z 平面中的镜像)。 Matlab自己使用了Cholesky因式分解程序,但这是将其应用于多项式频谱因式分解的一种方法。

多项式快速幂——快速傅里叶变换

快速傅里叶变换实现

lxz6527的博客 1134

MATLAB联合Fluent优化仿真

matlab与fluent交互

keleke_的博客 4724

LSF0108 level shift设计使用及debug流程

目录 初版设计 测试出现的问题1 解决问题(尝试1) 测试出现的问题2 解决问题2-1 解决问题2-2 单Port测试结果 所有Port均连接测试结果 初版设计 此电路的应用场景在于将LCD屏幕连接到FPGA上,进而通过FPGA中设计的硬件电路来驱动LCD屏幕,验证数字硬件电路设计的正确性。因此需要一个转接板位于FPGA和LCD屏幕之间,将二者连接起来。 转接板的硬件电路设计主要存在以下需求: 实现3.3V和1.8V之间的同时双向逻辑转换(LCD屏幕电平为3.3V,FPGA电平为1.

moshanghongfeng的博客 7562

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

多项式算法——快速傅里叶变换FFT 目录多项式算法——快速傅里叶变换FFT多项式多项式加法多项式乘法多项式表示法系数表示点值表示DFT与FFT单位负数根 两个多项式函数相加的时间复杂度为O(n)O(n)O(n),而相乘的时间复杂度为O(n2)O(n^2)O(n2),即所有系数的笛卡尔积。傅里叶变换DFT将优化多项式相乘(以下简称卷积),而快速傅里叶变换则优化至O(nlg⁡n)O(n \lg n)O(nlgn)。 多项式 本章定义的多项式函数为定义在实数域上,关于变量xxx形如: A(x)=∑j=0n−1aj

jiahonghao2002的博客 1030

vislib_vex5:面向VEX V5的嵌入式视觉处理库

嵌入式视觉处理是机器人实时感知的核心能力,其本质是在资源受限环境下实现图像采集、色彩转换、阈值分割与目标定位的确定性流水线。原理上依赖硬件加速(如DMA2D)、定点运算优化与中断协同机制,以规避浮点开销和动态内存分配。技术价值在于提供亚毫秒级、无RTOS依赖、低延迟可预测的视觉基础能力,显著提升教育及竞赛机器人在动态场景下的响应鲁棒性。典型应用场景包括色块跟踪、目标居中控制、自动导航中的简易视觉伺服等。本文聚焦于专为VEX V5主控(STM32H743+图像协处理器)深度优化的轻量库vislib_vex5,

weixin_31185473的博客 606

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

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

GoWilli的优快云 7545

CentOS Stream 9中安装MySQL的详细步骤

本文详细介绍了在CentOS Stream 9系统中如何进行MySQL的在线安装、离线安装以及忘记密码的恢复操作。通过阅读本文,您将能够了解并掌握在CentOS Stream 9上安装MySQL的步骤,以及在遇到忘记密码的情况下的解决方案。

小白典的博客 7258

A Mathematical Framework for Transformer Circuits—(一)

transformer数学理解理论

qq_42208244的博客 2661

【多项式】快速傅里叶变换(FFT)

FFT通过分治法将DFT的O(N²)复杂度降至O(N log N),核心是蝶形运算与位逆序重排,广泛应用于信号处理、多项式乘法等领域。

zhangmohan123321的博客 1861

超简单五步实现VOS3000客户端呼入配置

1.查看SIP代理  在注册管理中查看自己线路注册的SIP代理IP地址,记录下来。 2.创建普通账户  创建一个呼入使用的普通账号,选择“计费费率”,根据自己情况选择费率,这里做测试就配置了免费的费率,如果费率不是免费,需要给这个普通账户充值。 3.新建对接网关 新建一个对接网关,点击该网关的“补充设置”,选择“网关类型”为静态IP,然后在IP地址栏填上刚才在注册管理里面记录的SIP代...

非著名运维的博客 1万+

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

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

weixin_39754831的博客 2505

大数据NiFi(十一):NiFi入门案例一

注意:数据写出的目录可以不需要提前在对应节点上创建,默认是可以自动创建,可以通过“Create Missing Directories”属性配置。将输出文件的权限设置为此属性的值,格式必须是UNIX rwxrwxrwx,用-来代替被拒绝的权限(例如rw-r--r--)或八进制数字(例如644),可以使用表达式,例如${file.permissions}。这里需要使用到的处理器是“GetFile”和“PutFile”,完成以上需求对“GetFile”和“PutFile”相关属性进行配置。

Lansonli(蓝深李)的博客 1489

(一)深入理解Bluez协议栈之蓝牙Mesh的支持(1/5)

BlueZ是Linux官方蓝牙协议栈。它是一个基于GNU General Public License (GPL)发布的开源项目,从Linux 2.4.6开始便成为Linux 内核的一部分。如果你是linux平台开发蓝牙的的工程师,肯定会接触过Bluez协议栈,hciconfig,hciattach,hciconfig等工具都是很好用的工具。

3321

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

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

To be a better man 3166

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

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

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

qq_52010229的博客 2518

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

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

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

快速计算多项式相乘系数 FFT快速傅里叶变换

2.怎么将点值表达法变回系数。1.怎么快速得到n+1个点。

xxcdsg的博客 726

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

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

weixin_39960700的博客 841

快速傅里叶变换(FFT)与多项式算法学习笔记

参考资料:menci的博客 前言: 最近在学习生成函数,无奈的发现如果我不学习\(O(nlogn)\)的多项式算法的话什么题也做不了qwq 于是就滚来学习FFT了 其实写的很烂,主要是给自己看的 好像整个机房就我不会这玩意了 定义 多项式 形如\(F(x)=\sum\limits_{i=0}^na_ix^i\)的柿子就是一个多项式,这个多项式的次数就是它的最高次数\(n\) 多项式的表示...

763

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

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

timeruler的博客 2587

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

简要记录FFT实现原理

上总介的博客 1222

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

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

fire_lch316的博客 969

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

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

weixin_30617797的博客 228
上一篇: Shell 脚本
下一篇: 初等数论——整数的分解
__AiR_H
博客等级 码龄11年 29粉丝 151原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值