首页 > 其他分享 >位运算卷积(FWT)

位运算卷积(FWT)

时间:2022-10-31 09:59:30浏览次数:80  
标签:begin end 运算 卷积 sum 矩阵 bmatrix FWT

本文大量参考了:

FWT 概论

定义位运算卷积:\(C[k]=\sum\limits_{i\oplus j=k}A[i]B[j]\),记作 \(C=A*B\),其中 $\oplus $ 为某一位运算。

设 \(A,B\) 下标的范围都是 \([0,n-1]\) 且满足 \(n\) 是 \(2\) 的幂,那么卷出来 \(C\) 的下标范围也是 \([0,n-1]\)。

为了加速位运算卷积,我们尝试构造一个像 FFT 一样的算法,把卷积转化为直接点积。

设转化矩阵为 \(c\),即 \(FWT(A)=cA\),\(FWT(A)[i]=\sum\limits_{j=0}^nc(i,j)A[j]\)。使其满足:

\[\begin{aligned}FWT(A)[i]\cdot FWT(B)[i]&=FWT(C)[i]\\\left(\sum_{j=0}^nc(i,j)A[j]\right)\left(\sum_{j=0}^nc(i,j)B[j]\right)&=\left(\sum_{j=0}^nc(i,j)C[j]\right)\\\sum_{j=0}^n\sum_{k=0}^nc(i,j)c(i,k)A[j]B[k]&=\sum_{j=0}^nc(i,j)\sum_{a\oplus b=j}A[a]B[b]\\\sum_{j=0}^n\sum_{k=0}^nc(i,j)c(i,k)A[j]B[k]&=\sum_{j=0}^n\sum_{k=0}^nc(i,j\oplus k)A[j]B[k]\end{aligned} \]

只要满足 \(c(i,j)c(i,k)=c(i,j\oplus k)\) 即可让上式成立。

事实上我们也可以证明出必要性:由于这个式子需要对任意的 \(A,B\) 都成立(也就是说 \(A[1],\cdots,A[n],B[1],\cdots,B[n]\) 可以看成是 \(2n\) 个独立的变量),那么我们就必须要满足 \(c(i,j)c(i,k)=c(i,j\oplus k)\)。

你可能会发现这个条件和 \(i\) 并没有关系,那你可能会想:能不能先找到一个数组 \(c'\) 满足 \(c'(j)c'(k)=c'(j\oplus k)\),然后让所有的 \(c(i,j)\) 都直接赋值为 \(c'(j)\) 就好了呢?

肯定是不行的,为了保证我们得到 \(FWT(C)=c\times C\) 后能得回 \(C\),我们还需要满足矩阵 \(c\) 有逆。而按刚刚的构造方法得到的矩阵 \(c\) 秩为 \(1\),没有逆。

现在的问题是我们要构造出 \(n\) 种数组 \(c'\) 使得它们都满足 \(c'(j)c'(k)=c'(j\oplus k)\),而且要求这 \(n\) 个数组拼起来得到的矩阵有逆。

一种巧妙的构造方式是:我们先构造出对于 \(n=2\) 时满足要求的矩阵,记为 \(c_1\)。然后递推对于 \(n=2^k(k>1)\) 时满足的矩阵:\(c_k=c_1\otimes c_{k-1}\)。

其中 \(\otimes\) 为克罗内克积:对于大小为 \(n\times n\) 的矩阵 \(A\) 和大小为 \(m\times m\) 的矩阵 \(B\),它们的克罗内克积为:

\[A\otimes B=\begin{bmatrix}A_{1,1}B&\cdots&A_{1,n}B\\\vdots &\ddots &\vdots\\A_{n,1}B&\cdots&A_{n,n}B\end{bmatrix} \]

也就是说 \(c_k\) 为 \(c_1\) 的 \(k\) 级分形。设 \(n=2^m\),最后取 \(c_{m}\) 即为我们想要的 \(c\)。

考虑这么做为什么是对的,我们需要证明两点:\(c(i,j)c(i,k)=c(i,j\oplus k)\) 和矩阵 \(c\) 有逆。

  • 定理 1:\(c(i,j)c(i,k)=c(i,j\oplus k)\)。

    证明:设 \(x_t\) 表示 \(x\) 在二进制下的第 \(t\) 位,通过构造方式不难证明出 \(c(i,j)=\prod\limits_{i=0}^{m-1} c_1(i_t,j_t)\)。而矩阵 \(c_1\) 是满足条件的。

    \(c(i,j)=\prod\limits_{i=0}^{m-1} c_1(i_t,j_t)\) 这条式子是非常好的记忆方法:即我们先找出对 \(n=2\) 满足要求的矩阵,那么 \(c(i,j)\) 就是 \(i,j\) 拆位后各位的 \(c\) 的乘积。

在证明矩阵 \(c\) 有逆之前,我们需要了解一个有关克罗内克积的引理。

  • 引理 1:对于大小为 \(n\times n\) 的矩阵 \(A\) 和大小为 \(m\times m\) 的矩阵 \(B\),设它们的克罗内克积为 \(C=A\otimes B\),那么有:

    \[|C|=|A|^m|B|^n \]

    证明:考虑使用高斯消元法来求解行列式,那么 \(|A|\) 的含义就是:\((-1)^{\mu(A)}D(A)\),其中 \(D(A)\) 表示将 \(A\) 消为上三角矩阵后对角线上元素的乘积,\(\mu(A)\) 表示消元过程中使用操作”交换两行“的次数的奇偶性。

    现在考虑对 \(C\) 进行高斯消元,我们可以每 \(m\) 行一组按对 \(B\) 消元的方式消元,共 \(n\) 组,得到:(其中 \(B'\) 为将矩阵 \(B\) 消元后得到的上三角矩阵)

    \[|C|=(-1)^{n\cdot \mu(B)}\left|\begin{bmatrix}A_{1,1}B'&\cdots&A_{1,n}B'\\\vdots &\ddots &\vdots\\A_{n,1}B'&\cdots&A_{n,n}B'\end{bmatrix}\right| \]

    然后再把每 \(m\times m\) 的矩阵看成一格,然后用对 \(A\) 消元的方式对剩下的这个 \(n\times n\) 格的矩阵消元,得到:(其中 \(A'\) 为将矩阵 \(A\) 消元后得到的上三角矩阵)

    \[|C|=(-1)^{n\cdot \mu(B)}(-1)^{m\cdot \mu(A)}\left|\begin{bmatrix}A'_{1,1}B'&\cdots&A'_{1,n}B'\\\vdots &\ddots &\vdots\\A'_{n,1}B'&\cdots&A'_{n,n}B'\end{bmatrix}\right| \]

    最后得到的这个矩阵是一个上三角矩阵,它的对角线的乘积为 \(D(A)^mD(B)^n\),于是:

    \[\begin{aligned}|C|&=(-1)^{n\cdot \mu(B)}\times (-1)^{m\cdot \mu(A)}\times D(A)^m\times D(B)^n\\&=\left((-1)^{\mu(A)}D(A)\right)^m\left((-1)^{\mu(B)}D(B)\right)^n\\&=|A|^m|B|^n\end{aligned} \]

  • 定理 2:矩阵 \(c\) 有逆。

    证明:矩阵有逆等价于矩阵行列式不为 \(0\)。初始时 \(c_1\) 满足条件,即 \(c_1\) 行列式不为 \(0\)。根据引理1可以归纳证明对于任意 \(k\) 都有 \(c_k\) 行列式不为 \(0\)。

至此,我们证明了我们所构造出来的 \(c\) 是满足条件的转化矩阵。

而用这种构造方式构造出的 \(c\) 的一个好处是它能用分治加速转化的过程。

假设我们现在要求 \(c_k A\),其中 \(A\) 的下标范围为 \([0,2^k-1]\):

nmsl

根据构造方式,我们可以将 \(c_k\) 分成四块,每块都是 \(c_{k-1}\) 的若干倍(具体来说,倍数分别为 \(c_1\) 中对应的的四个数)。那么我们也将 \(A\) 分成两半 \(A_1,A_2\),那么我们只需要求出 \(c_{k-1}A_1\) 和 \(c_{k-1}A_2\) 就能 \(O(2^k)\) 求出 \(c_kA\) 了。

于是就可以分治。具体来说,在第 \(k\) 轮时,我们将 \(0\sim n-1\) 每 \(2^k\) 分成一块,然后对于每一段 \(l\sim r(r-l+1=2^k)\),用 \(c_{k-1}A_{l\sim mid}\) 和 \(c_{k-1}A_{mid+1\sim r}\) 一起 \(O(2^k)\) 推导得到 \(c_kA_{l\sim r}\)。

时间复杂度 \(O(n\log n)\)。

下面举几种位运算的例子。

Or 卷积

相当于要求两种线性无关的 \(c\) 使得它们都满足 \(c(j)c(k)=c(j|k)\)。我们可以先求出所有的可能的 \(c\):(记 \(a=c(0),b=c(1)\))

\[\begin{cases}a\cdot a=a\\a\cdot b=b\\b\cdot b=b\end{cases} \]

得到 \(3\) 组解:\(\begin{cases}a=0\\b=0\end{cases},\begin{cases}a=1\\b=0\end{cases},\begin{cases}a=1\\b=1\end{cases}\),唯一的方法是取后两组组成矩阵 \(c_1=\begin{bmatrix}1&0\\1&1\end{bmatrix}\)。

And 卷积

类似,得到 \(c_1=\begin{bmatrix}0&1\\1&1\end{bmatrix}\)。

Xor 卷积

类似,得到 \(c_1=\begin{bmatrix}1&1\\1&-1\end{bmatrix}\)。

位值域扩展

注意到:or 卷积为模 \(2\) 意义下的高维 max 卷积,and 卷积为模 \(2\) 意义下的高维 min 卷积,xor 卷积为模 \(2\) 意义下的高维加法卷积。

事实上,我们也可以用类似的方法实现模 \(k\) 意义下的高维 max/min/加法 卷积。

设 \(n=k^b\)。我们同样先构造出对于 \(n=k\) 时满足要求的 \(k\times k\) 矩阵 \(c_1\),然后 \(c_1\) 的 \(b\) 级分形即为我们要的转化矩阵 \(c\)。同样,我们只需要证明 \(c(i,p)c(i,q)=c(i,p\oplus q)\) 且矩阵 \(c\) 有逆。

对于前者,我们类似地可以得到 \(c(i,j)=\prod_{t=0}^{b-1} c(i_t,j_t)\),其中 \(i_t\) 为 \(i\) 在 \(k\) 进制下第 \(t\) 位的值。那么就易证了。

而关于矩阵有逆的证明则没有任何变化,因为过程中我们只用到了克罗内克积的性质。

所以按照该方法构造出来的矩阵 \(c\) 仍然是满足要求的。

仍然是分治加速求 \(c\)。在第 \(t\) 轮时,我们将序列每 \(k^t\) 分成一段,一段内用 \(O(k\cdot k^t)\) 的时间求出 \(c_tA_{l\sim r}\)。于是每一轮的时间复杂度均为 \(O(kn)\),总时间复杂度 \(O(nk\log_kn)\)。

模 \(k\) 意义下的 max/min 卷积

先讲 max 卷积的情况。我们需要构造 \(k\) 组线性无关的 \(c\) 使得它们都满足 \(c(p)c(q)=c(\max(p,q))\)。

取 \(p=q\) 我们首先可以确定 \(c\) 的值域为 \(\{0,1\}\)。然后发现 \(c(p)c(q)=c(\max(p,q))\) 说明 \(c\) 数组肯定形如前一段是 \(1\) 后一段是 \(0\)。那么除了全 \(0\) 之外恰好就有 \(k\) 组 \(c\)。把它们按任意顺序拼成一个矩阵均可。

为了方便,一般采用形如 \(\scriptsize\begin{bmatrix}1&0&0&0\\1&1&0&0\\1&1&1&0\\1&1&1&1\end{bmatrix}\) 这种方式,其逆为 \(\scriptsize\begin{bmatrix}1&0&0&0\\-1&1&0&0\\0&-1&1&0\\0&0&-1&1\end{bmatrix}\)。

发现其本质上就是前缀和及差分,所以单次求 \(c_tA_{l\sim r}\) 的时间可以从 \(O(k\cdot k^t)\) 优化到 \(O(k^t)\)。总时间复杂度降为 \(O(n\log_kn)\)。

从更宏观的角度来说,这个过程就是在做一个高维前缀和(每一轮做了一位的前缀和)以及高维差分(每一轮做了一位的差分)。

min 卷积也是类似的,只不过 \(c\) 数组肯定形如前一段是 \(0\) 后一段是 \(1\) 罢了。

模 \(k\) 意义下的加法卷积

我们需要构造 \(k\) 组线性无关的 \(c\) 使得它们都满足 \(c(p)c(q)=c((p+q)\bmod k)\)。

直接令 \(c_1\) 为 FFT 中的范德蒙德矩阵即可,即 \(c(i,j)=w_k^{ij}\)。

但在模意义下可能不存在 \(k\) 次单位根。

咕。

标签:begin,end,运算,卷积,sum,矩阵,bmatrix,FWT
From: https://www.cnblogs.com/ez-lcw/p/16843249.html

相关文章

  • 范德蒙德卷积
    \[\sum_{i=0}^k\binom{n}{i}\dbinom{m}{k-i}=\binom{n+m}{k}\]可以理解为在大小分别为\(n,m\)的两个堆中共取\(k\)个物品,枚举在两个堆中各取了多少个。根据\(\dbin......
  • if,三目运算符,switch,while,do...while,for,嵌套循环,break,continue,goto
    类型和C大致相同,此处仅仅列举语法格式和部分例题:________________________1.if格式与C相同:if(){}elseif(){}else{};嵌套也相同:if(){if(){};};例题......
  • mnist数据集使用torch进行卷积训练
    importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorchvision.datasets.mnistasmnistimporttorchvision.transformsasTimporttorchv......
  • 【XSY3434】【UOJ431】time map(线段树维护位运算)
    首先注意到一个性质:如果我们把权值相同且相邻的点归为一个连通块的话,那么一个叶子节点往上会经过至多\(O(\logV)\)个连通块(因为父亲节点一定是儿子节点的子集)。又注意......
  • 取反运算符
    必备知识:1.不会二进制和十进制转换的同学点击这里学习https://jingyan.baidu.com/article/597a0643614568312b5243c0.html2.二进制中第一位为符号位,0代表正数,1代表负......
  • 能够作用于序列的一些运算符和函数
    1、序列:可以分为可变序列和不可变序列;(可变:列表;不可变:元组,字符串)2、“+、*”“+”:序列的加法表示两个序列的拼接   “*”:表示序列的重复,复制   3、列表,元组......
  • 54-ES9-ES9扩展运算符与rest参数
     ......
  • CBAM: 卷积注意力模块的学习、实现及其应用
    简介ConvolutionalBlockAttentionModule(CBAM),卷积注意力模块。该论文发表在ECCV2018上(论文地址),这是一种用于前馈卷积神经网络的简单而有效的注意力模块。CBAM融合了......
  • 上手python之运算符和字符串格式化
    运算符算术(数学)运算符运算符描述实例+加两个对象相加 a + b 输出结果 30-减得到负数或是一个数减去另一个数 a - b 输出结果 -10*乘两个数相乘或是返回一个被重复......
  • 2. 奇偶正负交错运算 (取反算法)
    2.奇偶正负交错运算2.1算法/**description:1~100正负交错加减(1-2+3-4+5...+99-100)*/publicclassInverseSum{publicstaticvoidmain(String[]arg......