def qft(a = 11, param = "draw"): # Initialisation if param == "draw": drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) else: eng = MainEngine() [La, n] = int2bit(a) xa = eng.allocate_qureg(n) # initialisation de a et b for i in range(n): if La[i]: X | xa[i] # On passe de a a phi(a) : QTF eng.flush() QFT | xa eng.flush() if param != "draw": amp_xa = [] for i in range(1 << n): phase_reel = phase(eng.backend.get_amplitude(adapt_binary(bin(i), n), xa)) / (2 * math.pi) amp_xa.append(Fraction(phase_reel).limit_denominator(10)) print(amp_xa) All(Measure) | xa eng.flush() if param == "draw": print(drawing_engine.get_latex())
def run_adder(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) [xa, xb] = initialisation(eng2, a, b) adder(eng2, xa, xb) measure(eng2, xa, xb) print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) [xa, xb] = initialisation(eng, a, b) adder(eng, xa, xb) print(measure(eng, xa, xb))
def draw_algorithm(algorithm, num_qubits=None, name="test"): """ Draw circuit of corresponding algorithm. algorithm: list of strs, gate sequence. num_qubits: int, number of qubits for algorithm. Can be None, in which case the algorithm will be run on the minimum number of qubits required. name: str, the resulting tex file will be written to name.tex. return: None. """ #TODO: include drawing of measure gates. if num_qubits is None: num_qubits = get_num_qubits(algorithm) drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) qureg = eng.allocate_qureg(num_qubits) for gate in algorithm: if "measure" not in gate.lower(): apply_gate(gate, qureg) else: _, gate_args = get_gate_info(gate) ops.Measure | qureg[gate_args[0]] eng.flush() with open("%s.tex" % name, "w") as f: f.write(drawing_engine.get_latex())
def run_inv(a=11, b=1, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet(modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter] # create a main compiler engine a1 = a b1 = b if a == 0: a1 = 1 if b == 0: b1 = 1 n = max(int(math.log(a1, 2)), int(math.log(b1, 2))) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xa = initialisation_n(eng2, a, n + 1) xb = initialisation_n(eng2, b, n + 1) # b --> phi(b) QFT | xb phi_adder(eng2, xa, xb) with Dagger(eng2): QFT | xb All(Measure) | xa All(Measure) | xb eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) xa = initialisation_n(eng, a, n + 1) xb = initialisation_n(eng, b, n + 1) # b --> phi(b) QFT | xb with Dagger(eng): phi_adder(eng, xa, xb) with Dagger(eng): QFT | xb All(Measure) | xa All(Measure) | xb eng.flush() n = n+1 measurements_a = [0] * n measurements_b = [0] * n for k in range(n): measurements_a[k] = int(xa[k]) measurements_b[k] = int(xb[k]) return [measurements_a, meas2int(measurements_b), measurements_b]
def create_eng(path): drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) create_circuit(eng, path) eng.flush() with open('circuit.tex', 'w') as f: #print >> f, 'Filename:', filename # Python 2.x #print('Filename:', filename, file=f) # Python 3.x print(drawing_engine.get_latex(), file=f)
def test_print_circuit_diagram(self): """ This function shows how to print LaTeX-based circuit diagrams. """ drawer = CircuitDrawer() engine = MainEngine(drawer) qubits = engine.allocate_qureg(3) All(H) | qubits X | qubits[2] CNOT | (qubits[2], qubits[0]) for qubit in qubits: Measure | qubit engine.flush() print(drawer.get_latex())
def run(args, param="simulation"): """ Be careful the Measure command can take a lot of time to execute as you can create as much as qubit as you want :param args: list of int :param param: choose between simulation or latex :return: """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) Xreg = initialisation(eng2, args) m = len(Xreg) All(Measure) | Xreg eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) Xreg = initialisation(eng, args) m = len(Xreg) n = Xreg[0].__len__() for i in range(m): All(Measure) | Xreg[i] eng.flush() measurement = [] for i in range(m): measurement.append([0] * n) for k in range(n): measurement[i][k] = int(Xreg[i][k]) return measurement
def run(a=11, b=1, N=12, param="simulation"): # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine n = int(math.log(N, 2)) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xN = initialisation_n(eng2, N, n + 1) xa = initialisation_n(eng2, a, n + 1) xb = initialisation_n(eng2, b, n + 1) c1 = initialisation_n(eng2, 1) c2 = initialisation_n(eng2, 1) aux = initialisation_n(eng2, 0) # b --> phi(b) QFT | xb modularAdder(eng2, xa, xb, xN, c1, c2, aux) with Dagger(eng2): QFT | xb Measure | c1 Measure | c2 Measure | aux All(Measure) | xa All(Measure) | xb All(Measure) | xN eng2.flush() print(drawing_engine.get_latex()) else: eng = MainEngine(Simulator(), compilerengines) xN = initialisation_n(eng, N, n + 1) xa = initialisation_n(eng, a, n + 1) xb = initialisation_n(eng, b, n + 1) [c1, c2, aux] = initialisation(eng, [1, 1, 0]) # b --> phi(b) QFT | xb modularAdder(eng, xa, xb, xN, c1, c2, aux) with Dagger(eng): QFT | xb Measure | c1 Measure | c2 Measure | aux All(Measure) | xa All(Measure) | xb All(Measure) | xN eng.flush() measurements_a = [0] * n measurements_b = [0] * n measurements_N = [0] * n for k in range(n): measurements_a[k] = int(xa[k]) measurements_b[k] = int(xb[k]) measurements_N[k] = int(xN[k]) return [ measurements_a, measurements_b, int(xb[n]), measurements_N, int(aux[0]), int(c1[0]), int(c2[0]), meas2int(measurements_b), (a + b) % N ]
from projectq import MainEngine from projectq.backends import CircuitDrawer import teleport if __name__ == "__main__": # create a main compiler engine with a simulator backend: drawing_engine = CircuitDrawer() locations = {0: 1, 1: 2, 2: 0} drawing_engine.set_qubit_locations(locations) eng = MainEngine(drawing_engine) # we just want to draw the teleportation circuit def create_state(eng, qb): pass # run the teleport and then, let Bob try to uncompute his qubit: teleport.run_teleport(eng, create_state, verbose=False) # print latex code to draw the circuit: print(drawing_engine.get_latex())
def run(a=4, N=7, x=2, param="run"): """ :param a: a<N and must be invertible mod[N] :param N: :param x: :param param: :return: |1> --> |(a**x) mod N> """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine a = a % N b = 0 n = int(math.log(N, 2)) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng = MainEngine(drawing_engine) if param == "count": eng = MainEngine(resource_counter) else: eng = MainEngine(Simulator(), compilerengines) output = initialisation_n(eng, 1, n + 1) xN = initialisation_n(eng, N, n + 1) xx = initialisation_n(eng, x, n + 1) xb = initialisation_n(eng, b, n + 1) aux = initialisation_n(eng, 0, 1) expoModN(eng, a, output, xb, xN, aux, xx, N) Measure | aux All(Measure) | output All(Measure) | xx All(Measure) | xb All(Measure) | xN eng.flush() if param == "count": return resource_counter if param == "latex": print(drawing_engine.get_latex()) measurements_b = [0] * n measurements_x = [0] * n measurements_N = [0] * n for k in range(n): measurements_b[k] = int(xb[k]) measurements_N[k] = int(xN[k]) measurements_x[k] = int(output[k]) mes_aux = int(aux[0]) assert int(xb[n]) == 0 assert int(xN[n]) == 0 assert int(xx[n]) == 0 assert meas2int(measurements_b) == 0 assert meas2int(measurements_N) == N assert mes_aux == 0 return [(a**x) % N, meas2int(measurements_x), measurements_x]
from projectq import MainEngine from projectq.backends import CircuitDrawer from projectq.ops import All, CNOT, H, Measure, Rz, X, Z def getBellPair(engine): bit1 = engine.allocate_qubit() bit2 = engine.allocate_qubit() H | bit1 CNOT | (bit1, bit2) return bit1, bit2 circuit_drawer = CircuitDrawer() engine = MainEngine(circuit_drawer) getBellPair(engine) engine.flush() print(circuit_drawer.get_latex())
def run(a=4, b=6, N=7, x=2, param="count"): """ Last update 19/02 : nb of gate linear in log(N) Be careful this algo is a bit long to execute |b> --> |b+(ax) mod N> works for :param a: :param b: :param N: :param x: :param param: :return: """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine n = int(math.log(N, 2)) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xN = initialisation_n(eng2, N, n + 1) xx = initialisation_n(eng2, x, n + 1) xb = initialisation_n(eng2, b, n + 1) [xc, aux] = initialisation(eng2, [1, 0]) cMultModN_non_Dagger(eng2, a, xb, xx, xN, aux, xc) eng2.flush() Measure | aux Measure | xc All(Measure) | xx All(Measure) | xb All(Measure) | xN eng2.flush() print(drawing_engine.get_latex()) else: if param == "count": eng = MainEngine(resource_counter) else: eng = MainEngine(Simulator(), compilerengines) xN = initialisation_n(eng, N, n + 1) xx = initialisation_n(eng, x, n + 1) xb = initialisation_n(eng, b, n + 1) [aux, xc] = initialisation(eng, [0, 1]) cMultModN_non_Dagger(eng, a, xb, xx, xN, aux, xc, N) Measure | aux Measure | xc All(Measure) | xx All(Measure) | xb All(Measure) | xN eng.flush() if param == "count": return resource_counter measurements_b = [0] * n measurements_x = [0] * n measurements_N = [0] * n for k in range(n): measurements_b[k] = int(xb[k]) measurements_N[k] = int(xN[k]) measurements_x[k] = int(xx[k]) mes_aux = int(aux[0]) mes_c = int(aux[0]) return [ measurements_b, meas2int(measurements_b), (b + a * x) % N, measurements_N, measurements_x, mes_aux, mes_c, meas2int(measurements_b), meas2int(measurements_N), meas2int(measurements_x) ]
def run(a=4, N=7, x=2, param="count"): """ |b> --> |b+(ax) mod N> nb of gate ~454*log2(N) :param a: a<N and must be invertible mod[N] :param N: :param x: :param param: :return: """ # build compilation engine list resource_counter = ResourceCounter() rule_set = DecompositionRuleSet( modules=[projectq.libs.math, projectq.setups.decompositions]) compilerengines = [ AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), AutoReplacer(rule_set), TagRemover(), LocalOptimizer(3), resource_counter ] # create a main compiler engine a = a % N inv_a = mod_inv(a, N) b = 0 n = int(math.log(N, 2)) + 1 if param == "latex": drawing_engine = CircuitDrawer() eng2 = MainEngine(drawing_engine) xN = initialisation_n(eng2, N, n + 1) xx = initialisation_n(eng2, x, n + 1) xb = initialisation_n(eng2, b, n + 1) [xc, aux] = initialisation(eng2, [1, 0]) gateUa(eng2, a, inv_a, xx, xb, xN, aux, xc, N) eng2.flush() Measure | aux Measure | xc All(Measure) | xx All(Measure) | xb All(Measure) | xN eng2.flush() print(drawing_engine.get_latex()) else: if param == "count": eng = MainEngine(resource_counter) else: eng = MainEngine(Simulator(), compilerengines) xN = initialisation_n(eng, N, n + 1) xx = initialisation_n(eng, x, n + 1) xb = initialisation_n(eng, b, n + 1) [xc, aux] = initialisation(eng, [1, 0]) gateUa(eng, a, inv_a, xx, xb, xN, aux, xc, N) Measure | aux Measure | xc All(Measure) | xx All(Measure) | xb All(Measure) | xN eng.flush() if param == "count": return resource_counter measurements_b = [0] * n measurements_x = [0] * n measurements_N = [0] * n for k in range(n): measurements_b[k] = int(xb[k]) measurements_N[k] = int(xN[k]) measurements_x[k] = int(xx[k]) mes_aux = int(aux[0]) mes_c = int(aux[0]) assert int(xb[n]) == 0 assert int(xN[n]) == 0 assert int(xx[n]) == 0 assert meas2int(measurements_b) == 0 assert meas2int(measurements_N) == N assert mes_aux == 0 return [(a * x) % N, meas2int(measurements_x), measurements_x, mes_c]
from projectq import MainEngine # import the main compiler engine from projectq.ops import C, X, H, Measure # import the operations we want to perform (Hadamard and measurement) from projectq.backends import CircuitDrawer circuit_backend = CircuitDrawer() eng = MainEngine( circuit_backend) # create a default compiler (the back-end is a simulator) qubit = eng.allocate_qubit() # allocate a quantum register with 1 qubit qureg = eng.allocate_qureg(5) # how about a list of qubits? lq = (qureg[0], qureg[1], qureg[3], qureg[4]) H | qubit # apply a Hadamard gate Measure | qubit # measure the qubit C(X, 3) | (qureg[0], qureg[1], qureg[2], qureg[3]) C(X, 3) | lq eng.flush() # flush all gates (and execute measurements) print( "Measured {}".format(int(qubit)) ) # converting a qubit to int or bool gives access to the measurement result print(circuit_backend.get_latex())
def zoo_profile(): """Generate and display the zoo of quantum gates.""" # create a main compiler engine with a drawing backend drawing_engine = CircuitDrawer() locations = {0: 1, 1: 2, 2: 0, 3: 3} drawing_engine.set_qubit_locations(locations) main_eng = MainEngine(drawing_engine) qureg = main_eng.allocate_qureg(4) # define a zoo of gates te_gate = TimeEvolution(0.5, 0.1 * QubitOperator('X0 Y2')) def add(x, y): return x, y + 1 zoo = [ (X, 3), (Y, 2), (Z, 0), (Rx(0.5), 2), (Ry(0.5), 1), (Rz(0.5), 1), (Ph(0.5), 0), (S, 3), (T, 2), (H, 1), (Toffoli, (0, 1, 2)), (Barrier, None), (Swap, (0, 3)), (SqrtSwap, (0, 1)), (get_inverse(SqrtSwap), (2, 3)), (SqrtX, 2), (C(get_inverse(SqrtX)), (0, 2)), (C(Ry(0.5)), (2, 3)), (CNOT, (2, 1)), (Entangle, None), (te_gate, None), (QFT, None), (Tensor(H), None), (BasicMathGate(add), (2, 3)), (All(Measure), None), ] # apply them for gate, pos in zoo: if pos is None: gate | qureg elif isinstance(pos, tuple): gate | tuple(qureg[i] for i in pos) else: gate | qureg[pos] main_eng.flush() # generate latex code to draw the circuit s = drawing_engine.get_latex() prefix = 'zoo' with open('{}.tex'.format(prefix), 'w') as f: f.write(s) # compile latex source code and open pdf file os.system('pdflatex {}.tex'.format(prefix)) openfile('{}.pdf'.format(prefix))
from Bell_States_Generator import bell_state from Quantum_Teleportation import quantum_teleportation from projectq import MainEngine from projectq.backends import CircuitDrawer from projectq.ops import H,Rz import os drawer=CircuitDrawer() eng=MainEngine(drawer) qubit_psi=eng.allocate_qubit() H|qubit_psi Rz(1.32)|qubit_psi quantum_teleportation(eng,qubit_psi) eng.flush() with open("./circuit_plot/quantum_teleportation.tex","w") as f: f.write(drawer.get_latex())
class DHAOracle: def __init__(self, delta, numBits, ancillaBit=None): self.C = C self.X = X self.H = H self.Barrier = Barrier self.delta = delta self.numBits = numBits self.delta_bin = np.binary_repr(delta, numBits) self.delta_bin = [int(i) for i in self.delta_bin] self.gatesList = [] self.reverseGatesList = [] self.circuit_drawer = CircuitDrawer() self.diag_eng = MainEngine(self.circuit_drawer) self.valreg = self.diag_eng.allocate_qureg(self.numBits) self.refreg = self.diag_eng.allocate_qureg(self.numBits) if (ancillaBit is None): self.ancilla = self.diag_eng.allocate_qureg(1) else: self.ancilla = ancillaBit # old qiskit ver # self.valreg = QuantumRegister(self.numBits, 'val') # self.refreg = QuantumRegister(self.numBits, 'reg') # self.qc = QuantumCircuit(self.valreg, self.refreg) # self.circdrawer = circuit_drawer(self.qc) def makeGates(self, delta_bin=None): if delta_bin is None: delta_bin = self.delta_bin idx = 0 # current bit cidx = 0 # current control bit prefix = [] # initialize with no prefixes while (idx<len(delta_bin)): # debug print (idx) # Condition 0. For each 0 at the start, place a simple CNOT. if delta_bin[idx] == 0: print('Condition 0') self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]])) idx = idx+1 # move to next bit/next iteration cidx = cidx+1 # Condition 1. All remaining bits are 1. E.g. 11111, 01111 etc. elif np.all(delta_bin[idx:]): print('Condition 1') self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[i] for i in range(idx, len(delta_bin))]) + tuple([self.refreg[cidx]])) print('Exited at idx ' + str(idx)) # DEBUG idx = len(delta_bin) # end the loop, early stopping # Condition 2a. Current bit is 1, rest are 0. E.g. 01000 etc. elif np.all(np.logical_not(delta_bin[idx+1:])) and delta_bin[idx] == 1: print('Condition 2a') self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]])) print('Exited at idx ' + str(idx)) # DEBUG idx = len(delta_bin) # early stopping # Condition 2b. Current bit is 1. End of sequence. elif (idx == len(delta_bin)-1) and delta_bin[idx] == 1: print('Condition 2b') self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]])) print('Exited at idx ' + str(idx)) # DEBUG idx = len(delta_bin) # early stopping # Condition 3. Current bit is 1. All special cases failed. elif (delta_bin[idx] == 1): print('Condition 3') prefix.append(idx) idx = idx + 1 # but we don't need to move cidx # Condition 4. Current bit is 0. All special cases failed. elif (delta_bin[idx] == 0): print('Condition 4') # attach all existing prefixes, and write a toffoli with a node at the 0 self.gatesList.append(tuple([self.valreg[prefix[i]] for i in range(len(prefix))]) + tuple([self.valreg[idx]]) + tuple([self.refreg[cidx]])) idx = idx + 1 else: print('Unknown conditions') # implement the gates for i in range(len(self.gatesList)): print(self.gatesList[i]) # implement the gate self.C(X,len(self.gatesList[i])-1) | self.gatesList[i] # Barrier for neatness? self.Barrier | (self.valreg, self.refreg, self.ancilla) # implement X gates on 0 bits for i in range(len(delta_bin)): if (delta_bin[i] == 0): self.X | self.refreg[i] # implement Hadamard on ancilla self.H | self.ancilla # implement centre Toffoli self.C(X,len(delta_bin)) | (self.refreg, self.ancilla) # == and then implement all the reverses == # implement Hadamard on ancilla self.H | self.ancilla # implement X gates on 0 bits for i in range(len(delta_bin)): if (delta_bin[i] == 0): self.X | self.refreg[i] # Barrier for neatness? self.Barrier | (self.valreg, self.refreg, self.ancilla) # implement the gates for i in range(len(self.gatesList)-1, -1, -1): print(self.gatesList[i]) # implement the gate self.C(X,len(self.gatesList[i])-1) | self.gatesList[i] # flush gates self.diag_eng.flush() def showGates(self, adjustBarrier=False): text2print = self.circuit_drawer.get_latex() if adjustBarrier: # fix the barrier text to be vertical text2print = text2print.replace("Barrier", "\\rotatebox{90}{Barrier}") print('\n') print(text2print) return text2print