def construct_total_circuit_local(self, time_step): ## This function creates the circuit that will be used to evaluate overlap and its gradient, in a local fashion # First, create the Trotter step step_h = time_step * self.hamiltonian trotter = PauliTrotterEvolution(reps=1) U_dt = trotter.convert(step_h.exp_i()).to_circuit() l_circ = self.ansatz.assign_parameters({self.params_vec: self.left}) r_circ = self.ansatz.assign_parameters({self.params_vec: self.right}) ## Projector zero_prj = StateFn(projector_zero_local(self.hamiltonian.num_qubits), is_measurement=True) state_wfn = zero_prj @ StateFn(r_circ + U_dt + l_circ.inverse()) return state_wfn
def test_trotter_from_bound(self): """HamiltonianPhaseEstimation with bound and Trotterization""" result = self._setup_from_bound(PauliTrotterEvolution( trotter_mode="suzuki", reps=3), op_class="SummedOp") phase_dict = result.filter_phases(0.1) phases = list(phase_dict.keys()) with self.subTest("test phases has the correct length"): self.assertEqual(len(phases), 2) with self.subTest("test phases has correct values"): self.assertAlmostEqual(phases[0], 1.5, delta=0.001) self.assertAlmostEqual(phases[1], -1.5, delta=0.001)
def test_H2_hamiltonian(self): """Test H2 hamiltonian""" hamiltonian = (-1.0523732457728587 * (I ^ I)) + (0.3979374248431802 * (I ^ Z)) \ + (-0.3979374248431802 * (Z ^ I)) + (-0.011280104256235324 * (Z ^ Z)) \ + (0.18093119978423147 * (X ^ X)) state_preparation = StateFn((I ^ H).to_circuit()) evo = PauliTrotterEvolution(trotter_mode='suzuki', reps=4) result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evo) with self.subTest('Most likely eigenvalues'): self.assertAlmostEqual(result.most_likely_eigenvalue, -1.855, delta=.001) with self.subTest('Most likely phase'): self.assertAlmostEqual(result.phase, 0.5937, delta=.001) with self.subTest('All eigenvalues'): phase_dict = result.filter_phases(0.1) phases = list(phase_dict.keys()) self.assertAlmostEqual(phases[0], -0.8979, delta=0.001) self.assertAlmostEqual(phases[1], -1.8551, delta=0.001) self.assertAlmostEqual(phases[2], -1.2376, delta=0.001)
class TestHamiltonianPhaseEstimation(QiskitAlgorithmsTestCase): """Tests for obtaining eigenvalues from phase estimation""" def hamiltonian_pe( self, hamiltonian, state_preparation=None, num_evaluation_qubits=6, backend=None, evolution=None, bound=None, ): """Run HamiltonianPhaseEstimation and return result with all phases.""" if backend is None: backend = qiskit.BasicAer.get_backend("statevector_simulator") quantum_instance = qiskit.utils.QuantumInstance(backend=backend, shots=10000) phase_est = HamiltonianPhaseEstimation( num_evaluation_qubits=num_evaluation_qubits, quantum_instance=quantum_instance) result = phase_est.estimate( hamiltonian=hamiltonian, state_preparation=state_preparation, evolution=evolution, bound=bound, ) return result @data(MatrixEvolution(), PauliTrotterEvolution("suzuki", 4)) def test_pauli_sum_1(self, evolution): """Two eigenvalues from Pauli sum with X, Z""" hamiltonian = 0.5 * X + Z state_preparation = StateFn(H.to_circuit()) result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) phase_dict = result.filter_phases(0.162, as_float=True) phases = list(phase_dict.keys()) phases.sort() self.assertAlmostEqual(phases[0], -1.125, delta=0.001) self.assertAlmostEqual(phases[1], 1.125, delta=0.001) @data(MatrixEvolution(), PauliTrotterEvolution("suzuki", 3)) def test_pauli_sum_2(self, evolution): """Two eigenvalues from Pauli sum with X, Y, Z""" hamiltonian = 0.5 * X + Y + Z state_preparation = None result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evolution) phase_dict = result.filter_phases(0.1, as_float=True) phases = list(phase_dict.keys()) phases.sort() self.assertAlmostEqual(phases[0], -1.484, delta=0.001) self.assertAlmostEqual(phases[1], 1.484, delta=0.001) 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) def test_H2_hamiltonian(self): """Test H2 hamiltonian""" hamiltonian = ((-1.0523732457728587 * (I ^ I)) + (0.3979374248431802 * (I ^ Z)) + (-0.3979374248431802 * (Z ^ I)) + (-0.011280104256235324 * (Z ^ Z)) + (0.18093119978423147 * (X ^ X))) state_preparation = StateFn((I ^ H).to_circuit()) evo = PauliTrotterEvolution(trotter_mode="suzuki", reps=4) result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=evo) with self.subTest("Most likely eigenvalues"): self.assertAlmostEqual(result.most_likely_eigenvalue, -1.855, delta=0.001) with self.subTest("Most likely phase"): self.assertAlmostEqual(result.phase, 0.5937, delta=0.001) with self.subTest("All eigenvalues"): phase_dict = result.filter_phases(0.1) phases = list(phase_dict.keys()) self.assertAlmostEqual(phases[0], -0.8979, delta=0.001) self.assertAlmostEqual(phases[1], -1.8551, delta=0.001) self.assertAlmostEqual(phases[2], -1.2376, delta=0.001) def test_matrix_evolution(self): """1Q Hamiltonian with MatrixEvolution""" hamiltonian = (0.5 * X) + (0.6 * Y) + (0.7 * I) state_preparation = None result = self.hamiltonian_pe(hamiltonian, state_preparation, evolution=MatrixEvolution()) phase_dict = result.filter_phases(0.2, as_float=True) phases = list(phase_dict.keys()) self.assertAlmostEqual(phases[0], 1.490, delta=0.001) self.assertAlmostEqual(phases[1], -0.090, delta=0.001) def _setup_from_bound(self, evolution, op_class): hamiltonian = 0.5 * X + Y + Z state_preparation = None bound = 1.2 * sum( [abs(hamiltonian.coeff * coeff) for coeff in hamiltonian.coeffs]) if op_class == "MatrixOp": hamiltonian = hamiltonian.to_matrix_op() backend = qiskit.BasicAer.get_backend("statevector_simulator") qi = qiskit.utils.QuantumInstance(backend=backend, shots=10000) phase_est = HamiltonianPhaseEstimation(num_evaluation_qubits=6, quantum_instance=qi) result = phase_est.estimate( hamiltonian=hamiltonian, bound=bound, evolution=evolution, state_preparation=state_preparation, ) return result def test_from_bound(self): """HamiltonianPhaseEstimation with bound""" for op_class in ("SummedOp", "MatrixOp"): result = self._setup_from_bound(MatrixEvolution(), op_class) cutoff = 0.01 phases = result.filter_phases(cutoff) with self.subTest( f"test phases has the correct length: {op_class}"): self.assertEqual(len(phases), 2) with self.subTest( f"test scaled phases are correct: {op_class}"): self.assertEqual(list(phases.keys()), [1.5, -1.5]) phases = result.filter_phases(cutoff, scaled=False) with self.subTest( f"test unscaled phases are correct: {op_class}"): self.assertEqual(list(phases.keys()), [0.25, 0.75]) def test_trotter_from_bound(self): """HamiltonianPhaseEstimation with bound and Trotterization""" result = self._setup_from_bound(PauliTrotterEvolution( trotter_mode="suzuki", reps=3), op_class="SummedOp") phase_dict = result.filter_phases(0.1) phases = list(phase_dict.keys()) with self.subTest("test phases has the correct length"): self.assertEqual(len(phases), 2) with self.subTest("test phases has correct values"): self.assertAlmostEqual(phases[0], 1.5, delta=0.001) self.assertAlmostEqual(phases[1], -1.5, delta=0.001)