Esempio n. 1
0
 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)
Esempio n. 2
0
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
Esempio n. 3
0
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()
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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