引入
沃尔什变换的数学定义
沃尔什转换矩阵
沃尔什转换矩阵为一个方阵,其阶数为 2 的幂。2k 的沃尔什矩阵可用迭代方式产生。
起始点 k=1,定义 21 阶沃尔什转换矩阵 W2=(111−1)。假设已经有 2k 阶沃尔什转换矩阵 W2k,定义 V2k+1=(W2kW2kW2k−W2k),再将 V2k+1 的列重新排列得到 W2k+1。
在不同的应用领域,对 V2k+1 列的排序时,要按照不同的顺序排序。
Walsh Ordering |
Paley Ordering |
Hadamard Ordering |
常用于信号处理 |
较常用于控制工程 |
较常用于数学 |
正变换与逆变换
沃尔什变换的转换式为 Fi=j=0∑n−1fjWij。Wij 是沃尔什变换矩阵的第 i 行第 j 列的元素。其逆变换为 fi=n1j=0∑n−1FjWij。
沃尔什变换的在通信中的应用
沃尔什变换是在频谱分析上作为离散傅立叶变换的替代方案的一种方法。
在频谱分析上最常用的一种方法是使用傅立叶变换。然而,即使已经有 FFT 来实现傅立叶变换,仍然具有一些实现上的缺点。
在傅立叶变换中,向量必须乘上复数矩阵加以处理,且复数的实部和虚部大多数情况下都为浮点数,因此计算量和误差会比较大。
在沃尔什变换中,向量需要乘上的矩阵是一个整数的矩阵,而且这些矩阵的元素只可能是 1 或 –1,这使得我们不需要作浮点数的乘法运算。更进一步,只需要使用加法来实现沃尔什变换,这使的沃尔什变换在运算复杂度上远小于傅立叶变换。
使用傅立叶变换相当于把信号拆解成在不同频率的正弦函数与余弦函数的分量,而使用沃尔什转换相当于把信号拆解成在许多不同震荡频率的方波上。因此,除非所要分析的信号拥有类似方波组合的特性,使用沃尔什变换作频谱分析的效果会比使用离散傅立叶变换分析的效果要差,这是降低运算复杂度所要付出的代价。
CDMA 就应用了沃尔什变化做多工。
沃尔什变换在信息学竞赛中的应用
在信息学竞赛中,沃尔什变换用于解决对下标进行位运算卷积的问题。快速沃尔什变换,简称 FWT,能够在 O(nlogn) 的时间内完成沃尔什变换及其逆变换。
一些约定
- ∧ 为与运算符,∨ 为或运算符,⊕ 为异或运算符。
- 一般用大写字母 A 表示一个多项式,n 为多项式的长度。
- 对于所有讨论的多项式,其长度 n 都为 2 的幂次。
- 设 A 为长度为 n 的 n−1 次多项式,其系数表达式为 (a0,a1,⋯,an−1)。定义 A0 为 A 的前 2n 项,A1 为 A 的后 2n 项。
- A+B 表示将多项式 A,B 对应的系数相加,即 ci=ai+bi。
- A−B 表示将多项式 A,B 对应的系数相减,即 ci=ai−bi。
- A×B 表示将多项式 A,B 对应的系数相乘,即 ci=aibi。
- FWT(A) 表示将多项式 A 进行快速沃尔什变换,其结果为一个长度与 A 相同的多项式。
- IFWT(A) 表示将多项式 A 进行逆快速沃尔什变换,显然有 IFWT(FWT(A))=A。
- [A,B] 表示多项式的拼接。A 的系数表达式为 (a0,a1,⋯,an1),B 的系数表达式为 (b0,b1,⋯,bn2),那么 [A,B] 的系数表达式为 (a0,⋯,an1,b0,⋯,bn2)。
- C=A∧B 表示对下标进行与运算卷积,ci=j∧k=i∑ajbk。
- C=A∨B 表示对下标进行或运算卷积,ci=j∨k=i∑ajbk。
- C=A⊕B 表示对下标进行异或运算卷积,ci=j⊕k=i∑ajbk。
引理
引理 1 [A+B,C+D]=[A,C]+[B,D]。
略证 将多项式用系数表达式表示得证。
引理 2 [A×B,C×D]=[A,C]×[B,D]。
略证 将多项式用系数表达式表示得证。
**引理 3 ** (A+B)0=A0+B0,(A+B)1=A1+B1。
略证 将多项式化为系数表达式得证。
引理 4 [(A∧B)0,(A∧B)1]=[A0∧B0+A0∧B1+A1∧B0,A1∧B1]。
略证 A0 的各个下标范围是 0∼2n−1,而 A1 的下标范围是 2n∼n−1,A1 中下标的最高位是 1,而 A0 中下标的最高位为 0。因此卷积结果的前半部分为三项之和:A0∧B0+A0∧B1+A1∧B0,每一项的下标范围都在 0∼2n−1。后半部分为 A1∧B1,下标范围在 2n∼n−1 之间。
引理 5 [(A∨B)0,(A∨B)1]=[A0∨B0,A1∨B0+A0∨B1+A1∨B1]。
略证 A0 的各个下标范围是 0∼2n−1,而 A1 的下标范围是 2n∼n−1,A1 中下标的最高位是 1,而 A0 中下标的最高位为 0。因此卷积结果的前半部分为 A0∨B0,下标范围在 0∼2n−1 之间。后半部分为三项之和:A0∨B0+A0∨B1+A1∨B0,每一项的下标范围都在 2n∼n−1 之间。
引理 6 [(A⊕B)0,(A⊕B)1]=[A0⊕B0+A1⊕B1,A1⊕B0+A0⊕B1]。
证明 A0 的各个下标范围是 0∼2n−1,而 A1 的下标范围是 2n∼n−1,A1 中下标的最高位是 1,而 A0 中下标的最高位为 0。因此卷积结果的前半部分为 A0⊕B0 与 A1⊕B1 之和,两项的下标范围均在 0∼2n−1 之间。后半部分为 A0⊕B1 与 A1⊕B0 之和,两项的下标范围都在 2n∼n−1 之间。
三种卷积
基于以上的约定,对于两个长度为 n 的 n−1 次多项式 A,B,FWT 可以解决三种对下标进行位运算卷积的问题:A∧B,A∨B,A⊕B。
类似 FFT,我们需要定义 FWT,先正向得到 FWT(A) 和 FWT(B),然后能够在线性的时间内得到 FWT(C),最后进行逆变换即可得到 C。
接下来依次介绍求解三种卷积的方法,对于不同的卷积,FWT 的定义形式也有些许不同。
与卷积 C=A∧B
定义
定义 FWT(A)={A[FWT(A0+A1),FWT(A1)]n=1n>1。
同时不加证明地给出逆变换 IFWT(A)={A[IFWT(A0−A1),IFWT(A1)]n=1n>1。
定理
定理 1.1 FWT(A+B)=FWT(A)+FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWT(A+B)=A+B=FWT(A)+FWT(B),显然成立。
假设当 n=2k 时等式成立,其中 k 为 2 的正整数幂。
当 n=k 时,
FWT(A+B)=[FWT((A+B)0+(A+B)1),FWT((A+B)1)]=[FWT(A0+A1+B0+B1),FWT(A1+B1)]=[FWT(A0)+FWT(A1)+FWT(B0)+FWT(B1),FWT(A1)+FWT(B1)]=[FWT(A0)+FWT(A1),FWT(A1)]+[FWT(B0)+FWT(B1),FWT(B1)]=FWT(A)+FWT(B)
证毕。
定理 1.2 FWT(A∧B)=FWT(A)×FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWTA∧B=A×B=FWT(A)×FWT(B),等式成立。
假设当 n=2k 时等式成立,其中 k 为 2 的正整数次幂。
当 n=k 时,
FWT(A∧B)=FWT([(A∧B)0,(A∧B)1])=FWT([A0∧B0+A1∧B0+A0∧B1,A1∧B1])=[FWT(A0∧B0+A1∧B0+A0∧B1+A1∧B1),FWT(A1∧B1)]=[FWT(A0∧B0)+FWT(A1∧B0)+FWT(A0∧B1)+FWT(A1∧B1),FWT(A1∧B1)]=[FWT(A0)×FWT(B0)+FWT(A1)×FWT(B0)+FWT(A0)×FWT(B1) +FWT(A1)×FWT(B1),FWT(A1)×FWT(B1)]=[(FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1)),FWT(A1)×FWT(B1)]=[FWT(A0+A1)×FWT(B0+B1),FWT(A1)×FWT(B1)]=[FWT(A0+A1),FWT(A1)]×[FWT(B0+B1),FWT(B1)]
证毕。
代码
基于定理1.2,C=IFWT(FWT(A∧B))=IFWT(FWT(A)×FWT(B))。
正变换:FWT(A)=[FWT(A0+A1),FWT(A1)]。
逆变换:IFWT(A)=[IFWT(A0−A1),IFWT(A1)]。
可用分治法解决。
1 2 3 4 5 6 7 8 9 10 11
| void FWT_AND(ll *x,short opt){ for(register int i=1;i<n;i<<=1){ int step=i<<1; for(register int j=0;j<n;j+=step){ for(register int k=0;k<i;k++){ x[j+k]+=x[j+k+i]*opt; x[j+k]=(x[j+k]%mod+mod)%mod; } } } }
|
或卷积 C=A∨B
定义
定义 FWT(A)={A[FWT(A0),FWT(A0+A1)]n=1n>1。
同时不加证明地给出逆变换 IFWT(A)={A[IFWT(A0),IFWT(A1−A0)]n=1n>1。
定理
定理 2.1 FWT(A+B)=FWT(A)+FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWT(A+B)=A+B=FWT(A)+FWT(B),等式成立。
假设当 n=2k 时,等式成立。其中,k 为 2 的正整数幂。
当 n=k 时,
FWT(A+B)=[FWT(A0+B0),FWT(A0+B0+A1+B1)]=[FWT(A0)+FWT(B0),FWT(A0)+FWT(B0)+FWT(A1)+FWT(B1)]=[FWT(A0),FWT(A0)+FWT(A1)]+[FWT(B0),FWT(B0)+FWT(B1)]=FWT(A)+FWT(B)
证毕。
定理 2.2 FWT(A∨B)=FWT(A)×FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWT(A∨B)=A×B=FWT(A)×FWT(B),等式成立。
假设当 n=2k 时,等式成立。
当 n=k 时,
FWT(A∨B)=FWT([(A∨B)0,(A∨B)1])=FWT([A0∨B0,A0∨B1+A1∨B0+A1∨B1])=[FWT(A0∨B0),FWT(A0∨B0+A0∨B1+A1∨B0+A1∨B1)]=[FWT(A0∨B0),FWT(A0∨B0)+FWT(A0∨B1)+FWT(A1∨B0)+FWT(A1∨B1)]=[FWT(A0)×FWT(B0),FWT(A0)×FWT(B0)+FWT(A0)×FWT(B1) +FWT(A1)×FWT(B0)+FWT(A1)×FWT(B1)]=[FWT(A0)×FWT(B0),(FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1))]=[FWT(A0),FWT(A0+A1)]×[FWT(B0),FWT(B0+B1)]=FWT(A)×FWT(B)
代码
基于定理 2.2,C=IFWT(FWT(A∨B))=IFWT(FWT(A)×FWT(B))。
正变换:FWT(A)=[FWT(A0),FWT(A0+A1)]。
逆变换:IFWT(A)=[IFWT(A0),FWT(A1−A0)]。
可用分治法解决。
1 2 3 4 5 6 7 8 9 10 11
| void FWT_OR(ll *x,short opt){ for(register int i=1;i<n;i<<=1){ int step=i<<1; for(register int j=0;j<n;j+=step){ for(register int k=0;k<i;k++){ x[j+k+i]+=x[j+k]*opt; x[j+k+i]=(x[j+k+i]%mod+mod)%mod; } } } }
|
异或卷积 C=A⊕B
定义
定义 FWT(A)={A[FWT(A0+A1),FWT(A0−A1)]n=1n>1。
同时不加证明地给出逆变换 IFWT(A)={A[2IFWT(A0+A1),2IFWT(A0−A1)]n=1n>1。
定理
定理 3.1 FWT(A+B)=FWT(A)+FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWT(A+B)=A+B=FWT(A)+FWT(B),等式成立。
假设当 n=2k 时,等式成立。其中,k 为 2 的正整数幂。
当 n=k 时,
FWT(A+B)=[FWT((A+B)0+(A+B)1),FWT((A+B)0−(A+B)1)]=[FWT(A0)+FWT(A1)+FWT(B0)+FWT(B1),FWT(A0)−FWT(A1)+FWT(B0)−FWT(B1)]=[FWT(A0)+FWT(A1),FWT(A0)−FWT(A1)]+[FWT(B0)+FWT(B1),FWT(B0)−FWT(B1)]=FWT(A)+FWT(B)
证毕。
定理 3.2 FWT(A⊕B)=FWT(A)×FWT(B)。
证明 用数学归纳法证明。
当 n=1 时,FWT(A⊕B)=A×B=FWT(A)×FWT(B),等式成立。
假设当 n=2k 时等式成立。其中,k 为 2 的正整数幂。
当 n=k 时,
FWT(A⊕B)=FWT([(A⊕B)0,(A⊕B)1])=FWT([A0⊕B0+A1⊕B1,A0⊕B1+A1⊕B0])=[FWT(A0⊕B0+A1⊕B1+A0⊕B1+A1⊕B0+),FWT(A0⊕B0+A1⊕B1−A0⊕B1−A1⊕B0)]=[FWT(A0⊕B0)+FWT(A1⊕B1)+FWT(A0⊕B1)+FWT(A1⊕B0), FWT(A0⊕B0)+FWT(A1⊕B1)−FWT(A0⊕B1)−FWT(A1⊕B0)]=[FWT(A0)×FWT(B0)+FWT(A1)×FWT(B1)+FWT(A0)×FWT(B1)+FWT(A1)×FWT(B0), FWT(A0)×FWT(B0)+FWT(A1)×FWT(B1)−FWT(A0)×FWT(B1)−FWT(A1)×FWT(B0)]=[(FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1)),(FWT(A0)−FWT(A1))×(FWT(B0)−FWT(B1))]=[FWT(A0+A1)×FWT(B0+B1),FWT(A0−A1)×FWT(B0−B1)]=[FWT(A0+A1)−FWT(A0−A1)]×[FWT(B0+B1)−FWT(B0−B1)]=FWT(A)×FWT(B)
证毕。
代码
基于定理 3.2,C=IFWT(FWT(A⊕B))=IFWT(FWT(A)×FWT(B))。
正变换:FWT(A)=[FWT(A0)+FWT(A1),FWT(A0)−FWT(A1)]。
逆变换:IFWT(A)=[2IFWT(A0)+IFWT(A1),2IFWT(A0)−IFWT(A1)]。
可用分治法解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void FWT_XOR(ll *x,short opt){ for(register int i=1;i<n;i<<=1){ int step=i<<1; for(register int j=0;j<n;j+=step){ for(register int k=0;k<i;k++){ const ll u=x[j+k],v=x[j+k+i]; x[j+k]=u+v; x[j+k+i]=u-v; x[j+k]=(x[j+k]%mod+mod)%mod; x[j+k+i]=(x[j+k+i]%mod+mod)%mod; if(opt==-1){ x[j+k]=x[j+k]*inv2%mod; x[j+k+i]=x[j+k+i]*inv2%mod; } } } } }
|