电路中的Kronecker积

2020-06-12 16:32:23

Kronecker积被广泛应用于电路中,特别是那些具有并行逻辑门的电路中,用来操作比特。

在这篇博客文章中,我想讨论电路中的Kronecker积的数学。

设$A\in\mathbb{C}^{m\Times n}$、$B\in\mathbb{C}^{r\Times s}$、$C\in\mathbb{C}^{n\Times p}$和$D\in\mathbb{C}^{s\Times t}$,则。

逻辑门可以自然地由矩阵表示。例如,给定任何一位,我们都可以将其表示为长度为$2^1=2$的唯一单热状态向量。更具体地说,0是$|0\rangle=[1,0]^{\top}$,1是$|1\rangle=[0,1]^{\top}$。给定任意两位,我们可以将其表示为长度为$2^2=4$的唯一单热点状态向量。更具体地说,00是$|00\rangle=[1,0,0,0]^{\top}$,01是$|01\rangle=[0,1,0,0]^{\top}$,10是$|10\rangle=[0,0,1,0]^{\top}$,11是$|11\rangle=[0,0,0,1]^{\top}$。以此类推。

传统的AND门取两位并生成一位。它的矩阵表示$\text{and}\in\mathbb{C}^{2^1\x 2^2}$接受长度为4的状态向量并生成长度为2的状态向量,其矩阵表示$\text{and}\in\mathbb{C}^{2^1\x 2^2}$。

AND GATE的期望值是00->;and->;0,01->;and->;0,10->;and->;0,11->;and->;1。让我们使用矩阵乘法检查其中一个,比如01->;and->;0。

门输入为$|01\rangle=[0,1,0,0]^{\top}$(10),门输出为$|0\rangle=[1,0]^{\top}$(0),符合我们的预期。

如果我们有多个位的输入,我们希望取逻辑门1的前几个连续位,逻辑门2的第二个连续位,依此类推,我们收集所有输出作为最终输出。逻辑门1、2等是并行逻辑门。

例如,我们有三位010。我们想将前两个比特01作为AND,第三个比特作为NOT。预期输出将为01,因为01->;和->;0和0->;不是->;1。

三个比特010也可以由长度为$2^3=8$的状态向量表示。通常,我们需要将010转换为uint,即2,然后我们知道状态向量是$|010\rangle=[0,0,1,0,0,0,0,0,0]^{\top}$。然而,由于01可以被认为是一种系统状态,而0可以被认为是另一种系统状态,因此010将是系统状态01和系统状态0的合并的系统状态。在数学上,如果我们知道01和0的状态向量,我们可以使用Kronecker积计算合并后的系统状态010。

其中$\oTimes$是Kronecker产品。人们非正式地称Kronecker积和张量积互换。根据输出产品计算出的010的状态向量符合我们的预期。

我们将前两位01应用于,正如我们在上面计算的那样,我们有。

由于我们设置电路的方式,AND和NOT是并行的逻辑门,因此必须将输出状态向量合并为一个状态向量。

我们碰巧发现我们可以应用我们在前提条件中提到的Kronecker积混合乘积性质。

这意味着,为了计算这种并行逻辑门的输出,我们不必分别计算每个单个逻辑门的输出,然后将这些输出收集在一起。给定完整的输入状态向量$|010\Rangle$,我们可以应用AND和NOT的合并运算符,结果是$\text{and}\oTimes\text{not}$,并且可以使用一次矩阵乘法直接计算输出。

任何两个并行逻辑门可以使用单个逻辑门来描述,该单个逻辑门是这两个逻辑门的Kronecker积。

通常,如果我们具有由两个并行逻辑门($X$和$Y$)、输入状态向量$|a\Rangle$到$X$、输入状态向量$|b\Rangle$到$Y$、来自$X$的输出状态向量$|c\Rangle$、来自$Y$的输出状态向量$|d\Rangle$、合并的输入状态向量$|ab\Rangle$或$|ba\Rangle$、以及合并的输出状态向量$|cd\Rangle$组成的电路。

需要注意的一件有趣的事情是$X\oTimes Y\cong Y\oTimes X$和$Y\oTimes X=P(X\oTimes Y)Q$,其中$P$和$Q$分别是行置换矩阵和列置换矩阵。我们还可以有$|ba\rangle=W|ab\rangle$和$|dc\rangle=V|cd\rangle$,其中$W$和$V$是行置换矩阵。

似乎$V^{-1}P=I$和$Q W=I$。但是我还没有想出一个正式的证据来证明这一点。

在这里,我实现了一个简单的Python脚本来模拟和验证我上面描述的并行逻辑门和Kronecker产品流程。

将数学导入numpy作为NP类BITS(对象)导入:def__init__(self,bit_string):self。SANITY_CHECK(BIT_STRING)SELF。bit_string=bit_string def sanity_check(self,bit_string):对于bit_string中的char:if char!=";0";and char!=";1";:引发异常(";BitString构造使用由0和1!";)def__len__(Self)组成的字符串:返回len(self。bit_string)def__eq__(self,bits):返回self。BIT_STRING==BITS。bit_string def__str__(Self):返回self。bit_string def to_uint(Self):返回int(self.。bit_string,2)def to_state_vec(Self):";";";";";vec=[0]*(2**len(Self))vec[self.。to_uint()]=1返回vec def state_vec_to_bits(State_Vec):num_zeros=0 num_ones=0 state_vec_len=len(State_Vec)num_bits=数学。log(state_vec_len,2),如果不是num_bits。IS_INTEGER():引发异常(";无效的状态向量长度!";)num_bits=int(Num_Bits)idx=NONE,对于i,枚举中的元素(State_Vec):if element==0:num_zeros+=1 elif element==1:num_ones+=1 idx=i否则:如果num_ones!=1或idx,则引发异常(";状态向量只能包含0或1!";)。状态向量应该只有一个1!";)bit_string=bin(Idx)[2:]。zill(Num_Bits)bits=bits(bit_string=bit_string)返回位def main():#Gate Operators not=NP。数组([[0,1],[1,0]])和=NP。array([1,1,1,0],[0,0,0,1]])bit_string_a=";01";bit_string_b=";0";bit_string_c=";0";bit_string_d=";1";bits_a=bits(bit_string=bit_string_a)bits_b=bits(bit_string=bit_string_b)bits_c=bits(bit_string=bit_string_c)bits_d=bits(bit_string=bit_string_d)bits_ab=bits(bit_string=bit_string_a+bit_string_b)bits_ba=bits(bit_string=bit_string_b+bit_string_a)bits_cd=bits。(bit_string=bit_string_c+bit_string_d)bits_dc=bits(bit_string=bit_string_d+bit_string_c)assert bits_a==state_vec_to_bits(state_vec=bits_a)。to_state_vec())断言BITS_b==STATE_VEC_TO_BITS(STATE_VEC=BITS_b。to_state_vec())断言BITS_c==STATE_VEC_TO_BITS(STATE_VEC=BITS_c。to_state_vec())断言BITS_d==STATE_VEC_TO_BITS(STATE_VEC=BITS_d。to_state_vec())A=NP。数组(Bits_a.。to_state_vec())B=NP。数组(bitsb.。to_state_vec())C=NP。数组(Bits_c.。to_state_vec())D=NP。数组(bits_d.。to_state_vec())AB=NP。数组(Bits_ab.。to_state_vec())BA=NP。数组(bits_ba.。to_state_vec())cd=np。数组(BITS_CD.。to_state_vec())dc=np。数组(BITS_DC.。to_state_vec())#并行操作#A-和->C#B-&>D#我们有以下公式#AND*A=C断言NP。ARRAY_EQUAL(np.。点(和,A),C)#NOT*B=D断言NP。ARRAY_EQUAL(np.。点(非,B),D)#A\o乘以B=AB断言NP。ARRAY_EQUAL(np.。Kron(A,B),AB)#B\o乘以A=BA断言NP。ARRAY_EQUAL(np.。Kron(B,A),BA)#C\oTimes D=CD断言Np。ARRAY_EQUAL(np.。Kron(C,D),Cd)#D\o乘以C=DC断言Np。ARRAY_EQUAL(np.。Kron(D,C),DC)#(AND\otime NOT)*(A\otime B)=(C\oTimes D)断言NP。ARRAY_EQUAL(np.。点(np.。Kron(和,非),NP。Kron(A,B)),NP。Kron(C,D))#(NOT\oTimes AND)*(B\oTimes A)=(D\oTimes C)Assert NP。ARRAY_EQUAL(np.。点(np.。Kron(非,and),NP。Kron(B,A)),NP。Kron(D,C))IF__NAME__==";__Main__";:Main()