快速数论变换NTT学习笔记

2024-01-26 13:04

本文主要是介绍快速数论变换NTT学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是NTT?

数论变换(number-theoretic transform, NTT)是离散傅里叶变换(DFT)在数论基础上的实现。
NTT是一种计算卷积的快速算法,FFT也是其中一种。

但是FFT具有一些实现上的缺点,举例来说,向量必须乘上复数系数的矩阵进行处理,而且每个复数系数的实部和虚部是一个正弦及余弦函数,因此大部分的系数都是浮点数,也就是说,必须做浮点复数运算,计算量会比较大,并且浮点数运算产生的误差会比较大。

NTT解决的是多项式乘法带模数的情况,受到模数的限制,数也比较大。
在数学中,NTT 是关于任意环上的DFT。在有限域的情况下,通常称为数论变换,即NTT。

原根

FFT的实现是找单位圆上的 n n n个点 ω n 0 , ω n 1 , … , ω n n \omega_n^0, \omega_n^1, \dots, \omega_n^n ωn0,ωn1,,ωnn(称为单位根) ,然后对这些点进行FFT。因此,对于NTT,我们需要在取模域上找到和这个点等价的数。为了找到这 n n n个等价的数,我们要使用原根。

n n n为大于1的2的幂, p p p为质数且 n ∣ ( p − 1 ) n|(p-1) n(p1),即 n n n整除 p − 1 p-1 p1 ,则存在本原 n n n次方根。对于质数 p = q n + 1 p=qn+1 p=qn+1,(模 p p p意义下的)原根 g g g满足: g q n = 1 ( m o d p ) g^{qn}=1 (\mod p) gqn=1(modp),将 g n = g q ( m o d p ) = g p − 1 n ( m o d p ) g_n=g^q (\mod p)=g^{{p-1}\over n} (\mod p) gn=gq(modp)=gnp1(modp)看作 ω n \omega_n ωn的等价。

于是原根 g n g_n gn和单位根 ω n \omega_n ωn满足相似的性质!

原根和单位根的等价性

g n = g p − 1 n g_n=g^{{p-1}\over n} gn=gnp1

于是,
g n n = g n ⋅ p − 1 n = g p − 1 g_n^n=g^{n \cdot {p-1\over n}}=g^{p-1} gnn=gnnp1=gp1

g n n 2 = g p − 1 2 g_n^{n\over 2}=g^{p-1\over 2} gn2n=g2p1

g a n a k = g a k ( p − 1 ) a n = g k ( p − 1 ) n = g n k 【对应单位根消去引理】 g_{an}^{ak}=g^{\frac{ak(p-1)}{an}}=g^{\frac{k(p-1)}{n}}=g_n^k【对应单位根消去引理】 ganak=ganak(p1)=gnk(p1)=gnk【对应单位根消去引理】

可以得到:
g n n ≡ 1 ( m o d p ) 【对应单位根 ω n n ≡ 1 】 g_n^n \equiv 1 (\mod p) 【对应单位根\omega_n^n\equiv 1】 gnn1(modp)【对应单位根ωnn1

g n n 2 ≡ − 1 ( m o d p ) 【对应单位根 ω n n 2 ≡ − 1 】 g_n^{n\over 2} \equiv -1 (\mod p)【对应单位根\omega_n^{n\over 2}\equiv -1】 gn2n1(modp)【对应单位根ωn2n1

g n k + n 2 = g n k ⋅ g n n 2 = − g n k ( m o d p ) 【对应单位根折半引理】 g_n^{k+{n\over 2}}=g_n^{k}\cdot g_n^{n\over 2}=-g_n^{k} (\mod p)【对应单位根折半引理】 gnk+2n=gnkgn2n=gnk(modp)【对应单位根折半引理】

( g n k + n 2 ) 2 = g n 2 k + n = g n 2 k ⋅ g n n = g n 2 k ( m o d p ) (g_n^{k+{n\over 2}})^2=g_n^{2k+n}=g_n^{2k}\cdot g_n^n=g_n^{2k} (\mod p) (gnk+2n)2=gn2k+n=gn2kgnn=gn2k(modp)

我们发现单位根具有的性质原根都有,所以我们将 g n k g_n^k gnk g n k + n 2 g_n^{k+{n\over 2}} gnk+2n代入,本质上和将 ω n k \omega_n^k ωnk ω n k + n 2 \omega_n^{k+{n\over 2}} ωnk+2n代入并无二异!

在INTT中,乘单位根的共轭复数的操作也就会相应地变为乘原根在模意义下的逆元。

常见的模数和原根如下:
p = 1004535809 = 479 × 2 21 + 1 , g = 3 p = 998244353 = 7 × 17 × 2 23 + 1 , g = 3 p=1004535809=479\times 2^{21}+1, g=3 \\ p = 998244353=7\times 17\times2^{23}+1, g=3 p=1004535809=479×221+1,g=3p=998244353=7×17×223+1,g=3

快速数论变换(FNTT)

简而言之,FNTT是NTT增加分治操作之后的快速算法,也是FFT在数论基础上的实现。FNTT使用的分治办法,与FFT使用的分治办法完全一致。

DFT、FFT、NTT、FNTT的关系

  • 在 DFT与NTT的基础上,增加分治操作,得到FFT与FNTT。分治操作同FFT一致。
  • 在DFT与FFT的基础上,将复数加法与复数乘法替换为模 p p p意义下的加法和乘法,一般大小限制在0到 p − 1 p-1 p1之间;将本原单位根改为模 p p p意义下的相同阶数的本原单位根,阶数为2的幂,即可得到NTT与FNTT。

一大堆参考资料

  • 快速数论变换(NTT)超详解
  • OI Wiki 快速数论变换
  • 快速数论变换NTT
  • 快速傅立叶变换FFT学习笔记

这篇关于快速数论变换NTT学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646885

相关文章

shell脚本快速检查192.168.1网段ip是否在用的方法

《shell脚本快速检查192.168.1网段ip是否在用的方法》该Shell脚本通过并发ping命令检查192.168.1网段中哪些IP地址正在使用,脚本定义了网络段、超时时间和并行扫描数量,并使用... 目录脚本:检查 192.168.1 网段 IP 是否在用脚本说明使用方法示例输出优化建议总结检查 1

Rust中的Option枚举快速入门教程

《Rust中的Option枚举快速入门教程》Rust中的Option枚举用于表示可能不存在的值,提供了多种方法来处理这些值,避免了空指针异常,文章介绍了Option的定义、常见方法、使用场景以及注意事... 目录引言Option介绍Option的常见方法Option使用场景场景一:函数返回可能不存在的值场景

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题: