From e6677cecf3071c85e6524cfab02f98d5d3f2ad8c Mon Sep 17 00:00:00 2001 From: Dominik Roth Date: Thu, 8 Jul 2021 18:39:45 +0200 Subject: [PATCH] 100% Quantum Supremacy --- qG.py | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 qG.py diff --git a/qG.py b/qG.py new file mode 100644 index 0000000..c375377 --- /dev/null +++ b/qG.py @@ -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 "" + + 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 "" + + 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()