100% Quantum Supremacy
This commit is contained in:
parent
d0b3557854
commit
e6677cecf3
190
qG.py
Normal file
190
qG.py
Normal file
@ -0,0 +1,190 @@
|
||||
import random
|
||||
import numpy as np
|
||||
|
||||
class Gate():
|
||||
def __init__(self, childGates=[]):
|
||||
self.childGates = childGates
|
||||
self._condense()
|
||||
|
||||
def _condense(self):
|
||||
self.mat = np.identity(2)
|
||||
for gate in self.childGates:
|
||||
self.mat = np.dot(self.mat, gate.mat)
|
||||
return True
|
||||
|
||||
def __call__(self,*arg):
|
||||
if len(arg)==0:
|
||||
return self
|
||||
elif len(arg)==1:
|
||||
return self._mul(inp)
|
||||
else:
|
||||
raise Exception("NaBrO")
|
||||
|
||||
def __mul__(self, other):
|
||||
return self._mul(other)
|
||||
|
||||
def __repr__(self):
|
||||
return "<qGate ["+str(self)+"]>"
|
||||
|
||||
def __str__(self):
|
||||
return "".join(str(gate) for gate in self.childGates)
|
||||
|
||||
def _mul(self, obj):
|
||||
if isinstance(obj, Gate):
|
||||
return self._op(obj)
|
||||
elif isinstance(obj, State):
|
||||
return State(np.dot(self.mat, obj.vec))
|
||||
|
||||
def _op(self, obj):
|
||||
return Gate(self.childGates + [obj])
|
||||
|
||||
@property
|
||||
def adj(self):
|
||||
return AdjGate(self)
|
||||
|
||||
def shorten(self):
|
||||
newGates = []
|
||||
changes = 0
|
||||
i=0
|
||||
while i < len(self.childGates):
|
||||
gate = self.childGates[i]
|
||||
if i < len(self.childGates)-1:
|
||||
nextChild = self.childGates[i+1]
|
||||
else:
|
||||
nextChild = None
|
||||
changes += 1
|
||||
if np.all(gate.mat==np.identity(2)):
|
||||
pass
|
||||
elif isinstance(gate, AdjGate) and isinstance(gate.origGate, AdjGate):
|
||||
newGates.append(gate.origGate.origGate)
|
||||
elif isinstance(gate, AdjGate) and str(gate.origGate) == "H":
|
||||
newGates.append(H)
|
||||
elif isinstance(gate, AdjGate) and str(gate.origGate) == str(nextChild):
|
||||
newGates.append(gate.origGate)
|
||||
i += 1
|
||||
elif i != len(self.childGates) and isinstance(nextChild, AdjGate) and str(nextChild.origGate) == str(gate):
|
||||
newGates.append(nextChild.origGate)
|
||||
i += 1
|
||||
else:
|
||||
newGates.append(gate)
|
||||
changes -= 1
|
||||
i += 1
|
||||
|
||||
if len(newGates)==0:
|
||||
newGates = I()
|
||||
|
||||
newGate = Gate(newGates)
|
||||
|
||||
if changes != 0:
|
||||
return newGate.shorten()
|
||||
|
||||
return newGate
|
||||
|
||||
class AdjGate(Gate):
|
||||
def __init__(self, gate):
|
||||
self.origGate = gate
|
||||
self._condense()
|
||||
|
||||
def __str__(self):
|
||||
return "("+str(self.origGate)+")'"
|
||||
|
||||
def _condense(self):
|
||||
self.mat = self.origGate.mat.H
|
||||
|
||||
def _op(self, obj):
|
||||
return Gate([self, obj])
|
||||
|
||||
def shorten(self):
|
||||
wrap = Gate([self])
|
||||
return wrap.shorten()
|
||||
|
||||
class BaseGate(Gate):
|
||||
def __init__(self, mat, symb):
|
||||
self.childGates = None
|
||||
self.mat = mat
|
||||
self.symb = symb
|
||||
|
||||
def __str__(self):
|
||||
return self.symb
|
||||
|
||||
def _condense(self):
|
||||
return False
|
||||
|
||||
def _op(self, obj):
|
||||
return Gate([self, obj])
|
||||
|
||||
def shorten(self):
|
||||
wrap = Gate([self])
|
||||
return wrap.shorten()
|
||||
|
||||
class I(BaseGate):
|
||||
def __init__(self):
|
||||
super().__init__(np.matrix([[1,0],[0,1]]), "I")
|
||||
|
||||
class H(BaseGate):
|
||||
def __init__(self):
|
||||
q = 1/np.sqrt(2)
|
||||
super().__init__(np.matrix([[q,q],[q,-1*q]]), "H")
|
||||
|
||||
class X(BaseGate):
|
||||
def __init__(self):
|
||||
super().__init__(np.matrix([[0,1],[1,0]]), "X")
|
||||
|
||||
class Y(BaseGate):
|
||||
def __init__(self):
|
||||
i = complex(0, 1)
|
||||
super().__init__(np.matrix([[0,-i],[i,0]]), "Y")
|
||||
|
||||
class Z(BaseGate):
|
||||
def __init__(self):
|
||||
super().__init__(np.matrix([[1,0],[0,-1]]), "Z")
|
||||
|
||||
class T(BaseGate):
|
||||
def __init__(self, angle):
|
||||
super().__init__(np.matrix([[np.cos(angle),-1*np.sin(angle)],[np.sin(angle),np.cos(angle)]]), "T{"+str(angle)+"}")
|
||||
|
||||
class State():
|
||||
def __init__(self, array):
|
||||
self.vec = array
|
||||
|
||||
def __call__(self,*arg):
|
||||
if len(arg)==0:
|
||||
return self
|
||||
elif len(arg)==1:
|
||||
return self._mul(inp)
|
||||
else:
|
||||
raise Exception("NaBrO")
|
||||
|
||||
def __mul__(self, other):
|
||||
return self._mul(other)
|
||||
|
||||
def __repr__(self):
|
||||
return "<qState ["+str(self)+"]>"
|
||||
|
||||
def __str__(self):
|
||||
return "("+str(self.vec[0])+"|0> + "+str(self.vec[1])+"|1>)"
|
||||
|
||||
def __int__(self):
|
||||
return int(0 + 1*(random.random() < self.vec[1]**2))
|
||||
|
||||
def _mul(self, other):
|
||||
if isinstance(other, Gate):
|
||||
return State(np.dot(self.vec, other.mat))
|
||||
elif isinstance(other, State):
|
||||
return np.dot(self.vec, other.vec)
|
||||
|
||||
def measure(self):
|
||||
if random.random() < self.vec[0]**2:
|
||||
return Zero()
|
||||
else:
|
||||
return One()
|
||||
|
||||
class Zero(State):
|
||||
def __init__(self):
|
||||
super().__init__(np.array([1,0]))
|
||||
|
||||
class One(State):
|
||||
def __init__(self):
|
||||
super().__init__(np.array([0,1]))
|
||||
|
||||
I, H, X, Y, Z, One, Zero = I(), H(), X(), Y(), Z(), One(), Zero()
|
Loading…
Reference in New Issue
Block a user