Exemplo n.º 1
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)
Exemplo n.º 2
0
def mcx(relative_numbers):
    from unqomp.ancillaallocation import AncillaCircuit
    from qiskit import QuantumRegister, QuantumCircuit

    n = 12

    print('MCX  ; ', end = '')
    #for qiskit 
    ctrls2 = QuantumRegister(n, 'ctrls')
    target2 = QuantumRegister(1, 'target')
    anc = QuantumRegister(n - 2, 'anc')
    circuit2 = QuantumCircuit(ctrls2, target2, anc)
    circuit2.mcx(ctrls2, target2, anc, mode = 'v-chain')
    nb_qb_qi = circuit2.num_qubits
    nb_gates_qi = circuit2.decompose().decompose().decompose().decompose().decompose().count_ops()
    if not relative_numbers:
        print(str(nb_qb_qi) + ' ; ' + str(nb_gates_qi['cx'] + nb_gates_qi['u3']) + ' ; ' + str(nb_gates_qi['cx']) + ' ; ', end = '')
    
    
    ctrls = QuantumRegister(n, 'ctrls')
    target = QuantumRegister(1, 'target')
    circuit1 = AncillaCircuit(ctrls, target)
    circuit1.mcx(ctrls, target)
    circuit1 = circuit1.circuitWithUncomputation()
    nb_qb_mi = circuit1.num_qubits
    nb_gates_mi = circuit1.decompose().decompose().decompose().decompose().decompose().count_ops()
    if not relative_numbers:
        print(str(nb_qb_mi) + ' ; ' + str(nb_gates_mi['cx'] + nb_gates_mi['u3']) + ' ; ' + str(nb_gates_mi['cx']))

    if relative_numbers:
        print_relative_vals(nb_qb_qi, nb_gates_qi['cx'], nb_gates_qi['u3'], nb_qb_mi, nb_gates_mi['cx'], nb_gates_mi['u3'])
Exemplo n.º 3
0
def mcx():
    x = QuantumRegister(10)
    r = QuantumRegister(1)
    circuit = AncillaCircuit(x, r)
    circuit.mcx(x[:], r)
    circuit = circuit.circuitWithUncomputation()
    nb_qb_mi = circuit.num_qubits
    nb_gates_mi = circuit.decompose().decompose().decompose().decompose(
    ).decompose().count_ops()
    print("MCX " + str(nb_qb_mi) + ';' +
          str(nb_gates_mi['cx'] + nb_gates_mi['u3']) + ';' +
          str(nb_gates_mi['cx']))
Exemplo n.º 4
0
    def _construct_diffusion_circuit():
        num_variable_qubits = n
        var_reg2 = QuantumRegister(num_variable_qubits)
        qc = AncillaCircuit(var_reg2)

        qc.h(var_reg2)
        qc.u(np.pi, 0, np.pi, var_reg2)
        qc.u(np.pi / 2, 0, np.pi, var_reg2[-1])
        qc.mcx(var_reg2[:-1], var_reg2[-1])
        qc.u(np.pi / 2, 0, np.pi, var_reg2[-1])
        qc.u(np.pi, 0, np.pi, var_reg2)
        qc.h(var_reg2)
        return qc
Exemplo n.º 5
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()
Exemplo n.º 6
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)
Exemplo n.º 7
0
def makeWeightedAdder(num_state_qubits, weights):
    # Straightforward implementation using Unqomp, uses less gate but more qubits
    num_sum_qubits = int(np.floor(np.log2(sum(weights))) +
                         1) if sum(weights) > 0 else 1
    # The number of sum qubits in the circuit
    num_carry_qubits = num_sum_qubits - 1
    # The number of carry qubits required to compute the sum.

    for i, weight in enumerate(weights):
        if not np.isclose(weight, np.round(weight)):
            raise ValueError('Non-integer weights are not supported!')
        weights[i] = np.round(weight)

    num_result_qubits = num_state_qubits + num_sum_qubits

    qr_state = QuantumRegister(num_state_qubits, name='state')
    qr_sum = QuantumRegister(num_sum_qubits, name='sum')
    circuit = AncillaCircuit(qr_state, qr_sum)
    #print(num_state_qubits)
    #print(num_sum_qubits)

    # loop over state qubits and corresponding weights
    for i, weight in enumerate(weights):
        # only act if non-trivial weight
        if np.isclose(weight, 0):
            continue

        # get state control qubit
        q_state = qr_state[i]

        # get bit representation of current weight
        weight_binary = '{0:b}'.format(int(weight)).rjust(num_sum_qubits,
                                                          '0')[::-1]
        #print("carry qb" + str(num_carry_qubits))
        qr_carry = circuit.new_ancilla_register(num_carry_qubits,
                                                name="anccarryite" + str(i))

        # loop over bits of current weight and add them to sum and carry registers
        for j, bit in enumerate(weight_binary):
            if bit == '1':
                if num_sum_qubits == 1:
                    circuit.cx(q_state, qr_sum[j])
                elif j == 0:
                    # compute (q_sum[0] + 1) into (q_sum[0], q_carry[0])
                    # - controlled by q_state[i]
                    circuit.ccx(q_state, qr_sum[j], qr_carry[j])
                    circuit.cx(q_state, qr_sum[j])
                elif j == num_sum_qubits - 1:
                    # compute (q_sum[j] + q_carry[j-1] + 1) into (q_sum[j])
                    # - controlled by q_state[i] / last qubit,
                    # no carry needed by construction
                    circuit.cx(q_state, qr_sum[j])
                    circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
                else:
                    # compute (q_sum[j] + q_carry[j-1] + 1) into (q_sum[j], q_carry[j])
                    # - controlled by q_state[i]
                    circuit.mcx([q_state, qr_sum[j], qr_carry[j - 1]],
                                qr_carry[j],
                                negated_ctrls=[1, 2])
                    circuit.cx(q_state, qr_carry[j])
                    circuit.cx(q_state, qr_sum[j])
                    circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
            else:
                if num_sum_qubits == 1:
                    pass  # nothing to do, since nothing to add
                elif j == 0:
                    pass  # nothing to do, since nothing to add
                elif j == num_sum_qubits - 1:
                    # compute (q_sum[j] + q_carry[j-1]) into (q_sum[j])
                    # - controlled by q_state[i] / last qubit,
                    # no carry needed by construction
                    circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
                else:
                    # compute (q_sum[j] + q_carry[j-1]) into (q_sum[j], q_carry[j])
                    # - controlled by q_state[i]
                    circuit.mcx([q_state, qr_sum[j], qr_carry[j - 1]],
                                qr_carry[j])
                    circuit.ccx(q_state, qr_carry[j - 1], qr_sum[j])
    return circuit