Fast Walsh-Hadamard Transform——快速沃尔什变换
模板题:
给定$n = 2^k$和两个序列$A_{0..n-1}$, $B_{0..n-1}$,求
$$C_i = \sum_{j \oplus k = i} A_j B_k$$
其中$\oplus$是某一满足交换律的位运算,要求复杂度$O(nlogn)$。
快速沃尔什变换:
这是什么东西?能吃吗?有用吗? 请参阅SDOI2017r2d1-cut。
看到这个大家是不是立刻想到了快速傅里叶变换?
$$C_i = \sum_{j + k = i} A_j B_k$$
我们来想想离散傅里叶变换的本质。
$$\begin{aligned}& DFT(A)_i \\
&= A(\omega_n^i)\\
&=\sum_{j=0}^{n-1} A_j * (\omega_n^i)^j\end{aligned}$$
令$f(n, i, j) = (\omega_n^i)^j$,则
$$DFT(A)_i = \sum_{j=0}^{n-1} A_j f(n, i, j)$$
它要满足$DFT(A)_i * DFT(B)_i = DFT(C)_i$,即
$$(\sum_{j=0}^{n-1} A_j f(n, i, j))(\sum_{k=0}^{n-1} B_k f(n, i, k))=\sum_{l=0}^{n-1} C_l f(n, i, l)$$
$$\sum_{j=0}^{n-1} \sum_{k=0}^{n-1} A_j B_k f(n, i, j) f(n, i, k))=\sum_{l=0}^{n-1} (\sum_{a+b=l} A_a B_b) f(n, i, l)$$
这时我们发现左右分别有$n^2$项,令对应项系数相等,得
$$f(n, i, j)f(n, i, k) = f(n, i, j + k)$$
只要任意一个可以进行逆变换且满足上述条件的$f$都可以。
现在我们把上面的$+$都改成$\oplus$,就是离散沃尔什变换即
$$DWT(A)_i = \sum_{j=0}^{n-1} A_j f(n, i, j)$$
$$f(n, i, j)f(n, i, k) = f(n, i, j \oplus k)$$
怎么样,是不是云里雾里顿开茅塞?
然而我们还需要变快,所以快速傅里叶变换采用
$$f(n, i, j) = (\omega_n^i)^j$$
那它有什么优美的性质呢?
我们发现, 由于有折半引理,$f(n, i, j)$和$f(n, i+n/2, j)$可以同时从$f(n/2,i,j)$得来。
那么,从感性的角度,既然$\oplus$是一个位运算,那么应该更容易找到一个跟位运算有关的$f$,这样就自然有类似折半引理的东西使得我们可以做到上述事情。
例如,当$\oplus$是位与时,可以取$f(i, j) = [i \& j = i]$, 即$j$的二进制完全包含在$i$的二进制里时为1,否则为0。
当$\oplus$是位异或时, 可取$f(i, j) = (-1)^{count(i \& j)}$,其中$count(x)$表示$x$的二进制表示中1的个数。
逆变换:
逆变换看上去好难啊。。。
其实逆变换还是比较简单的。因为既然$f$跟位运算有关,我就只需要考虑某一位就好了。
例如$\oplus$是位异或时我考虑$n=2,A=(a_0, a_1)$,
那么$DWT(A) = (da_0 = a_0 + a_1, da_1 = a_0 - a_1)$
我只需要解一个二元一次方程(把$da_0, da_1$作为常数, $a_0, a_1$作为变量)就可以解出$a_0, a_1$了。
没了。
关于$f$函数的构造:
$f$函数怎么构造。。。和逆变换的方法差不多啊。。。只需要看$n=2$的情况就行(实际上一般就是$-1$的几次幂,或者$0, 1, -1$)
如果记忆力好可以把所有都背下来,反正满足交换律的位运算只有8个,其中还有2个是全一和全零。。。
把剩下六个列出来吧。。。(下列$f$函数均将第一个参数$n$省略, $[expr]$在布尔表达式$expr$为真时为1, 否则为0)
$\oplus$为位与: $f(i, j) = [j \& i = i]$.
$\oplus$为位或: $f(i, j) = [j \& i = j]$.
$\oplus$为位异或: $f(i, j) = (-1)^{count(i \& j)}$.
$\oplus$为位与非,位或非的时候把三个数组的下标都取反就对应位或和位与。
$\oplus$为同或时直接求位异或卷积再把$C$的下标取反就行了。
吐槽:
明明可以背代码我偏要说这么多。。。
只是因为闲的慌。。。
当然是要帮助大家更好的理解FWT。
至于为什么要满足交换律。。。我才不会告诉你我还没有搞出不满足怎么做。
有同学说FWT难以感性理解。。。我也不知道如何感性理解。。。
代码嘛。。。直接拿FFT改一改就好了。。。
1 void FWT(int *P, int len) { 2 if (len == 1) return; 3 FWT(P, len / 2); 4 FWT(P + len / 2, len / 2); 5 for (int i = 0; i < len / 2; ++i) { 6 int t1 = P[i], t2 = P[i + len / 2]; 7 P[i] = t1 + t2; 8 P[i + len / 2] = t1 - t2; 9 } 10 } 11 void IFWT(int *P, int len) { 12 if (len == 1) return; 13 for (int i = 0; i < len / 2; ++i) { 14 int t1 = P[i], t2 = P[i + len / 2]; 15 P[i] = (t1 + t2) / 2; 16 P[i + len / 2] = (t1 - t2) / 2; 17 } 18 IFWT(P, len / 2); 19 IFWT(P + len / 2, len / 2); 20 }
FWT异或卷积
转载于:https://www.cnblogs.com/y-clever/p/6875743.html
Fast Walsh-Hadamard Transform——快速沃尔什变换相关推荐
- Fast Radial Symmetry Transform/快速径向对称变换
本文主要介绍一下利用径向变换进行特征提取的方法和原理,基本原理主要来自Gareth Loy and Alexander Zelinsky的A Fast Radial Symmetry Transfor ...
- [模板] 快速沃尔什变换
快速沃尔什变换 快速沃尔什变换是求这样的式子: 对序列 \(A\), \(B\), 求序列 \(C\), 使得 \[ C_{i}=\sum_{j \oplus k} A_{j} B_{k} \] 其中 ...
- FWT(快速沃尔什变换)零基础详解qaq(ACM/OI)
1.前言(废话) 记得一年半之前做SRM518 Nim的时候还不知道FWT,当时自己用分治完美的水过去了.然后昨天的牛客有一道题,是说nim博弈中有n堆石子,请问最多取出多少堆石子可以让先手必败.当时 ...
- [多项式算法](Part 4)FWT 快速沃尔什变换 学习笔记
其他多项式算法传送门: [多项式算法](Part 1)FFT 快速傅里叶变换 学习笔记 [多项式算法](Part 2)NTT 快速数论变换 学习笔记 [多项式算法](Part 3)MTT 任意模数FF ...
- SIFT和SURF的替换算法——ORB (Oriented FAST and Rotated BRIEF 快速定向和旋转)
SIFT和SURF的替代算法--ORB (Oriented FAST and Rotated BRIEF 快速定向和旋转 1. 效果图 2. 源码 参考 1. 用于关键点检测和描述的SIFT(Scal ...
- 解题报告(一)快速沃尔什变换FWT(ACM / OI)超高质量题解
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- 《小学生都能看懂的快速沃尔什变换从入门到升天教程》(FWT / FMT / FMI)(最最严谨清晰的证明!零基础也能得学会!)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00 卷积 0x01 多项式 0x02 卷积的定义 0x03 卷积的基本性质 0x04 位运 ...
- 快速沃尔什变换(FWT)
1前言 在之前学完了FFT稍微码了一些题.也学习了一下NTT相关的知识之后,我觉得有必要学习一下FWT,这篇博客就是阐述我对FWT的理解的 2介绍 2.1解决的问题 对于FFT,它的过程本质上是cn= ...
- 模板:快速莫比乌斯变换(FMT)+快速沃尔什变换(FWT)(多项式)
文章目录 前言 解析 OR 定义 变换: 逆变换 代码 AND 代码 XOR 定义 变换 逆变换 代码 所谓快速沃尔什变换,就是快速的沃尔玛什锦专柜变换 (逃) 前言 正常卷积的定义:ck=∑i+j= ...
最新文章
- 卷积神经网络的“封神之路
- disruptor实现细节及源码分析
- oracle查看用户密码时间限制
- Elasticsearch之kopf插件安装之后的浏览详解
- 【精华总结】全文4000字、20个案例详解Pandas当中的数据统计分析与排序
- Building JavaScript Games for Phones Tablets and Desktop(3)-创造一个游戏世界
- STL源码剖析 hashtable
- 单链表操作实现getelem_c语言实现--带头结点单链表操作
- linux下的微博客户端,Linux下非官方的新浪微博客户端:WeCase(微盒),附安装方法...
- qt tcp不可以循环发送_不知道低温冷却液循环泵的冷却剂选择和更换条件?这这里可以找到答案...
- SVN如何迁移到Git?
- prml线性模型小结
- python实现ping命令_Python实现Ping程序
- matlab中的全局参量,matlab参数传递及全局变量 | 学步园
- B站高清视频下载方法揭密
- 嵌入式开发第5天(数组)
- i.MX Yocto Project User‘s Guide
- 《C语言入门100例》(第6例)给定两个点的坐标 (x1, y1) 和 (x2, y2),求两点间的距离 | 浮点数精度问题
- easyui 设置css样式,Easyui 条件设置行背景颜色_EasyUI 教程
- 最小化一维曼哈顿距离的简单证明
热门文章
- 武大计算机宿舍,国内最“豪华”的4所大学宿舍,武大上榜,最后一所意想不到!...
- 解决ZooKeeper集群搭建 [myid:1] - WARN [QuorumPeer[myid=1]:QuorumCnxManager@685] - Cannot open channel
- mysql密码错误 mac_MAC下MYSQL5.7.17连接不上提示密码错解决步骤
- python 接雨水
- HTML地址栏传数据和json区别,前端利用formData格式进行数据上传,前端formData 传值 和 json传值的区别?...
- centos 调整home分区xfs_Linux中对lvm逻辑卷分区大小的调整教程(针对xfs与ext4不同文件系统)...
- 百度广告点击软件_网络营销百问百答之64,如何提升企业百度广告点击率
- JQuery方式执行ajax请求
- 谷歌技术三宝之MapReduce
- 【自动驾驶】视觉里程计