def getGateData(gatename): if isinstance(gatename, QGate): shape = (gatename.size, 2**gatename.size) else: name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if arg1 is None: arg1 = 0 if arg2 is None: arg2 = 0 if arg3 is None: arg3 = 0 if "SWAP" in name or name == "XX" or name == "YY" or name == "ZZ": shape = (2, 4) else: qgate = ct.c_void_p( __cGetQGate__(ct.c_char_p(name.encode()), ct.c_double(arg1), ct.c_double(arg2), ct.c_double(arg3), ct.c_int(int(invert)))) if ( qgate or False ) == qgate: # NOTNULLPTR and True returns True, NOTNULLPTR or False returns NOTNULLPTR nqubits = int(__cGetQGateQubits__(qgate)) size = int(__cGetQGateSize__(qgate)) shape = (nqubits, size) else: shape = None print("Error while getting the specified gate!") return shape
def getGate(gatename): name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if arg1 is None: arg1 = 0 if arg2 is None: arg2 = 0 if arg3 is None: arg3 = 0 qgate = ct.c_void_p( __cGetQGate__(ct.c_char_p(name.encode()), ct.c_double(arg1), ct.c_double(arg2), ct.c_double(arg3), ct.c_int(int(invert)))) if ( qgate or False ) == qgate: # NOTNULLPTR and True returns True, NOTNULLPTR or False returns NOTNULLPTR # nqubits = int(__cGetQGateQubits__(qgate)) size = int(__cGetQGateSize__(qgate)) plainmatrix2d = __cGet2dGate__(qgate)[:size * size * 2] rematrix2d = plainmatrix2d[:size * size] immatrix2d = plainmatrix2d[size * size:size * size * 2] matrix = np.array([ complex(rematrix2d[i], immatrix2d[i]) for i in range(size * size) ]) matrix = matrix.reshape(size, size) # print("Gate for " + str(nqubits) + " qubits with size " + str(size)) else: matrix = None print("Error while getting the specified gate!") return matrix
def _invertStrGate(gatename): selfinvert = ["X", "Y", "Z", "H", "SWAP"] name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if name not in selfinvert: if invert: gatename = gatename[:-2] else: gatename += "-1" return gatename
def _getQuBitArg(gatename): args = None if isinstance(gatename, str): qubitargs = ["XX", "YY", "ZZ"] name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if name in qubitargs or "SWAP" in name: if name in qubitargs: args = set([arg2, arg3]) else: args = set([arg1, arg2]) return args
def _addQubitOffset(gatename, offset): qubitargs = ["XX", "YY", "ZZ"] name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if name in qubitargs or "SWAP" in name: arg2 += offset if name in qubitargs: arg3 += offset else: arg1 += offset if arg1 is not None: name += "(" + str(arg1) if arg2 is not None: name += str(arg2) if arg3 is not None: name += str(arg3) + ")" if invert: name += "-1" gatename = name return gatename
def _rebuildGateName(gate): cons = set() acons = set() gatename = gate if not isinstance(gate, str) and isinstance(gate, Iterable): gatename = gate[0] if (len(gate) > 1): if gate[1] is not None: if isinstance(gate[1], Iterable) and len(gate[1]) > 0: cons = set(gate[1]) elif not isinstance(gate[1], Iterable): cons = set([gate[1]]) if (len(gate) > 2): if gate[2] is not None: if isinstance(gate[2], Iterable) and len(gate[2]) > 0: acons = set(gate[2]) elif not isinstance(gate[2], Iterable): acons = set([gate[2]]) if not isinstance(gatename, QGate): if gatename is not None and gatename.lower() != "i": name, arg1, arg2, arg3, invert = prs.getGateData(gatename) if arg1 is not None: name += "(" + str(arg1) if arg2 is not None: name += "," + str(arg2) if arg3 is not None: name += "," + str(arg3) + ")" elif arg1 is not None: name += ")" if invert: name += "-1" else: name = None else: name = gatename return [name, cons, acons] if name is not None else None
def applyGate(self, *args, **kwargs): # gate, qubit=0, control=None, anticontrol=None): optimize = True if "optimize" in kwargs: optimize = kwargs["optimize"] if len(args) == 1 or (len(args) == 2 and np.issubdtype(type(args[1]), np.integer) and "qubit" not in kwargs): for key in kwargs: if key != "qubit" and key != "control" and key != "anticontrol" and key != "optimize": raise ValueError('Apart from the gates, you can only specify "qubit", "control", "anticontrol" (lowercase) and/or optimize') gate = args[0] if type(gate) == QGate: gate = (gate, gate.size) elif gate == "I" or gate is None: return else: gate = (gate, getGateData(gate)[0]) qubit = kwargs.get("qubit", self.usable[0]) if len(args) == 2: qubit = args[1] control = kwargs.get("control", []) if control is None: control = [] if not isinstance(control, Iterable): control = [control] anticontrol = kwargs.get("anticontrol", []) if anticontrol is None: anticontrol = [] if not isinstance(anticontrol, Iterable): anticontrol = [anticontrol] if isinstance(qubit, Iterable): for qid in qubit: self.applyGate(gate[0], qubit=qid, control=control, anticontrol=anticontrol, optimize=optimize) else: name = "" if type(gate[0]) != QGate: name, arg1, arg2, arg3, invert = prs.getGateData(gate[0]) invstring = "" if invert: invstring = "-1" qubits = set(control).union(anticontrol) # Todos los participantes if "SWAP" in name: qubit = arg1 qubits.add(arg2) elif name == "XX" or name == "YY" or name == "ZZ": qubit = arg2 qubits.add(arg3) else: qubits.update([qubit + i for i in range(1, gate[1])]) # print("Participants: " + str([qubit] + list(qubits))) rid = self.qubitMap[qubit] for qid in qubits: self.superposition(rid, self.qubitMap[qid]) reg, idlist = self.regs[rid] # print("RDATA: [" + str(reg.getNQubits()) + ", " + str(idlist) + "]") regmap = {idlist[i]: i for i in range(len(idlist))} newqubit = regmap[qubit] newcontrol = [regmap[qid] for qid in control] newanticontrol = [regmap[qid] for qid in anticontrol] if type(gate[0]) == QGate: reg.applyGate(gate[0], qubit=newqubit, control=newcontrol, anticontrol=newanticontrol, optimize=optimize) else: if "SWAP" in name: gate = (name + "(" + str(regmap[arg1]) + "," + str(regmap[arg2]) + ")" + invstring, gate[1]) if name == "XX" or name == "YY" or name == "ZZ": gate = (name + "(" + str(arg1) + "," + str(regmap[arg2]) + "," + str(regmap[arg3]) + ")" + invstring, gate[1]) # print(gate[0]) reg.applyGate(gate[0], qubit=newqubit, control=newcontrol, anticontrol=newanticontrol, optimize=optimize) elif len(kwargs) == 0 and len(args) > 0: nq = 0 gates = [] for arg in args: if type(arg) == QGate: gatenq = (arg, arg.size) elif arg == "I" or arg is None: gatenq = (None, 1) else: gatenq = (arg, getGateData(arg)[0]) nq += gatenq[1] gates.append(gatenq) #print(gates) if nq == self.getNQubits(): qid = 0 for gate in gates: if gate[0] is not None: self.applyGate(gate[0], qubit=qid, optimize=optimize) qid += gate[1] else: print("You have to specify a gate for each QuBit (or None if you don't want to operate with it)") elif len(args) == 0: print("You must specify at least one gate") else: print("You can't apply more than one gate when using " + '"qubit", "control" or "anticontrol"')
def applyGate(self, gate, qubit=0, control=None, anticontrol=None, optimize=True): if np.issubdtype( type(qubit), np.integer) and qubit < self.getNQubits() and qubit >= 0: ''' print("Gate:", gate) print("Target:", qubit) print("Control:", control) print("Anticontrol:", anticontrol) ''' if not isinstance(control, Iterable) and type( control) != int and not (control is None): raise ValueError( "Control must be an int, a list of ints or None!") elif not isinstance(anticontrol, Iterable) and type( anticontrol) != int and not (anticontrol is None): raise ValueError( "Anticontrol must be an int, a list of ints or None!") elif isinstance(control, Iterable) and isinstance( anticontrol, Iterable) and len(set(control) & set(anticontrol)) > 0: raise ValueError("A control can't be an anticontrol!") else: allOk = True clen = 0 if np.issubdtype(type(control), np.integer): int_array = ct.c_int * 1 control = int_array(control) clen = 1 elif control is None or len(control) == 0: control = c_int_p() clen = 0 else: control = set(control) clen = len(control) int_array = ct.c_int * clen control = int_array(*control) allOk = all(0 <= id < self.getNQubits() for id in control) aclen = 0 if np.issubdtype(type(anticontrol), np.integer): int_array = ct.c_int * 1 anticontrol = int_array(control) aclen = 1 elif anticontrol is None or len(anticontrol) == 0: anticontrol = c_int_p() aclen = 0 else: anticontrol = set(anticontrol) aclen = len(anticontrol) int_array = ct.c_int * aclen anticontrol = int_array(*anticontrol) allOk = allOk and all(0 <= id < self.getNQubits() for id in anticontrol) if allOk: if type(gate) == str: name, arg1, arg2, arg3, invert = getGateData(gate) if arg1 is None: arg1 = 0 if arg2 is None: arg2 = 0 if arg3 is None: arg3 = 0 if (name.lower() == "swap"): __SWAPQubits__(self.reg, arg1, arg2, False, False, invert, control, clen, anticontrol, aclen) elif (name.lower() == "iswap"): __SWAPQubits__(self.reg, arg1, arg2, True, False, invert, control, clen, anticontrol, aclen) elif (name.lower() == "sqrtswap"): __SWAPQubits__(self.reg, arg1, arg2, False, True, invert, control, clen, anticontrol, aclen) elif (name.lower() == "xx"): __IsingQubits__(self.reg, 0, arg1, arg2, arg3, invert, control, clen, anticontrol, aclen) elif (name.lower() == "yy"): __IsingQubits__(self.reg, 1, arg1, arg2, arg3, invert, control, clen, anticontrol, aclen) elif (name.lower() == "zz"): __IsingQubits__(self.reg, 2, arg1, arg2, arg3, invert, control, clen, anticontrol, aclen) else: if int( __cApplyGate__(self.reg, ct.c_char_p(name.encode()), ct.c_double(arg1), ct.c_double(arg2), ct.c_double(arg3), ct.c_int(int(invert)), ct.c_int(qubit), control, ct.c_int(clen), anticontrol, ct.c_int(aclen))) == 0: print( "Error applying gate to specified QuBit!") elif type(gate) == QGate: gate._applyGate(self, qubit, control[:clen], anticontrol[:aclen], optimize=optimize) else: print("The ids must be between 0 and " + str(self.getNQubits)) else: if not np.issubdtype(type(qubit), np.integer): print("Qubit must be of integer type!") elif qubit >= self.getNQubits() or qubit < 0: print("The specified qubit doesn't exist!")