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 \le |A|}{A_i}$
则 $\hat{A} = S_{\lceil log_2n \rceil}$
初始情况下有 $S_0$ 被拆分为 $n$ 段, $S_0([A_i],i) = A_i$
考虑每次将相邻两段合并。
记 $B0 = S_t([A0,A1],x)$ 的前一半,记 $B1$ 为后一半。
则有
$$B0 = A0 \\ B1 = A0 + A1$$
从而考虑将序列长度补为 $2^t$,不停合并序列即可实现时间复杂度 $O(nt)$ 的变换方法,逆变换只需要按上述变换解方程即可。
考虑应用这个变换
试求$$C_x = \sum_{a\ or\ b = x} A_a B_b$$
考虑应用变换的性质
$$\hat{C_c} \\ = \sum{[x\ or\ c=c]C_x} \\ = \sum{[(a\ or\ b)\ or\ c = c]A_a B_b} \\= \sum{[(a\ or\ c = c)]A_a [(b\ or\ c = c)B_b ]} \\=\hat{A_c} \hat{B_c}$$
对于
$$C_x = \sum_{a\ and\ b = x}{A_a B_b}$$
我们考虑构造另外一种变换方法,$$[(a\ and\ b)\ and\ c = c] = [(a\ and\ c = c)][(b\ and\ c = c)]$$
新的变换方法同上,为$$B0 = A0 + A1 \\ B1 = A1$$
上述变换很容易推广到高维的情况,略。
那么考虑另外一种逻辑规则$$C_x = \sum_{a \oplus b = x} A_a B_b$$
类比上述两式我们应用本身的运算 $xor$,再考虑将其化为只含有0,1的逻辑函数。
尝试定义 $f(a,b) = a \oplus b$ 中一的个数取余2,从而有
$$([f(a,c)=0]-[f(a,c)=1])([f(b,c)=0] - [f(b,c)=1]) \\= [f(a \oplus b,c) = 0] - [f(a \oplus b,c) = 1]$$
我们将变换称为 $w$ 变换
从而 $w(C) = w(A)\cdot w(B)$
考虑如何求解 $w(A)$
假定,记$$B0 = B00 - B10 \\ B1 = B01 - B11$$
从而
$$B00 = A00 + A11, B01 = A10 + A01 \\ B10 = A10 + A01, B11 = A00 + A11 \\ B0 = A00+A11-A10-A01 \\ B1 = A10+A01-A00-A11$$
从而$$B0 = A0 - A1, B1 = A1 - A0$$
正确但是无法通过反解的方式进行逆变换。
可以发现关键问题在于我们要设法使得$B0, B1$的生成式不能线性相关,从而不可以使得$$f(a,b) = g(a \oplus b)$$
因为前者会导致两个递归式线性相关。
而使得$$f(a,b) = g(a\ or\ b) / g(a\ and\ b)$$
则可以得到两个并不线性相关的式子。
考虑修改 $f(a,b)$ 定义,经尝试得到$f(a,b) = a\ and\ b$ 中 1 的个数满足$$f(a\oplus b,c) = f(a,c) \oplus f(b,c)$$契合上述式子
这样我们会得到变换$$B0 = A0+A1 \\ B1 = A0-A1$$
从而逆变换为$$A0 = \frac{B0+B1}{2} \\ A1 = \frac{B0-B1}{2}$$
考虑和$fft$一样,统一正反变换,得到
$$B0 = \frac{A0+A1}{\sqrt 2} \\ B1 = \frac{A0-A1}{\sqrt 2}$$
反向变换相同。
我们考虑将原序列中各个元素对于变换后序列每一项的贡献,用矩阵写出来得到$Hadamard$ 矩阵。
$$H_n = \frac{1}{\sqrt 2}\left( \begin{array}{ccc} H{n-1} & H{n-1} \\ H{n-1} & -H{n-1} \end{array} \right)$$
后两个变换的简单测试程序:
#include <bits/stdc++.h>
using namespace std;
void W(int a[],int l,int r)
{
if(l==r) return;
int m = (l+r)>>;
W(a,l,m);
W(a,m+,r);
for(int i=l;i<=m;i++)
{
a[i]-=a[i-l++m];
a[i-l++m] = -a[i];
}
}
void FWT(int a[],int l,int r)
{
if(l==r) return;
int m = (l+r)>>;
FWT(a,l,m);
FWT(a,m+,r);
for(int i=l;i<=m;i++)
{
int x = a[i], y = a[i-l++m];
a[i] = x+y;
a[i-l++m] = x-y;
}
}
void rFWT(int a[],int l,int r)
{
if(l==r) return;
int m = (l+r)>>;
for(int i=l;i<=m;i++)
{
int x = a[i], y = a[i-l++m];
a[i] = (x+y)/;
a[i-l++m] = (x-y)/;
}
rFWT(a,l,m);
rFWT(a,m+,r);
}
int sol(int now)
{
int ans = ;
for(;now;now>>=) if(now&) ans=-ans;
return ans;
}
#define N 100010
int a[N],s[N];
int main()
{
int t;
cin >> t;
for(int i=;i<(<<t);i++) scanf("%d",&a[i]);
for(int i=;i<(<<t);i++)
{
s[i] = ;
for(int j=;j<(<<t);j++) s[i] += sol(i^j)*a[j];
}
W(a,,(<<t)-);
for(int i=;i<(<<t);i++) cout << s[i] - a[i] << endl;
return ;
}
Fast Walsh–Hadamard transform的更多相关文章
- h.264 fast,1/2,1/4像素运动估计与插值处理
Hadamard Transform 在1/2,1/4像素运动估计这一阶段中,对于像素残差,可以选择采用哈达玛变换来代替离散余弦变换进行高低频的分离. 优点:哈达玛矩阵全是+1,-1,因此只需要进行加 ...
- H.264 Transform
变换是视频.图像编码的核心部分.目前所采用的变换算法都是从傅里叶变换演变而来.单纯的变换并不会导致视频(图像)的码率变小,反而会增大.但是非常巧妙的一点是:变换把图像从空域转换成的时域,把由色块组成的 ...
- 简单的量子算法(一):Hadamard 变换、Parity Problem
Hadamard Transform Hadamard 变换在量子逻辑门中提过,只不过那时是单量子的Hadamard门,负责把\(|1\rangle\)变成\(|-\rangle\),\(|0\ran ...
- paper 132:图像去噪算法:NL-Means和BM3D
这篇文章写的非常好,确定要~认真~慎重~的转载了,具体请关注本文编辑作者:http://wenhuix.github.io/research/denoise.html 我不会告诉你这里的代码都是f ...
- 图像去噪算法:NL-Means和BM3D
图像去噪是非常基础也是非常必要的研究,去噪常常在更高级的图像处理之前进行,是图像处理的基础.可惜的是,目前去噪算法并没有很好的解决方案,实际应用中,更多的是在效果和运算复杂度之间求得一个平衡,再一次验 ...
- X264参考手册
艺搜简介 基本语法: x264 [options]-o outfile infile 注意与ffmpeg的输入输出文件位置恰好相反: ffmpeg[options][[infile options]- ...
- Video processing systems and methods
BACKGROUND The present invention relates to video processing systems. Advances in imaging technology ...
- FWT,FST入门
0.目录 目录 0.目录 1.什么是 FWT 2. FWT 怎么做 2.1. 或卷积 2.2.与卷积 2.3.异或卷积 2.4.例题 3. FST 3.1. FST 怎么做 3.2.例题 1.什么是 ...
- [译]处理文本数据(scikit-learn 教程3)
原文网址:http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html 翻译:Tacey Won ...
随机推荐
- 【LeetCode】:二叉搜索树
相关概念: 一棵二叉搜索树(BST)是以一棵二叉树来组织的,可以用链表数据结构来表示,其中,每一个结点就是一个对象,一般地,包含数据内容key和指向孩子(也可能是父母)的指针属性.如果某个孩子结点不存 ...
- mutation与action
mutation 作用: 更改state的状态 说明: 每个mutation对象都有字符串类型(type)与回调函数,在回调函数内进行状态修改,回调函数的第一个参数为state eg: mutatio ...
- NGINX中遇到SELinux 13:permission denied
被selinux坑了.抓包发现端口始终没有流量, 操作过程中还特地dmesg看了c并没发现selinux的异常. https://www.nginx.com/blog/using-nginx-plus ...
- IntelliJ IDEA Sringboot 项目部署到外部Tomcat服务器
<packaging>war</packaging> 添加依赖 <dependency> <groupId>org.springframework.bo ...
- 内存表 ClientDataSet CreateDataSet
unit Form_Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, F ...
- C#winform拖拽实现获得文件路径
1.关键知识点说明: 通过DragEnter事件获得被拖入窗口的“信息”(可以是若干文件,一些文字等等),在DragDrop事件中对“信息”进行解析.窗体的AllowDrop属性必须设置成true;且 ...
- Java集合类--->入门下篇
HashSet集合 在上篇大概了解了什么是集合类,知道它可以存储任意类型的对象,并且比数组灵活,集合类的长度可以变化.这里将接着介绍一下,Set接口的实现类之一,HashSet集合,Set集合:元素不 ...
- 关于IDT报错乱码总结
可算是把我折腾坏了.一筹莫展.最后才把这些问题搞好.有些事不知道做以前,怎么都想不到.发现了方法之后,原来也不过这样.我觉得自己记性太差.还是好好写下来吧.写下来顺便会帮我重新再梳理一遍.原先乱码是因 ...
- 简单使用c3p0连接池
首先,c3p0是一个连接池插件 需要jar包: 使用手动配置: /** * 手动配置使用c3p0 * @throws PropertyVetoException * @throws SQLExcept ...
- HihoCoder 1636
/** * 题目链接:https://cn.vjudge.net/problem/HihoCoder-1636 * 题目意思,石子合并,每次可以合并相邻的石子.每次可以x堆合并为一堆. * x属于[l ...