上次的博客有点模糊的说...我把思路和算法实现说一说吧...

思路

关于快速沃尔什变换,为了方便起见,我们采用线性变换(非线性变换不会搞)。

那么,就会有一个变化前各数值在变换后各处的系数,即前一篇博文中的$f(i,j)$,表示线性变换中第$i$项到第$j$项的系数。

$$DWT(A)_i = \sum_{j=0}^{n-1} A_j * f(i,j)$$

那么,我们既然要求$\oplus$卷积在变换后等价于乘积,就有

$$DWT(A)_i * DWT(B)_i = DWT(C)_i$$

其中$C$是$A,B$的$\oplus$卷积。

那么,将线性变换式及卷积定义代入,并令对应项系数相等,就可得到结论:

$$f(i, j) * f(i, k) = f(i, j \oplus k)$$

那么,通过构造合适的$f(i,j)$,就可得出变换。

$f$函数的构造

我们以异或为例(因为这时最麻烦的)。

既然是位运算,那么我们就从位运算入手。

考虑位运算,我们只需要考虑一位的情况,对于多位运算需要将每位的结果相乘(注意是相乘,这很重要!)。

通过定义,我们得到

$$f(i, 0) * f(i, j) = f(i, 0 \oplus j) = f(i, j)$$

$$f(i, 1) * f(i, 1) = f(i, 0)$$

又由于我们不能使所有系数都相同,那么只能取

$$\begin{cases}
f(i, 0) &= 1\\
f(0, j) &= 1\\
f(1, 1) &= -1
\end{cases}$$

那么此时

$$DWT(a_0, a_1) = (a_0 + a_1, a_0 - a_1)$$

可以验证其满足规则。

算法实现:

要实现$FWT$,我们仿照快速傅里叶变换,首先将$A$分成两半$A_0, A_1$(按二进制最高位,即直接取前一半和后一半)递归调用$FWT$,然后,

合并时,根据下面的式子($i_0,i_1$分别表示$i$的最高位和剩余位):

$$\begin{aligned}
DWT(A)_i &= \sum_{j=0}^{n-1} f(i, j)A_j\\
&= \sum_{j=0}^{n/2-1}f(i,j)A_j + \sum_{j=n/2}^{n-1}f(i,j)A_j\\
&= \sum_{j=0}^{n/2-1}f(i_0,j_0)f(i_1,j_1)A_j + \sum_{j=n/2}^{n-1}f(i_0,j_0)f(i_1,j_1)A_j\\
&= \sum_{j=0}^{n/2-1}f(i_0,0)f(i_1,j_1)A_j + \sum_{j=n/2}^{n-1}f(i_0,1)f(i_1,j_1)A_j\\
&= f(i_0, 0)\sum_{j=0}^{n/2-1}f(i_1,j_1)A_j + f(i_1)\sum_{j=n/2}^{n-1}f(i_0,1)f(i_1,j_1)A_j\\
&= f(i_0, 0)*DWT(A_0)_{i_1} + f(i_0, 1)*DWT(A_1)_{i_1}\end{aligned}$$

其中由第2行到第3行是因为我们对多位的$f$直接定义为各位的$f$相乘,即

$$f(i,j)=f(i_0,j_0)*f(i_1,j_1)$$

那么,算法实现就简单多了。

FWT(A, len)
1 divide A into (A0, A1) 
2 FWT(A0, len/2)
3 FWT(A1, len/2)
4 for i=0 to len/2
5   A[i]=f00*A0[i]+f01*A1[i]
6   A[i+len/2]=f10*A0[i]+f11*A1[i]

关于逆变换嘛。。。你只需要告诉自己:我只是要处理刚被$FWT$变换过的数组,我只需要把它倒过来。

那么

IFWT(A, len)
1 divide A into (A0, A1) 
for i=0 to len/2
3   solve the equation set, where the unknown numbers are A0[i] and A1[i]:
4     f00*A0[i]+f01*A1[i]=A[i]
5     f10*A0[i]+f11*A1[i]=A[i+len/2]
6 IFWT(A0, len/2)
7 IFWT(A1, len/2)

(当然解二元一次方程组只需要手算出来就好啦)

把三种运算(即与,或,异或)的f给出来:

$$\begin{array}{c|cccc}
Ops & f_{00} & f_{01} & f_{10} & f_{11} \\
\hline
And & 1 & 1 & 0 & 1 \\
Or & 1 & 0 & 1 & 1 \\
Xor & 1 & 1 & 1 & -1 
\end{array}
$$

附三种运算变换代码:

 void FWT_And(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
FWT_And(A, len2);
FWT_And(A + len2, len2);
for (int i = ; i < len2; ++i)
A[i] += A[i + len2];
}
void IFWT_And(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
for (int i = ; i < len2; ++i)
A[i] -= A[i + len2];
IFWT_And(A, len2);
IFWT_And(A + len2, len2);
} void FWT_Or(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
FWT_Or(A, len2);
FWT_Or(A + len2, len2);
for (int i = ; i < len2; ++i)
A[i + len2] += A[i];
}
void IFWT_Or(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
for (int i = ; i < len2; ++i)
A[i + len2] -= A[i];
IFWT_Or(A, len2);
IFWT_Or(A + len2, len2);
} void FWT_Xor(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
FWT_Xor(A, len2);
FWT_Xor(A + len2, len2);
for (int i = ; i < len2; ++i) {
int x = A[i], y = A[i + len2];
A[i] = x + y;
A[i + len2] = x - y;
}
}
void IFWT_Xor(int *A, int len) {
if (len == ) return;
int len2 = len >> ;
for (int i = ; i < len2; ++i) {
int x = A[i], y = A[i + len2];
A[i] = (x + y) >> ;
A[i + len2] = (x - y) >> ;
}
IFWT_Xor(A, len2);
IFWT_Xor(A + len2, len2);
}

Fast Walsh-Hadamard Transform——快速沃尔什变换(二)的更多相关文章

  1. Fast Walsh–Hadamard transform

    考虑变换 $$\hat{A_x} = \sum_{i\ or\ x = x}{ A_i }$$ 记 $S_{t}(A,x) = \sum_{c(i,t)\ or\ c(x,t)=c(x,t),\ i ...

  2. 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$ ...

  3. 关于快速沃尔什变换(FWT)的一点学习和思考

    最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...

  4. 能轻松背板子的FWT(快速沃尔什变换)

    FWT应用 我不知道\(FWT\)的严格定义 百度百科和维基都不知道给一坨什么****东西** FWT(Fast Walsh Fransform),中文名快速沃尔什变换 然后我也不知道\(FWT\)到 ...

  5. FWT快速沃尔什变换学习笔记

    FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...

  6. [学习笔记]FWT——快速沃尔什变换

    解决涉及子集配凑的卷积问题 一.介绍 1.基本用法 FWT快速沃尔什变换学习笔记 就是解决一类问题: $f[k]=\sum_{i\oplus j=k}a[i]*b[j]$ 基本思想和FFT类似. 首先 ...

  7. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记

    一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...

  8. 快速沃尔什变换 FWT 学习笔记【多项式】

    〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...

  9. 集合并卷积的三种求法(分治乘法,快速莫比乌斯变换(FMT),快速沃尔什变换(FWT))

    也许更好的阅读体验 本文主要内容是对武汉市第二中学吕凯风同学的论文<集合幂级数的性质与应用及其快速算法>的理解 定义 集合幂级数 为了更方便的研究集合的卷积,引入集合幂级数的概念 集合幂级 ...

随机推荐

  1. 支持向量机通俗导论(SVM学习)

    1.了解SVM 支持向量机,因其英文名为support vector machine,故一般简称SVM,通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是 ...

  2. 初学Oracle

    初学Oracle,遇到了很多的问题,下载的是Oracle11g,没有找到合适的管理工具,所以用sql plus 创建表,以下是本人总结的一些sql plus的命令行的命令,希望对大家有用 与sql p ...

  3. HLS:OpenCV和RTL代码转换关系

    OpenCV 图像处理是基于存储器帧缓存而构建的, 它总是假设视频帧数据存放在外部 DDR 存储器中. 由于处理器的小容量高速缓存性能的限制, 因此, OpenCV 访问局部图像性能较差. 并且, 从 ...

  4. php工具箱使用

    linux安装过程 1,去网盘下载(本人网盘也有,如果找不到,contact me)http://pan.baidu.com/s/1cxHQge 我解压以后放在/mnt/hgfs/root/phpto ...

  5. 安装TD出现Unknown user name or bad password问题

    在Server 2003 sp2上安装TD8.0 出现Unknown user name or bad password,是因为2003启用了DEP保护.  关闭系统的DEP保护就可以了.  方法如下 ...

  6. 【es6】let和const

    let 1.不存在变量提升      es5中var和function都存在变量提升,但let声明的变量不存在.     在代码块内,使用let命令声明变量之前,该变量都是不可用的.这在语法上,称为“ ...

  7. 解决Ubuntu系统的每次开机重启后,resolv.conf清空的问题和DNS域名解析问题(图文详解)

    不多说,直接上干货! 问题情况描述如下: 普及知识:   /etc/resolv.conf ,其实是一个Link .它其实指向的是 /run/resolvconf/resolv.conf.  Ubun ...

  8. 001-Servlet模板

    package ${enclosing_package}; import java.io.IOException; import javax.servlet.ServletException; imp ...

  9. web端网页适配移动端注意事项,以及遇到的问题

    1.一定要加上 <!-- name=“viewport” 指视口 width=device-width 宽度等于视口宽 initial-scale=1.0 像素比例 maximum-scale= ...

  10. 深入理解java集合框架之---------Linked集合 -----构造函数

    linked构造函数 1.LinkedList(): 构造一个空列表的集合 /** * 序列化 */ private static final long serialVersionUID = 1090 ...