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
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)
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)
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
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