def _build_internal_circuit(self) -> qiskit.QuantumCircuit:
        state_reg = create_register(self._q_op.num_target_qubits, name='state')
        output_reg = create_register(self.num_output_qubits, name='output')
        ancilla_reg = create_register(
            max(self._a_op.num_ancillas, self._q_op.num_ancillas),
            name='ancilla', reg_type='ancilla'
        )
        circuit = create_circuit(state_reg, output_reg, ancilla_reg, name=self.name)

        # reverse qubits
        output_reg = output_reg[::-1]

        # apply A operator
        self._a_op(circuit, state_reg, ancilla_reg)

        # apply Hadamard on output register
        circuit.h(output_reg)

        # apply controlled-Q operator
        for k, q in enumerate(output_reg):
            for _ in range(2**k):
                self._q_op(circuit, q, state_reg, ancilla_reg)

        # reverse qubits
        output_reg = output_reg[::-1]

        # apply inverse QFT
        qft(circuit, output_reg, do_swaps=False, inverse=True)

        return circuit
Esempio n. 2
0
    def test_qft_add(self):
        value = 2
        n = 5
        qreg = qiskit.QuantumRegister(n)
        qc = qiskit.QuantumCircuit(qreg)
        qft(qc, qreg, do_swaps=False, classical_input=[0] * n)
        aq.qft_add(qc, qreg[::-1], value)
        qft(qc, qreg, do_swaps=False, inverse=True)

        sv = get_statevector(qc)
        expected_sv = np.zeros(2**n)
        expected_sv[value] = 1
        np.testing.assert_array_almost_equal(sv, expected_sv)
Esempio n. 3
0
    def test_qft_add_fraction(self):
        value = 2.5
        n = 5
        qreg = qiskit.QuantumRegister(n)
        qc = qiskit.QuantumCircuit(qreg)
        qft(qc, qreg, do_swaps=False, classical_input=[0] * n)
        aq.qft_add(qc, qreg[::-1], value)
        qft(qc, qreg, do_swaps=False, inverse=True)

        sv = get_statevector(qc)
        prob = (sv * sv.conj()).real

        shift = 2**(n - 1) - int(value)
        x_values = np.roll(np.arange(2**n) - shift, -shift)
        mean = prob @ x_values
        self.assertAlmostEqual(mean, value, 1)
Esempio n. 4
0
def phase_estimate(
    circuit: qiskit.QuantumCircuit,
    qreg_out: qiskit.QuantumRegister,
    qreg_ancilla: qiskit.QuantumRegister,
    c_op,  # controlled-U operator
    measure: typing.Optional[bool] = True,
    creg: typing.Optional[qiskit.ClassicalRegister] = None,
) -> qiskit.QuantumCircuit:
    """
    Quantum phase estimation
    :param circuit: QuantumCircuit object
    :param qreg_out: output quantum register
    :param qreg_ancilla: target register on which the U operator is applied
    :param c_op: controlled-U operator
    :param measure: (optional) if True, measure the output qubits at the end
    :param creg: (optional) classical register for measurement results
    :return: Quantum circuit
    """
    # initialize output qubits to equal superposition
    list(map(circuit.h, qreg_out))

    # apply controlled-U
    for k, control in enumerate(reversed(qreg_out)):
        c_op(circuit, 2**k, control, qreg_ancilla)

    # reverse qubits -- only needed if not using reversed(qreg_out) when applying controlled-U above
    # swap_qubits(qc, qout)

    # apply inverse QFT
    qft(circuit, qreg_out, do_swaps=False, inverse=True)

    # measure
    if measure:
        if creg is None:
            creg = qiskit.ClassicalRegister(len(qreg_out), name='c')
            circuit.add_register(creg)
        for qbit, cbit in zip(qreg_out, creg):
            circuit.measure(qbit, cbit)

    return circuit
Esempio n. 5
0
def fft_by_qft(x, inverse=False, use_classical_swaps=False):
    # QFT = inverse classical DFT
    inverse = not inverse
    # number of qubits
    n = int(np.log2(len(x)))
    assert len(x) == 2 ** n, "Length of x should be a power of 2"
    # construct circuit
    qreg = qiskit.QuantumRegister(n)
    qc = qiskit.QuantumCircuit(qreg)
    # initialize circuit with input state vector
    qc.initialize(x, qreg)
    # reverse qubit order classically -- inverse QFT
    if use_classical_swaps and inverse:
        qreg = qreg[::-1]
    # apply QFT
    qft.qft(qc, qreg, do_swaps=not use_classical_swaps, inverse=inverse)
    # execute circuit
    result = utils.qiskit_utils.get_statevector(qc)
    # reverse qubit order classically -- forward QFT
    if use_classical_swaps:
        result = qft.reorder_qft(result)
    return result