import numpy as np
D0 = np.array([[1],[0]]); D0
NOT = np.array([[0,1],[1,0]]); NOT

NOT.dot(D0)

D1 = np.array([[0],[1]]); D1
NOT.dot(D1)

AND = np.array([[1,1,1,0],[0,0,0,1]]); AND

AND.dot(np.kron(D0,D0))

AND.dot(np.kron(D0,D1))

AND.dot(np.kron(D1,D0))

AND.dot(np.kron(D1,D1))

OR = np.array([[1,0,0,0],[0,1,1,1]]); OR

OR.dot(np.kron(D0,D0))

OR.dot(np.kron(D0,D1))

OR.dot(np.kron(D1,D0))

OR.dot(np.kron(D1,D1))

NAND = np.array([[0,0,0,1],[1,1,1,0]]); NAND

NOT.dot(AND)

NOR = np.array([[0,1,1,1],[1,0,0,0]]);NOR

NOT.dot(OR)

np.kron(NOT,AND)

OR.dot(np.kron(NOT,AND))

NOT.dot(AND).dot(np.kron(NOT,NOT))

OR

NOT.dot(OR).dot(np.kron(NOT,NOT))

AND

import numpy as np
k = np.kron
XOR = np.array([[1,0,0,1],
                [0,1,1,0]])
AND = np.array(([1,1,1,0],
                [0,0,0,1]))
k(XOR,AND)

def criaCompat(nbits,nvezes):
  nlins = 2**(nbits*nvezes)
  ncols = 2**nbits
  compat = np.zeros(nlins*ncols).reshape(nlins,ncols)
  for i in range(ncols):
   formato = "0" + str(nbits) + "b"
   binario = format(i,formato)*nvezes
   decimal = int(binario,2)
   compat[decimal,i] = 1
  return(compat)

criaCompat(2,2)

k(XOR,AND).dot(criaCompat(2,2))

import numpy as np
k = np.kron

def criaCompat(nbits,nvezes):
  nlins = 2**(nbits*nvezes)
  ncols = 2**nbits
  compat = np.zeros(nlins*ncols).reshape(nlins,ncols)
  for i in range(ncols):
   formato = "0" + str(nbits) + "b"
   binario = format(i,formato)*nvezes
   decimal = int(binario,2)
   compat[decimal,i] = 1
  return(compat)

criaCompat(2,2)

NOT = np.array([[0,1],
                [1,0]])

AND3 = np.array([[1,1,1,1,1,1,1,0],
                 [0,0,0,0,0,0,0,1]])

OR4 = np.array([[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
                [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]])

I2 = np.array([[1,0],
               [0,1]])

t1z = k(NOT,k(NOT,I2))
t2z = k(NOT,k(I2,NOT))
t3z = k(I2,k(NOT,NOT))
t4z = k(I2,k(I2,I2))
ORz = k(AND3,k(AND3,k(AND3,AND3)))
ORz = OR4.dot(ORz).dot(k(t1z,k(t2z,k(t3z,t4z))))

t1c = k(NOT,k(I2,I2))
t2c = k(I2,k(NOT,I2))
t3c = k(I2,k(I2,NOT))
t4c = k(I2,k(I2,I2))
ORc = k(AND3,k(AND3,k(AND3,AND3)))
ORc = OR4.dot(ORc).dot(k(t1c,k(t2c,k(t3c,t4c))))

compat = criaCompat(3,8)
k(ORz,ORc).dot(compat)

import numpy as np
TOFFOLI = np.array([[1,0,0,0,0,0,0,0],
                    [0,1,0,0,0,0,0,0],
                    [0,0,1,0,0,0,0,0],
                    [0,0,0,1,0,0,0,0],
                    [0,0,0,0,1,0,0,0],
                    [0,0,0,0,0,1,0,0],
                    [0,0,0,0,0,0,0,1],
                    [0,0,0,0,0,0,1,0]])
TOFFOLI.dot(TOFFOLI)

import numpy as np
Z1 = np.array([[0,0,0,0,0,0,0,0],
               [1,1,0,0,0,0,0,0],
               [0,0,0,0,0,0,0,0],
               [0,0,1,1,0,0,0,0],
               [0,0,0,0,0,0,0,0],
               [0,0,0,0,1,1,0,0],
               [0,0,0,0,0,0,0,0],
               [0,0,0,0,0,0,1,1]])
Z1

Z1I4 = np.array([[0,0,0,0],
                 [1,0,0,0],
                 [0,0,0,0],
                 [0,1,0,0],
                 [0,0,0,0],
                 [0,0,1,0],
                 [0,0,0,0],
                 [0,0,0,1]])
Z1I4

ZpY = np.zeros([8,8])
ZpY[0,0] = 1; ZpY[1,2] = 1; ZpY[2,1] = 1; ZpY[3,3] = 1
ZpY[4,4] = 1; ZpY[5,6] = 1; ZpY[6,5] = 1; ZpY[7,7] = 1
ZpY

Zfim = np.array([[1,0,1,0,1,0,1,0],
                 [0,1,0,1,0,1,0,1]])

Zfim.dot(TOFFOLI).dot(ZpY).dot(TOFFOLI).dot(Z1I4)

import numpy as np
fred = np.identity(8)
fred[5,5] = 0; fred[5,6] = 1
fred[6,5] = 1; fred[6,6] = 0
fred

fred.dot(fred)

import numpy as np
Fy0 = np.zeros([8,4])
Fy0[0,0] = 1; Fy0[1,1] = 1; Fy0[4,2] = 1; Fy0[5,3] = 1
Fy0

xYz = np.array([[1,1,0,0,1,1,0,0],
                [0,0,1,1,0,0,1,1]])

xYz.dot(fred).dot(Fy0)