脑力体操: 半在线卷积能做到多好? (van der Hoeven, 2007)

固定一个可以 O(1) 运算的 effective field K, 并且假设其上的 FFT 时间复杂度为 O(NlogN). 有序列 {g}{ϕ}, 如何计算半在线卷积 fn=ϕn(i>0gifni)?

Folklore

把序列拆成两个 N/2 长度的段, 左边算完了算左边对右边的贡献, 然后算右边. T(N)=2T(N/2)+O(NlogN), 解得 O(Nlog2N).

能不能再给力一点啊?

把序列拆成 bN/b 长度的段, 左边算完了算左边对右边的贡献, 然后算右边.

注意到每块可以直接做 DFT 和 IDFT, 对之后每块的贡献不需要分别算了, 因此时间是 T(N)=bT(N/b)+O(NlogN+Nb), 取 b=logN, 解得 O(Nlog2NloglogN).

能不能再给力一点啊?

注意到上面的 "块之间的贡献" 也是一个半在线卷积, 时间可以是 T(N)=bT(N/b)+(2N/b)T(b)+O(NlogN). 注意这里的半在线卷积不是跑完一个跑另一个了, 而是它们一起跑.

b=N, 递归式是 T(N)=3NT(N)+O(NlogN), 复杂度 T(N)=O(N(logN)log3/log2).

能不能再给力一点啊? [vDH07]

我们的目标是什么? 答: 上面的递归式每次将 N 变成了 N1/2 级别的规模, 我们希望比这个块还要小.

N 理解成一个 N1/ 进制数, 或者说, 层分块, 对于 ij 的贡献, 我们在它们不同的那个最高位位置计算贡献. 这样一来, 有递归的时间复杂度

T(N)=(21)N11/T(N1/)+O(NlogN).

注意, 现在 N 每次变成 N1/ 了, 那么只需要经过 loglogN/log 轮后, 就到了递归树的叶子. 我们把 21 放成 2, 注意到下一层是

2N1N1/logN1/=2NlogN,

容易归纳发现第 k 层的代价是 2kNlogN, 所以递归的总代价是

T(N)=O(2loglogN/logNlogN).

由于

2loglogN/log=2loglogNlog+log,

最优取到 log=loglogN, 有

T(N)=O(NlogN22log2logN).

根据换底公式, 这也就是 [vDH07] 所写的

T(N)=O(NlogNexp(2log2loglogN)).

[vDH07] Joris van der Hoeven, 2007. New algorithms for relaxed multiplication.

能不能再给力一点啊? (upd: 2023.8.12)

如果递归树的叶子数和你根位置的时间复杂度长得不一样, 说明还有平衡的可能.

我们试图将 Hoeven 的分治改成更平衡的形式, 取 logN=1k, 时间复杂度是

T(N)(1+22++2k1k)O(NlogN).

如果 1=22==2k1k, 如果 k=2, 那么 1=2k, 且 logN=2k(k+1)/2. 只需取 k=2log2logN, 复杂度就是

k1O(NlogN)=O(NlogNe2log2loglogNloglogN).

好像 Hoeven 在 2014 年的时候在 审稿人的提示 下发现这件事了, 散了散了...

posted @   EntropyIncreaser  阅读(2388)  评论(7编辑  收藏  举报
相关博文:
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示