def neg_mct_gate(lneg): neg_mct = AncillaCircuit(3) for i in lneg: neg_mct.x(i) neg_mct.ccx(0, 1, 2) for i in lneg: neg_mct.x(i) return neg_mct.to_ancilla_gate(True)
def makeIntegerComparator(num_state_qubits, value, geq=True, with_uncomp=True): """Build the comparator circuit.""" or_gate = OR(2).to_gate() qr_state = QuantumRegister(num_state_qubits, name='state') q_compare = QuantumRegister(1, name='compare') circuit = AncillaCircuit(qr_state, q_compare) circuit.addQfreeGate(or_gate) qr_ancilla = circuit.new_ancilla_register( num_state_qubits - 1, name='ancilla') if num_state_qubits > 1 else None if value <= 0: # condition always satisfied for non-positive values if geq: # otherwise the condition is never satisfied circuit.x(q_compare) # condition never satisfied for values larger than or equal to 2^n elif value < pow(2, num_state_qubits): if num_state_qubits > 1: twos = _get_twos_complement(num_state_qubits, value) for i in range(num_state_qubits): if i == 0: if twos[i] == 1: circuit.cx(qr_state[i], qr_ancilla[i]) elif i < num_state_qubits - 1: if twos[i] == 1: circuit.append( or_gate, [qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]]) else: circuit.ccx(qr_state[i], qr_ancilla[i - 1], qr_ancilla[i]) else: if twos[i] == 1: circuit.append( or_gate, [qr_state[i], qr_ancilla[i - 1], q_compare]) else: circuit.ccx(qr_state[i], qr_ancilla[i - 1], q_compare) # flip result bit if geq flag is false if not geq: circuit.x(q_compare) else: # num_state_qubits == 1 and value == 1: circuit.cx(qr_state[0], q_compare) # flip result bit if geq flag is false if not geq: circuit.x(q_compare) else: if not geq: # otherwise the condition is never satisfied circuit.x(q_compare) return circuit
def makesOracle(i, n): # Creates the oracle finding exactly i on n qubits (+ 1 for target)(or its lowest n bits if i >= 2^n) # Could use some uncomputation... ctrls = QuantumRegister(n) target = QuantumRegister(1) fcirc = AncillaCircuit(ctrls, target, name="oracle_" + str(i) + "_" + str(n)) format_str = '{0:0' + str(n) + 'b}' binary_i = format_str.format(i)[::-1] for j in range(n): if binary_i[j] == '0': fcirc.x(ctrls[j]) fcirc.mcx(ctrls[:], target[0]) for j in range(n): if binary_i[j] == '0': fcirc.x(ctrls[j]) return fcirc.to_ancilla_gate()
def makesDJ(num_qubits, oracle_gate=None): #Builds the Deutsch Jozsa circuit for n + 1 qubits, finding the value 111...111 var_reg = QuantumRegister(num_qubits, name='vals') out_reg = QuantumRegister(1, name='out') circ = AncillaCircuit(var_reg, out_reg) circ.h(var_reg) circ.x(out_reg) circ.h(out_reg) if oracle_gate: circ.append(oracle_gate, [*var_reg, out_reg[0]]) else: circ.mcx(var_reg, out_reg) circ.h(var_reg) return (circ, var_reg)
def makesGroverCircuit(n, oracle=None, nb_sols=1): # grover circuit on n qubits, without measurements as uncomp cannot deal with that yet nbIter = int(np.floor(np.pi / 4.0 * np.sqrt(pow(2, n)))) working_qubits = QuantumRegister(n, name='r') phase_qubit = QuantumRegister(1, name='p') circ = AncillaCircuit(working_qubits, phase_qubit) circ.x(phase_qubit[0]) circ.h(phase_qubit[0]) circ.h(working_qubits) for l in range(nbIter): if oracle: circ.append(oracle, [*working_qubits[:], phase_qubit[0]]) else: circ.mcx(working_qubits, phase_qubit) #Grover diffusion operator circ.h(working_qubits) circ.x(working_qubits) circ.h(working_qubits[-1]) circ.mcx(working_qubits[:-1], working_qubits[-1]) circ.h(working_qubits[-1]) circ.x(working_qubits) circ.h(working_qubits) # bring the phase qubit back to 0, we can't uncompute it, as it went through cz, non qfree -> no need to uncomp it, Qiskit doesn't #circ.h(phase_qubit[0]) #circ.x(phase_qubit) return (circ, working_qubits)
def makesAdder(num_qubits): #[a, b, s]: s = a + b, a and b made of num_qubits each # returns an AncillaCircuit, without uncomputation def neg_mct_gate(lneg): neg_mct = AncillaCircuit(3) for i in lneg: neg_mct.x(i) neg_mct.ccx(0, 1, 2) for i in lneg: neg_mct.x(i) return neg_mct.to_ancilla_gate(True) a = QuantumRegister(num_qubits, name="a") b = QuantumRegister(num_qubits, name="b") s = QuantumRegister(num_qubits, name="s") c = AncillaRegister(num_qubits, name="c") circuit = AncillaCircuit(a, b, s, c) for i in range(num_qubits - 1): #sum t = circuit.new_ancilla_register(1, name='t' + str(i)) circuit.cx(a[i], t) circuit.cx(b[i], t) #to be quipper like circuit.cx(t, s[i]) circuit.cx(c[i], s[i]) #carry v = circuit.new_ancilla_register(1, name='v' + str(i)) circuit.append(neg_mct_gate([0, 1]), [a[i], b[i], v]) circuit.append(neg_mct_gate([1]), [v, c[i], c[i + 1]]) circuit.x(c[i + 1]) circuit.cx(a[num_qubits - 1], s[num_qubits - 1]) circuit.cx(b[num_qubits - 1], s[num_qubits - 1]) circuit.cx(c[num_qubits - 1], s[num_qubits - 1]) return circuit