邏輯 集合運算上的卷積一覽(FMT FWT, )

2022-03-01 19:07:12 字數 2751 閱讀 4678

公式渲染修好了。

對於邏輯\(\oplus\)的卷積,而且你不能n方豹草

\[a_k=\sum_ b_ic_j\\

\]那麼嘗試構造變換\(f_\)和反演\(f_^\)使滿足

\[f_(a)_k=f_(b)_k f_(c)_k\\

a_k=f_^(f_(a))_k

\]用來加速運算。

定義或、與卷積的變換分別為

\[f_(a)_k=\sum_a_i,f_(a)_k=\sum_a_i

\]如下驗證兩種變換的可行性

\[\begin

&\begin

f_(b)_k f_(c)_k

&=\sum_b(i)\sum_c(j)

\\&=\sum_\sum_b(i) c(j)

\\&=\sum_a(x)

\\&=f_(a)_k

\end

&\begin

f_(b)_k f_(c)_k

&=\sum_b(i)\sum_c(j)

\\&=\sum_\sum_b(i) c(j)

\\&=\sum_a(x)

\\&=f_(a)_k

\end

\end

\]驗證成功。

如何實現這兩種變換?注意到如果將\(n\)位二進位制數域對映到乙個\(n\)維空間,則\(f_(a)_i\)相當於在空間內求高維字首和,\(f_(a)\)則是求高維字尾和。

因此直接上高維前/字尾和就能做到\(o(n2^n)\)的複雜度,這樣的做法屬於「快速莫比烏斯變換」。

void fmt_or(int a,int len) \)個區間,並記\(f_(a)_\)表示x所在區間中所有下標與x就二進位制末i+1位滿足特定規則的元素累和。

例如\(f_(a)_=a_x\),而所求\(f_(a)_x=f_(a)_\)。

從階段i轉移到階段i+1時,階段i+1的乙個區間內的答案顯然由階段i中位置對應的相鄰兩個區間內的答案轉移而來,此時決策為二進位制第i+2末位的取與不取,即從\(f_(a)_\)和\(f_(a)_\)轉移到\(f_(a)_\)和\(f_(a)_\),其中l是階段i+1中的某個區間的左端點。這四個狀態,設為狀態a,b,c,d,狀態b,d能夠表示取到第i+2末位。(其實b的取是假的,因為b不存在在i+2位產生的貢獻)。轉移按照變換式針對這四個狀態做就好了。

例如或卷積中,a,b的下標 或上\(2^\)(取到i+2位)得到d的下標,而只有a的下標 或上\(0\)(不取i+2位)得到c的下標;只有b的下標 與上\(2^\)(取到i+2位)得到d的下標,a,b的下標 與上\(0\)(不取i+2位)得到c的下標。實現如下

void fwt_or(int a,int len) ^(a)_k=\sum_ (-1)^f_(a)_k\\

f_^(a)_k=\sum_ (-1)^f_(a)_k

\]其中\(|i|\)是將\(i\)的二進位製上\(1\)的個數。

先來「快速莫比烏斯反演」做法,直接把變換逆過來做

void ifmt_or(int a,int len) (a)_k=\sum_ (-1)^a_i

\]這次不去驗證,考慮直接推導【膜rockdu】,首先假定變換\(f_(a)\)與\(a\)線性相關,如下,

\[f_(a)_k=\sum_ g(k,i)a_i

\]當然\(g(,)\)是需要能支援反演的,因此\(g(,)=0\)之類的就不考慮了。那麼

\[\begin

f_(a)_k&=\sum_g(k,i)a_i=\sum_g(k,i)\sum_b_pc_q

\\&=\sum_\sum_g(k,i\veebar j)b_ic_j

\\f_(b)_k f_(c)_k

&=\sum_g(k,i)b_i\sum_g(k,j)c_j

\\&=\sum_\sum_g(k,i)g(k,j)b_ic_j

\\g(k,i\veebar j)&=g(k,i) g(k,j)

\end

\]我們需要構造乙個\(g(,)\)。

注意\(|i\veebar j|=|i|+|j|\pmod2\),以及\((i\veebar j)\wedge k=(i\wedge k)\veebar (j\wedge k)\),那麼

\[|(i\veebar j)\wedge k|=|(i\wedge k)\veebar(i\wedge k) |=|i\wedge k|+|j\wedge k|\pmod2\\

(-1)^=(-1)^(-1)^

\]因此令\(g(k,i)=(-1)^\)就能得到乙個合法變換

\[f_(a)_k=\sum_(-1)^a_i

\]如何實現這種變換?高維前/字尾和似乎已經g了,使用快速沃爾什變換,相鄰兩個階段轉移,要討論對下標與的二進位制1的個數的影響,結果如下

\[f_(a)_=f_(a)_+f_(a)_\\

f_(a)_=f_(a)_-f_(a)_

\]那麼變換就完成了

void fwt_xor(int a,int len) ^(a)_=f_(a)_\\

f_^(a)_=\frac^(a)_+f_^(a)_}2\\

f_^(a)_=\frac^(a)_-f_^(a)_}2\\

\]實現如下

void fwt_xor(int a,int len) \sum_ [i\vee j=k][i\wedge j=0] b_ic_j

\\=\sum_\sum_ [|i|+|j|=|k|] b_ic_j

\]可以列舉補充一維集合大小,從小到大列舉集合大小,分別做一次或卷積,時間複雜度\(o(n^22^n)\)。

還在補。

java邏輯運算上的短路特性

1.邏輯與 true true true true false false false true false false false false 由上可以得出,只要有乙個false,則可以肯定結果肯定為false。短路特性 public class test 執行後結果 e false c 3 我們...

double與float運算上的坑

一 double乘法坑 public static void main string args 執行結果 驚不驚喜?意不意外?7156 7157二 除法喜歡加f的群眾 public static void main string args 執行結果 開不開心?尾數0加了f 225456.00 尾數1...

PyTorch 反卷積運算 一

反卷積是一種特殊的正向卷積操作,通過補零的方式擴大輸入影象的尺寸,接著翻轉卷積核,和普通卷積一樣進行正向卷積,由於前期補充了大量的零,即便進行了卷積運算,輸出影象的尺寸依然比輸入影象大,這樣就達到了向上取樣的目的 下面展示一些例項,使用 pytorch 計算反卷積 示例 1 輸入輸出通道數都是1,步...