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

news2025/2/23 22:10:15

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

快速傅里叶变换(FFT)——有史以来最巧妙的算法?

正常求两个多项式乘积

A ( x ) = ∑ i = 0 n A i x i , B ( x ) = ∑ i = 0 n B i x i C ( x ) = ∑ i = 0 n ∑ j = 0 n A i B j x i + j A(x)=\sum_{i=0}^{n}{A_ix^i},B(x)=\sum_{i=0}^{n}{B_ix^i} \\ C(x)=\sum_{i=0}^{n}\sum_{j=0}^nA_iB_jx^{i+j} A(x)=i=0nAixi,B(x)=i=0nBixiC(x)=i=0nj=0nAiBjxi+j

复杂度为 O ( n 2 ) O(n^2) O(n2)

分别设n+1个在A与B上的点

根据高斯消元法,n+1个不同的点一定能确定一个唯一的n次多项式

A ( x ) = { ( x 0 , A ( x 0 ) ) , ( x 1 , A ( x 1 ) ) , ( x 2 , A ( x 2 ) ) . . . ( x n , A ( x n ) ) } B ( x ) = { ( x 0 , B ( x 0 ) ) , ( x 1 , B ( x 1 ) ) , ( x 2 , B ( x 2 ) ) . . . ( x n , B ( x n ) ) } A(x)=\{(x_0,A(x_0)),(x_1,A(x_1)),(x_2,A(x_2))...(x_n,A(x_n))\}\\ B(x)=\{(x_0,B(x_0)),(x_1,B(x_1)),(x_2,B(x_2))...(x_n,B(x_n))\}\\ A(x)={(x0,A(x0)),(x1,A(x1)),(x2,A(x2))...(xn,A(xn))}B(x)={(x0,B(x0)),(x1,B(x1)),(x2,B(x2))...(xn,B(xn))}

横坐标相同的点相乘

C ( x ) = { ( x 0 , A ( x 0 ) B ( x 0 ) ) , ( x 1 , A ( x 1 ) B ( x 1 ) ) . . . ( x n , A ( x n ) B ( x n ) ) } C(x)=\{(x_0,A(x_0)B(x_0)),(x_1,A(x_1)B(x_1))...(x_n,A(x_n)B(x_n))\} C(x)={(x0,A(x0)B(x0)),(x1,A(x1)B(x1))...(xn,A(xn)B(xn))}

那么就有两个问题:

1.怎么快速得到n+1个点

2.怎么将点值表达法变回系数

如果 A ( x ) A(x) A(x)是一个偶函数,那么 A ( x ) = A ( − x ) A(x)=A(-x) A(x)=A(x),因此带入一个值也就得到了两个点

同理如果 A ( x ) A(x) A(x)是一个奇函数,那么有 A ( x ) = − A ( − x ) A(x)=-A(-x) A(x)=A(x),也可以带一个点得到两个点

因此可以将 A ( x ) A(x) A(x)分成奇函数部分与偶函数部分

P ( x ) = a 0 + a 1 x + a 2 x 2 + . . . + a n x n P ( x ) = ( a 0 + a 2 x 2 + a 4 x 4 + . . . ) + x ( a 1 + a 3 x 2 + a 5 x 4 + . . . ) P ( x ) = P e ( x 2 ) + x P o ( x 2 ) P ( x i ) = P e ( x i 2 ) + x i P o ( x i 2 ) P ( − x i ) = P e ( x i 2 ) − x i P o ( x i 2 ) P(x)=a_0+a_1x+a_2x^2+...+a_nx^n\\ P(x)=(a_0+a_2x^2+a_4x^4+...)+x(a_1+a_3x^2+a_5x^4+...)\\ P(x)=P_e(x^2)+xP_o(x^2)\\ P(x_i)=P_e(x_i^2)+x_iP_o(x_i^2)\\ P(-x_i)=P_e(x_i^2)-x_iP_o(x_i^2) P(x)=a0+a1x+a2x2+...+anxnP(x)=(a0+a2x2+a4x4+...)+x(a1+a3x2+a5x4+...)P(x)=Pe(x2)+xPo(x2)P(xi)=Pe(xi2)+xiPo(xi2)P(xi)=Pe(xi2)xiPo(xi2)

然后如果将 P e ( x ) , P o ( x ) P_e(x),P_o(x) Pe(x),Po(x)继续分解

但我们的 P e ( x ) , P o ( x ) P_e(x),P_o(x) Pe(x),Po(x)是通过 P ( x ) = P e ( x 2 ) + x P o ( x 2 ) P(x)=P_e(x^2)+xP_o(x^2) P(x)=Pe(x2)+xPo(x2)得来的,因此取相反数也无法让它们一一符号相反

那么我们取复数呢?

i 2 = ( − i ) 2 = − 1 1 2 = ( − 1 ) 2 = 1 因此有 i , − i , 1 , − 1 :   x 1 , − x 1 , x 2 , − x 2 − 1 , 1 : x 1 2 , x 2 2 1 : x 1 4 可解决 n ≤ 4 的问题 i^2=(-i)^2=-1\\ 1^2=(-1)^2=1\\ 因此有\\ i,-i,1,-1:\ x_1,-x_1,x_2,-x_2\\ -1,1:x_1^2,x_2^2\\ 1:x_1^4 \\可解决n\leq4的问题 i2=(i)2=112=(1)2=1因此有i,i,1,1: x1,x1,x2,x21,1:x12,x221:x14可解决n4的问题

那么更大的呢?

我们令 w = e 2 π i n = c o s ( 2 π n ) + i s i n ( 2 π n ) w=e^{\frac{2\pi i}{n}}=cos(\frac{2\pi}{n})+isin(\frac{2\pi}{n}) w=en2πi=cos(n2π)+isin(n2π),我们可以得到它的性质正好可以解决该问题

请添加图片描述

反过来呢?

w = e − 2 π i n w=e^{-\frac{2\pi i}{n}} w=en2πi,然后给每个数都乘上 1 n \frac{1}{n} n1即可

//初始化每个位置最终到达的位置 
void init(int k)
{
    int len=1<<k;
	for(int i=0;i<len;i++)
	rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
}
//a表示要操作的系数,n表示序列长度
//若flag为1,则表示FFT,为-1则为IFFT(需要求倒数) 
void fft(cp *a,int n,int flag){ 
    for(int i=0;i<n;i++)
	{
	 //i小于rev[i]时才交换,防止同一个元素交换两次,回到它原来的位置。 
	  if(i<rev[i])swap(a[i],a[rev[i]]);
	}
	for(int h=1;h<n;h*=2)//h是准备合并序列的长度的二分之一
	{
		cp wn=exp(cp(0,flag*pie/h));//求单位根w_n^1 
		for(int j=0;j<n;j+=h*2)//j表示合并到了哪一位
		{
			cp w(1,0);
			for(int k=j;k<j+h;k++)//只扫左半部分,得到右半部分的答案
			{
			    cp x=a[k];
			    cp y=w*a[k+h];
		        a[k]=x+y;  //这两步是蝴蝶变换 
		        a[k+h]=x-y;
		        w*=wn; //求w_n^k 
			}
		 }
	 }
	 //判断是否是FFT还是IFFT 
	 if(flag==-1)
	 for(int i=0;i<n;i++)
     a[i]/=n;
}

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

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

相关文章

Java多线程基础-11:工厂模式及代码案例之线程池

在Java中&#xff0c;xx池的概念是很常见的&#xff0c;比如之前遇到过的常量池、数据库连接池等等。 线程池是一种常用的多线程处理方式&#xff0c;它可以重复利用已创建的线程&#xff0c;从而减少线程的创建和销毁开销&#xff0c;并提高程序的性能。 通俗来说&#xff…

【Windows】Redis集群部署

集群是如何进行工作的 Redis采用哈希槽来处理数据与节点之间的映射关系&#xff0c;一个集群共有16384 个哈希槽&#xff0c;每个key通过 CRC16算法计算出一个16bit的值&#xff0c;再对16384取模&#xff0c;得到对应的哈希槽&#xff0c;集群通过维护哈希槽与节点的关系来得…

flutter聊天界面-Text富文本表情emoji、url、号码展示

flutter聊天界面-Text富文本表情emoji、url、号码展示 Text富文本表情emoji展示&#xff0c;主要通过实现Text.rich展示文本、emoji、自定义表情、URL等 一、Text及TextSpan Text用于显示简单样式文本 TextSpan它代表文本的一个“片段”&#xff0c;不同“片段”可按照不同的…

Verilog学习笔记2:反相器

代码&#xff1a; //反相器 timescale 1ns/10ps module inv( A,y); input A; output y; assign y~A; endmodule //testbench module inv_tb;reg A; wire YY;inv inv(.A(A),.y(YY));initial beginA<0;#10 A<1;#10 A<0; #10 A<1;#10 A<0; #10 A<1;#10 A<0;…

从小白到大神之路之学习运维第54天--------ELK日志收集分析

第三阶段基础 时 间&#xff1a;2023年7月6日 地 点&#xff1a;2304教室 授课人&#xff1a;李凤海 参加人&#xff1a;全班人员 内 容&#xff1a; ELK技术堆栈 目录 服务器设置&#xff1a; 部署elasticsearch集群&#xff1a; 配置elasticsearch集群&#xff…

怎样寻找SEO服务商,需要注意那些问题?

网上提供SEO服务的公司或个人多如牛毛&#xff0c;随便在搜索引擎上搜索一下&#xff0c;成千上万的公司就在眼前。大部分网站设计公司也兼职SEO服务&#xff0c;寻找合适的SEO服务商并不简单&#xff0c;鉴别合格的SEO服务商是关键。 1、确定外包任务 如果没有SEO团队&…

C++类相关概念

1. 函数形参默认值 &#xff08;1&#xff09; 建议函数&#xff08;不仅仅是构造函数&#xff09;形参默认值只在函数声明中指定&#xff1b; &#xff08;函数声明和定义写在同一个文件中&#xff0c;则函数声明、定义两者之一或两者都可指定形参默认值&#xff0c;两者都指定…

mybati执行流程源码分析

MyBatis执行流程源码分析 前言 由于之前写过关于mybatis源码的文章,但是感觉还是不够细致,不够完善.没有把一些具体的流程应用写下来,至此又写了一篇.内容可能比较长,希望大家可以打开源码跟着这篇文章一起看源码保证可以收获许多. 1.mybatis基础开发流程 1.引入mybatis相关…

短视频去水印小帮手微信小程序源码带后台

短视频去水印小帮手微信​小程序源码​带后台&#xff0c;短视频去水印系列教程服务端源码。 php版&#xff0c;这里不过多介绍&#xff0c;我假设您有基本的编码基础&#xff0c;并熟悉php语言及laravel框架。

Topaz Gigapixel AI v6 人工智能图像放大

其他软件或插件依赖于插值算法来放大图像&#xff0c;Topaz Gigapixel AI 则与众不同&#xff0c;它使用最先进的深度学习技术来扩大和增强图像。 它通过神经网络分析了数百万张照片&#xff0c;从而了解了不同的照片在放大时细节是如何损失的&#xff0c;以及如何为图像增强和…

四十三、贪心——Huffman树、排序不等式

算法主要内容 一、Huffman树1、题目内容——合并果子2、算法思路&#xff08;1&#xff09;“合并果子”中的Huffman树&#xff08;2&#xff09;算法步骤&#xff08;3&#xff09;状态转移 3、题解 二、排序不等式1、题目内容——排队打水2、算法思路&#xff08;1&#xff0…

【MySQL】数据库基础概念

文章目录 前言连接服务器什么是数据库&#xff1f;MySQL和MySQLdLinux中如何看到数据库文件SQL语句分类存储引擎 前言 今天继续讲解MySQL相关内容&#xff0c;本期主要讲解数据库的基础概念&#xff0c;方便后续学习数据库。 连接服务器 mysql -h [ip] -P [port] -u [root] …

IRIS在Linux下通过JDBC操作其他数据库

以前都是在Windows上用cache的SqlGateway通过odbc创建连接操作其他数据库。现在都用Linux了&#xff0c;那么和其他数据进行调用咋办呢。 可以看到是可以创建JDBC的连接的&#xff0c;而Java是跨平台的&#xff0c;所以可以用JDBC操作其他数据库&#xff0c;这次以mysql为例。…

浅谈Node.js中的npm和yarn

官方文档&#xff1a; npmhttps://www.npmjs.cn/ yarnhttps://yarn.bootcss.com/ npm和yarn的作用 yarn和npm都是构建和打包javascript代码的工具 区别 npm&#xff1a; 1npm使得js开发者易于分享其为解决特定问题而编写的代码&#xff0c;且可供其他开发者在他们自己的应…

【阶段学习小总结】

串口通信和CAN总线通信的区别 can总线和串口是两种不同的通信模式&#xff0c;注意CAN总线数据传输所用的虽然是DB9串口线&#xff0c;但它完全不是串口&#xff0c;这一点容易出错。 CAN总线通信是高速&#xff0c;可靠&#xff0c;灵活的一种通信协议。作为一种分布式通信方…

天梯赛注意事项

格式错误 有的时候题目隐含的条件是要你输出两行的&#xff0c;即使第二行什么也没有&#xff0c;也得输出。 答案错误可能涉及特殊值的处理 或者 题意与你本身的思维不一致 map定义在main外面 键自动赋值 it->first it->second mp自动按照下标排序 . 模拟出栈入栈操…

使用GTK创建简易计算器

使用GTK创建简易计算器 本文将介绍如何使用GTK&#xff08;GIMP Toolkit&#xff09;创建一个简单的计算器应用程序。通过这个例子&#xff0c;你将学习如何构建基本的图形用户界面&#xff0c;并了解GTK的一些常用组件和回调函数的使用。 准备工作 首先&#xff0c;确保你已…

Django之中间件

一、中间件介绍 官方的说法&#xff1a;中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统&#xff0c;用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。 但是由于其影响的是全局&#xff0c;所以需要…

Vivado2020.1 vitis使用:创建hello world项目

前言 之前网上的教程都是基于Vivado2018的&#xff0c;后来接手一个未完工的项目&#xff0c;是使用Vivado2020.1创建的&#xff0c;非常尴尬&#xff0c;只能打开&#xff0c;不能编辑。千辛万苦把2020.1安装好&#xff0c;当然此时不仅仅是Vivado2020.1了&#xff0c;而是vi…

gitee注册以及使用的简单教程

目录 1.gitee是什么&#xff1f; 2. gitee怎么注册? 3.gitee创建仓库 4.gitee怎么提交代码? 5. git的三板斧 1.gitee是什么&#xff1f; 基于Git的代码托管和研发协作平台上面可以托管个人或者公司的代码和开源项目。国外有github&#xff0c;国内有giteegithub经常出现…