예제 #1
0
    def test_qpe_Xplus(self, state):
        """eigenproblem X, |+>"""
        unitary_circuit = X.to_circuit()
        if state == 'minus':  # prepare |->
            state_preparation = X.to_circuit()
            state_preparation.h(0)
        else:  # prepare |+>
            state_preparation = H.to_circuit()

        phase = self.one_phase(unitary_circuit, state_preparation)
        if state == 'minus':
            self.assertEqual(phase, 0.5)
        else:
            self.assertEqual(phase, 0.0)
예제 #2
0
 def test_check_num_iterations(self):
     """test check for num_iterations greater than zero"""
     unitary_circuit = X.to_circuit()
     state_preparation = None
     with self.assertRaises(ValueError):
         self.one_phase(unitary_circuit,
                        state_preparation,
                        num_iterations=-1)
예제 #3
0
 def test_qpe_X_plus_minus(self, state_preparation, expected_phase,
                           phase_estimator):
     """eigenproblem X, (|+>, |->)"""
     unitary_circuit = X.to_circuit()
     phase = self.one_phase(unitary_circuit,
                            state_preparation,
                            phase_estimator=phase_estimator)
     self.assertEqual(phase, expected_phase)
예제 #4
0
    def test_qpe_Z1(self, backend_type):
        """eigenproblem Z, |1>"""
        backend = qiskit.BasicAer.get_backend(backend_type)

        unitary_circuit = Z.to_circuit()
        state_preparation = X.to_circuit()  # prepare |1>
        phase = self.one_phase(unitary_circuit,
                               state_preparation,
                               backend=backend)
        self.assertEqual(phase, 0.5)
예제 #5
0
    def test_single_pauli_op(self):
        """Two eigenvalues from Pauli sum with X, Y, Z"""
        hamiltonian = Z
        state_preparation = None

        result = self.hamiltonian_pe(hamiltonian,
                                     state_preparation,
                                     evolution=None)
        eigv = result.most_likely_eigenvalue
        with self.subTest("First eigenvalue"):
            self.assertAlmostEqual(eigv, 1.0, delta=0.001)

        state_preparation = StateFn(X.to_circuit())

        result = self.hamiltonian_pe(hamiltonian,
                                     state_preparation,
                                     bound=1.05)
        eigv = result.most_likely_eigenvalue
        with self.subTest("Second eigenvalue"):
            self.assertAlmostEqual(eigv, -0.98, delta=0.01)
예제 #6
0
class TestPhaseEstimation(QiskitAlgorithmsTestCase):
    """Evolution tests."""

    # pylint: disable=invalid-name
    def one_phase(
        self,
        unitary_circuit,
        state_preparation=None,
        backend_type=None,
        phase_estimator=None,
        num_iterations=6,
    ):
        """Run phase estimation with operator, eigenvalue pair `unitary_circuit`,
        `state_preparation`. Return the estimated phase as a value in :math:`[0,1)`.
        """
        if backend_type is None:
            backend_type = "qasm_simulator"
        backend = qiskit.BasicAer.get_backend(backend_type)
        qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000)
        if phase_estimator is None:
            phase_estimator = IterativePhaseEstimation
        if phase_estimator == IterativePhaseEstimation:
            p_est = IterativePhaseEstimation(num_iterations=num_iterations,
                                             quantum_instance=qi)
        elif phase_estimator == PhaseEstimation:
            p_est = PhaseEstimation(num_evaluation_qubits=6,
                                    quantum_instance=qi)
        else:
            raise ValueError("Unrecognized phase_estimator")
        result = p_est.estimate(unitary=unitary_circuit,
                                state_preparation=state_preparation)
        phase = result.phase
        return phase

    @data(
        (X.to_circuit(), 0.5, "statevector_simulator",
         IterativePhaseEstimation),
        (X.to_circuit(), 0.5, "qasm_simulator", IterativePhaseEstimation),
        (None, 0.0, "qasm_simulator", IterativePhaseEstimation),
        (X.to_circuit(), 0.5, "qasm_simulator", PhaseEstimation),
        (None, 0.0, "qasm_simulator", PhaseEstimation),
        (X.to_circuit(), 0.5, "statevector_simulator", PhaseEstimation),
    )
    @unpack
    def test_qpe_Z(self, state_preparation, expected_phase, backend_type,
                   phase_estimator):
        """eigenproblem Z, |0> and |1>"""
        unitary_circuit = Z.to_circuit()
        phase = self.one_phase(
            unitary_circuit,
            state_preparation,
            backend_type=backend_type,
            phase_estimator=phase_estimator,
        )
        self.assertEqual(phase, expected_phase)

    @data(
        (H.to_circuit(), 0.0, IterativePhaseEstimation),
        ((H @ X).to_circuit(), 0.5, IterativePhaseEstimation),
        (H.to_circuit(), 0.0, PhaseEstimation),
        ((H @ X).to_circuit(), 0.5, PhaseEstimation),
    )
    @unpack
    def test_qpe_X_plus_minus(self, state_preparation, expected_phase,
                              phase_estimator):
        """eigenproblem X, (|+>, |->)"""
        unitary_circuit = X.to_circuit()
        phase = self.one_phase(unitary_circuit,
                               state_preparation,
                               phase_estimator=phase_estimator)
        self.assertEqual(phase, expected_phase)

    @data(
        (X.to_circuit(), 0.125, IterativePhaseEstimation),
        (I.to_circuit(), 0.875, IterativePhaseEstimation),
        (X.to_circuit(), 0.125, PhaseEstimation),
        (I.to_circuit(), 0.875, PhaseEstimation),
    )
    @unpack
    def test_qpe_RZ(self, state_preparation, expected_phase, phase_estimator):
        """eigenproblem RZ, (|0>, |1>)"""
        alpha = np.pi / 2
        unitary_circuit = QuantumCircuit(1)
        unitary_circuit.rz(alpha, 0)
        phase = self.one_phase(unitary_circuit,
                               state_preparation,
                               phase_estimator=phase_estimator)
        self.assertEqual(phase, expected_phase)

    def test_check_num_iterations(self):
        """test check for num_iterations greater than zero"""
        unitary_circuit = X.to_circuit()
        state_preparation = None
        with self.assertRaises(ValueError):
            self.one_phase(unitary_circuit,
                           state_preparation,
                           num_iterations=-1)

    def phase_estimation(
        self,
        unitary_circuit,
        state_preparation=None,
        num_evaluation_qubits=6,
        backend=None,
        construct_circuit=False,
    ):
        """Run phase estimation with operator, eigenvalue pair `unitary_circuit`,
        `state_preparation`. Return all results
        """
        if backend is None:
            backend = qiskit.BasicAer.get_backend("statevector_simulator")
        qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000)
        phase_est = PhaseEstimation(
            num_evaluation_qubits=num_evaluation_qubits, quantum_instance=qi)
        if construct_circuit:
            pe_circuit = phase_est.construct_circuit(unitary_circuit,
                                                     state_preparation)
            result = phase_est.estimate_from_pe_circuit(
                pe_circuit, unitary_circuit.num_qubits)
        else:
            result = phase_est.estimate(unitary=unitary_circuit,
                                        state_preparation=state_preparation)
        return result

    @data(True, False)
    def test_qpe_Zplus(self, construct_circuit):
        """superposition eigenproblem Z, |+>"""
        unitary_circuit = Z.to_circuit()
        state_preparation = H.to_circuit()  # prepare |+>
        result = self.phase_estimation(
            unitary_circuit,
            state_preparation,
            backend=qiskit.BasicAer.get_backend("statevector_simulator"),
            construct_circuit=construct_circuit,
        )

        phases = result.filter_phases(1e-15, as_float=True)
        with self.subTest("test phases has correct values"):
            self.assertEqual(list(phases.keys()), [0.0, 0.5])

        with self.subTest("test phases has correct probabilities"):
            np.testing.assert_allclose(list(phases.values()), [0.5, 0.5])

        with self.subTest("test bitstring representation"):
            phases = result.filter_phases(1e-15, as_float=False)
            self.assertEqual(list(phases.keys()), ["000000", "100000"])