FFT求多项式乘积

news2024/10/5 13:10:42

之前在b站上看到了一些介绍FFT的视频

《快速傅里叶变换(FFT)——有史以来最巧妙的算法?》
《这个算法改变了世界》

于是打算写一篇记录一下qwq(本博客中的截图基本上来源于第一个视频)

Fast Fourier Transform 是一种能在 O ( n l o g n ) O(nlogn) O(nlogn)的时间内将一个用系数表示的多项式转化成点值表示。

P ( x ) = p 0 + p 1 x + p 2 x 2 + . . . + p d x d P(x)=p_0+p_1x+p_2x^2+...+p_dx^d P(x)=p0+p1x+p2x2+...+pdxd

系数表示法: [ p 0 , p 1 , p 2 , . . . , p d ] [p_0,p_1,p_2,...,p_d] [p0,p1,p2,...,pd]
点值表示法: ( x 0 , P ( x 0 ) , ( x 1 , P ( x 1 ) , . . . , ( x d , P ( x d ) ) {(x_0,P(x_0),(x_1,P(x_1),...,(x_d,P(x_d))} (x0,P(x0),(x1,P(x1),...,(xd,P(xd))

(n+1个不同点可以确定一个n次的多项式:可以用矩阵列式求解)

当我们试图算两个多项式相乘的结果:

A ( x ) = a 0 + a 1 x + . . . + a d x d A(x)=a_0+a_1x+...+a_dx^d A(x)=a0+a1x+...+adxd
B ( x ) = b 0 + b 1 x + . . . + b d x d B(x)=b_0+b_1x+...+b_dx^d B(x)=b0+b1x+...+bdxd

传统的做法需要 O ( n 2 ) O(n^2) O(n2),而如果我们先求出若干个点的坐标(多少个点根据最后算出的会是几次多项式而定,比如A是三次多项式,B是五次多项式,算出来的C会是八次多项式,那么就需要找九个点),最后再根据这些点把多项式还原成系数表示,但是对于每个点,知道一个横坐标,需要(d+1)次计算才能知道这个点的纵坐标,总复杂度还是会达到 O ( n 2 ) O(n^2) O(n2),达咩。

主要过程

可不可以通过选取一些巧妙的点来减少我们的计算次数?
划分
我们可以每次将多项式分成奇项和偶项,通过这样的划分可以便捷地算出横坐标互为相反数的一对点对的坐标,此时我们需要求出 x 2 x^2 x2分别代入 P e ( x 2 ) P_e(x^2) Pe(x2) P o ( x 2 ) P_o(x^2) Po(x2)算出来的值,原问题变成了两个子问题,每个子问题的次数是原问题的 1 / 2 1/2 1/2。我们想着能不能一直这么递归下去,直到分到底层(次数为1),再自底向上,层层归并求出答案?
递归
实际上在递归步骤,我们假设了每个多项式我们都使用相反数对来求值,然而对两个子问题而言,每个求值点都是平方数,没办法继续了(悲.jpg)于是我们希望把新的求值点也弄成相反数对QAQ

(P.S.为了方便讨论,下文的n均为2的整数次幂,如果题目的n不是2的整数次幂,我们可以加一波操作~)

于是——复数大法好!
四次方根
按照上面的逻辑推演,再向下递归一层我们需要两个相反点对,即要求出 x 4 = 1 x^4=1 x4=1的四个解;
八次方根
再向下递归一层我们需要四个相反点对,即要求出 x 8 = 1 x^8=1 x8=1的八个解;
现在推广到d阶多项式,我们要先取n>d个点,(并且n等于2的整数次幂),我们为求解多项式乘积所选取的点就是1的n个n次方根。
单位根
在这里插入图片描述

单位根的性质:

性质一: ω 2 n 2 k = ω n k ω^{2k}_{2n}=ω^{k}_n ω2n2k=ωnk

性质二: ω n k + n / 2 = − ω n k ω^{k+n/2}_n=−ω^k_n ωnk+n/2=ωnk(对应的点关于原点对称)

快速傅里叶变换的数学证明

A ( x ) = a 0 + a 1 x + a 2 x 2 + . . . + a n − 1 x n − 1 A(x) = a_0 + a_1x + a_2x^2 +...+a_{n-1}x^{n-1} A(x)=a0+a1x+a2x2+...+an1xn1,为求离散傅里叶变换,要把一个 x = ω n k x = \omega_n^k x=ωnk代入。

考虑将 A ( x ) A(x) A(x)的每一项按照下标的奇偶分成两部分:

A ( x ) = ( a 0 + a 2 x 2 + . . . + a n − 2 x n − 2 ) + ( a 1 x + a 3 x 3 + . . . + a n − 1 x n − 1 ) A(x) = (a_0 + a_2x^2 + ... + a_{n - 2}x^{n - 2}) + (a_1x + a_3x^3 + ... + a_{n-1}x^{n-1}) A(x)=(a0+a2x2+...+an2xn2)+(a1x+a3x3+...+an1xn1)

设两个多项式:
A 1 ( x ) = a 0 + a 2 x + . . . + a n − 2 x n 2 − 1 A_1(x) = a_0 + a_2x + ... + a_{n - 2}x^{\frac{n}{2} - 1} A1(x)=a0+a2x+...+an2x2n1
A 2 ( x ) = a 1 + a 3 x + . . . + a n − 1 x n 2 − 1 A_2(x) = a_1 + a_3x + ... + a_{n - 1}x^{\frac{n}{2} - 1} A2(x)=a1+a3x+...+an1x2n1
则: A ( x ) = A 1 ( x 2 ) + x A 2 ( x 2 ) A(x) = A_1(x^2) + xA_2(x^2) A(x)=A1(x2)+xA2(x2)

假设 k < n 2 k < \frac{n}{2} k<2n,现要把 x = ω n k x = \omega_n^k x=ωnk代入,

A ( ω n k ) = A 1 ( ω n 2 k ) + ω n k A 2 ( ω n 2 k ) = A 1 ( ω n 2 k ) + ω n k A 2 ( ω n 2 k ) \begin{align*} A(\omega_n^k) &= A_1(\omega_n^{2k}) + \omega_n^kA_2(\omega_n^{2k}) \\ &= A_1(\omega_{\frac{n}{2}}^{k}) + \omega_n^kA_2(\omega_{\frac{n}{2}}^{k}) \end{align*} A(ωnk)=A1(ωn2k)+ωnkA2(ωn2k)=A1(ω2nk)+ωnkA2(ω2nk)
那么对于 A ( ω n k + n 2 ) A(\omega_n^{k + \frac{n}{2}}) A(ωnk+2n):
A ( ω n k + n 2 ) = A 1 ( ω n 2 k + n ) + ω n k + n 2 A 2 ( ω n 2 k + n ) = A 1 ( ω n 2 k × ω n n ) + ω n k + n 2 A 2 ( ω n 2 k × ω n n ) = A 1 ( ω n 2 k ) − ω n k A 2 ( ω n 2 k ) \begin{align*} A(\omega_n^{k + \frac{n}{2}}) &= A_1(\omega_n^{2k + n}) + \omega_n^{k + \frac{n}{2}}A_2(\omega_n^{2k + n}) \\ &= A_1(\omega_{\frac{n}{2}}^{k} \times \omega_n^n) + \omega_n^{k + \frac{n}{2}} A_2(\omega_{\frac{n}{2}}^{k} \times \omega_n^n) \\ &= A_1(\omega_{\frac{n}{2}}^{k}) - \omega_n^kA_2(\omega_{\frac{n}{2}}^{k}) \end{align*} A(ωnk+2n)=A1(ωn2k+n)+ωnk+2nA2(ωn2k+n)=A1(ω2nk×ωnn)+ωnk+2nA2(ω2nk×ωnn)=A1(ω2nk)ωnkA2(ω2nk)

所以,如果我们知道两个多项式 A 1 ( x ) A_1(x) A1(x) A 2 ( x ) A_2(x) A2(x)分别在 ( ω n 2 0 , ω n 2 1 , ω n 2 2 , . . . , ω n 2 n 2 − 1 ) (\omega_{\frac{n}{2}}^{0}, \omega_{\frac{n}{2}}^{1}, \omega_{\frac{n}{2}}^{2}, ... , \omega_{\frac{n}{2}}^{\frac{n}{2} - 1}) (ω2n0,ω2n1,ω2n2,...,ω2n2n1)的值,就可以求出 A ( x ) A(x) A(x) ω n 0 , ω n 1 , ω n 2 , . . . , ω n n − 1 \omega_n^0, \omega_n^1, \omega_n^2, ..., \omega_n^{n-1} ωn0,ωn1,ωn2,...,ωnn1处的值了, A 1 ( x ) A_1(x) A1(x) A 2 ( x ) A_2(x) A2(x)是规模缩小一半的子问题,分治边界 n = 1 n=1 n=1.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现在我们有了这若干个点的纵坐标,问题来到如何根据这些点的坐标还原答案多项式的系数,这需要用到IFFT(Inverse Fast Fourier Transform)

结论:把多项式 A ( x ) A(x) A(x)的离散傅里叶变换结果作为另一个多项式 B ( x ) B(x) B(x)的系数,取单位根的倒数即 ω n 0 , ω n − 1 , ω n − 2 , . . . , ω n − ( n − 1 ) \omega_{n}^{0}, \omega_{n}^{-1}, \omega_{n}^{-2}, ..., \omega_{n}^{-(n - 1)} ωn0,ωn1,ωn2,...,ωn(n1)作为 x x x代入 B ( x ) B(x) B(x),得到的每个数再除以 n n n,得到的是 A ( x ) A(x) A(x)的各项系数。
在这里插入图片描述

参考资料: 小学生都能看懂的FFT!!!
《快速傅里叶变换(FFT)——有史以来最巧妙的算法?》

代码:咕咕,回头补

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/115300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业营销数字化转型:如何转型、如何选品、如何用好?

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2022年11月份热门报告盘点2023年&#xff0c;如何科学制定年度规划&#xff1f;《底层逻辑》高清配图清华大学256页PPT元宇宙研究报告.pdf&#xff08;附下载链接&#xff09;…

【LeetCode】1759. 统计同构子字符串的数目

统计同构子字符串的数目 题目描述 给你一个字符串 s &#xff0c;返回 s 中 同构子字符串 的数目。由于答案可能很大&#xff0c;只需返回对 109 7 取余 后的结果。 同构字符串 的定义为&#xff1a;如果一个字符串中的所有字符都相同&#xff0c;那么该字符串就是同构字符串…

自定义报表-FineReport JS实现隐藏Tab页

1. 概述 1.1 问题描述 在实际项目中&#xff0c;使用决策报表的时候&#xff0c;有时会用到在决策报表参数面板获取报表控件的值&#xff0c;那么该如何实现呢&#xff1f; 1.2 实现思路 使用 JS 获取报表主体的控件值&#xff1a; _g().getWidgetByName("area").…

【金猿人物展】数睿数据创始人兼CEO穆鸿:大数据价值创造关键在于应用普惠...

‍穆鸿本文由数睿数据创始人兼CEO穆鸿撰写并投递参与“数据猿年度金猿策划活动——2022大数据产业趋势人物榜单及奖项”评选。‍数据智能产业创新服务媒体——聚焦数智 改变商业事情还得从我2022年这一年经历的一些事情谈起&#xff0c;由于工作的原因&#xff0c;我要经常往返…

Python量化交易04——基于机器学习的交易策略

参考书目:深入浅出Python量化交易实战 学量化肯定要用的上机器学习这种强大的预测技术。本次使用机器学习构建一些简单的预测进行量化交易&#xff0c;使用Python进行回测。 获取数据 import pandas as pd import tushare as ts import numpy as npfrom sklearn.neighbors imp…

线程池设计与实现C

线程池实现 结构设计 先上图&#xff1a; 参数 线程池&#xff1a; 包含一个执行队列、一个任务队列mutex用来在多个线程取任务时锁任务队列&#xff0c;cond用来在任务队列为空时锁任务队列 如线程A锁了任务队列&#xff0c;去取任务时&#xff0c;又发现任务队列为空&…

【C++求解数学题】大圆圈里面三角形个数相等

本文介绍的问题是一道来自于二年级&#xff08;上&#xff09;数学的练习题。 问题 在下图中画8个Δ\DeltaΔ,使每个大圆圈里都有4个Δ\DeltaΔ. 示例&#xff1a; 每个大圆圈里面均有4个Δ\DeltaΔ. 方法 按照“变量-范围-条件”的三段式穷举法解题框架&#xff0c;对…

分布式系列之聊聊Nginx实现原理

Nginx作为开源的轻量级的HTTP服务器&#xff0c;广泛应用于分布式应用架构中。本文简要介绍了Nginx的特点及使用场景、Nginx的进程模型和请求处理流程&#xff0c;并结合不同场景进行配置&#xff0c;对Nginx的架构和实现原理有个初步的了解。 1、Nginx是什么 Nginx&#xff0…

Echarts之甘特图type: ‘custom‘参数详解

甘特图 const groupData XEUtils.groupBy(data, "eqpName"); //分组后的数据 const yAxisData Object.keys(groupData); const seriesData Object.keys(groupData).map((item, index) > {let arr [];groupData[item].forEach((GItem) > {arr.push([index,f…

Graphviz安装向导及入门指南

目录 1、首先在官网下载graphviz 2、安装。 3、测试并在Windows命令行中使用 4、在Python中使用 5、在自带的gvedit.exe 程序中使用 6、在语雀中使用 7、绘制一棵简单的二叉树 8、详细语法介绍 8.1 带标签 8.2 修改方框颜色和形状 8.3子视图 8.4 结构视图 8.5 …

【网络安全】Centos7安装杀毒软件----ClamAV

一、ClamAV介绍 Clam AntiVirus是一个Linux系统上使用的反病毒软件包。主要应用于邮件服务器&#xff0c;采用多线程后台操作&#xff0c;可以自动升级病毒库。 二、安装 1.下载rpm wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 2.升级epe…

4.1、网络层概述

1、主要任务 网络层的主要任务是实现网络互连\color{red}实现网络互连实现网络互连&#xff0c;进而实现数据包在各网路之间的传输\color{red}实现数据包在各网路之间的传输实现数据包在各网路之间的传输 例如&#xff1a; 这些异构型网络若只是需要各自内部通信&#xff0c…

高质量发展指标构建:全国各省高质量发展需求(2014-2021年)

高质量发展是坚持更高层次和更高水平对外开放的发展。中国改革开放四十年的实践充分证明&#xff0c;不断扩大对外开放是推动中国经济社会发展的重要动力&#xff0c;是实现国家繁荣富强的根本出路。因此&#xff0c;在中国经济发展的新时代&#xff0c;推动新一轮高水平开放&a…

docker logs实时查看日志tail

docker logs实时查看日志tail docker logs -f -t --since="2017-05-31" --tail=10 container说明: --since : 指定输出日志开始日期。 -f : 查看实时日志 -t : 查看日志产生的时间戳 -tail=10 : 查看最后的10条日志。 container : 容器名docker logs -f --until=2s说…

Docker常用操作命令总结(一)

文章目录一、Docker的应用场景二、Docker 的优点三、Docker 架构四、安装Docker1、更新 apt 包索引2、安装docker3、安装完成之后&#xff0c;运行命令sudo docker info&#xff0c;检查安装状态4、有可能&#xff0c;第一次需要手动启动服务.就需要执行下面的命令&#xff0c;…

LabVIEW如何减少下一代测试系统中的硬件过时4

LabVIEW如何减少下一代测试系统中的硬件过时4 DSSP Class Definition DSSP父类定义有三种不同类型的函数:仅父类、公共类和基于度量的函数。DSSP父类&#xff0c;DSSP.Lvclass包含所有子类函数的超集&#xff0c;加上父类特有的一些函数。DSSP父类的单个子实例(例如AgSigGen.…

2022年总结(2022年1月1日至2022年12月25日)

前言 时光飞逝&#xff0c;又到了一年一度的年终总结的时间了&#xff0c;2022年充满磨难的一年&#xff0c;悲哉&#xff0c;痛哉~~ 但对于我而言&#xff0c;其实还好&#xff0c;基本无太大影响&#xff0c;黄金单身汉&#xff0c;一人吃饱&#xff0c;全家不饿~&#xff…

spring之手写框架

文章目录前言一、手写spring框架之核心接口实现二、手写spring框架之实例化Bean三、手写spring框架之获取所有set方法四、手写spring框架之给属性赋值4.1 非简单类型属性赋值4.2 简单类型属性赋值附&#xff1a;前言 Spring IoC容器的实现原理&#xff1a;工厂模式解析XML反射…

学习性能所必须的知识之算法

什么是算法? 通过有效地缩小查找范围,只需要很少的次数就能很快速的找到需要的数字,这样的策略或方法就称为“算法”。 算法的好坏对性能有很大的影响。 学习算法的窍门 掌握算法优点与缺陷,“折中”是一个很重要的思维通过在图上推演来思考评价算法的指标 通过复杂度(…

各种型号西门子PLC所支持的通信协议小结

西门子PLC有4大类&#xff0c;几十个型号类型&#xff0c;PLC不同所支持的通讯协议也不相同。 按照大类型来划分&#xff0c;具体可分为串口协议和以太网通信协议两大类。 串口协议主要有&#xff1a;MODBUS RTU 通信协议&#xff1b;PROFIBUS 通信协议&#xff1b;USS通信协…