def test_uccsd_hf_qpUCCD(self): """ paired uccd test """ optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( self.fermionic_transformation.molecule_info['num_orbitals'], self.fermionic_transformation.molecule_info['num_particles'], qubit_mapping=self.fermionic_transformation._qubit_mapping, two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction) var_form = UCCSD( num_orbitals=self.fermionic_transformation.molecule_info['num_orbitals'], num_particles=self.fermionic_transformation.molecule_info['num_particles'], active_occupied=None, active_unoccupied=None, initial_state=initial_state, qubit_mapping=self.fermionic_transformation._qubit_mapping, two_qubit_reduction=self.fermionic_transformation._two_qubit_reduction, num_time_slices=1, shallow_circuit_concat=False, method_doubles='pucc', excitation_type='d' ) solver = VQE(var_form=var_form, optimizer=optimizer, quantum_instance=QuantumInstance( backend=BasicAer.get_backend('statevector_simulator'))) gsc = GroundStateEigensolver(self.fermionic_transformation, solver) result = gsc.solve(self.driver) self.assertAlmostEqual(result.total_energies[0], self.reference_energy_pUCCD, places=6)
def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( ansatz=TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz"), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend("statevector_simulator"), ) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest("User expectation kept."): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest("Expectation created."): self.assertIsInstance(vqe.expectation, ExpectationBase) try: vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") except Exception as ex: # pylint: disable=broad-except self.fail("Failed to change backend. Error: '{}'".format(str(ex))) return result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest( "Change backend with user expectation, it is kept."): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest( "Change backend without user expectation, one created."): self.assertIsInstance(vqe.expectation, ExpectationBase) with self.subTest("Check results."): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))
def test_uccsd_hf_qpUCCD(self): """paired uccd test""" self.skipTest( "Temporarily skip test until the changes done by " "https://github.com/Qiskit/qiskit-terra/pull/7551 are handled properly." ) optimizer = SLSQP(maxiter=100) initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles, self.qubit_converter) ansatz = PUCCD( self.qubit_converter, self.num_particles, self.num_spin_orbitals, initial_state=initial_state, ) solver = VQE( ansatz=ansatz, optimizer=optimizer, quantum_instance=QuantumInstance( backend=BasicAer.get_backend("statevector_simulator")), ) gsc = GroundStateEigensolver(self.qubit_converter, solver) result = gsc.solve(self.electronic_structure_problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy_pUCCD, places=6)
def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( operator=self.h2_op, var_form=TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz'), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend('statevector_simulator')) result0 = vqe.run() if user_expectation is not None: with self.subTest('User expectation kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest('Expectation created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) try: vqe.set_backend(BasicAer.get_backend('qasm_simulator')) except Exception as ex: # pylint: disable=broad-except self.fail("Failed to change backend. Error: '{}'".format(str(ex))) return result1 = vqe.run() if user_expectation is not None: with self.subTest( 'Change backend with user expectation, it is kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest( 'Change backend without user expectation, one created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) with self.subTest('Check results.'): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))
def test_eval_op_qasm_aer(self): """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53.""" try: # pylint: disable=import-outside-toplevel # pylint: disable=unused-import from qiskit import Aer backend = Aer.get_backend("aer_simulator") except ImportError as ex: # pylint: disable=broad-except self.skipTest(f"Aer doesn't appear to be installed. Error: '{str(ex)}'") return solver = VQEUCCFactory( optimizer=SLSQP(maxiter=100), expectation=AerPauliExpectation(), include_custom=True, quantum_instance=QuantumInstance( backend=backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) calc = GroundStateEigensolver(self.qubit_converter, solver) res_qasm = calc.solve(self.electronic_structure_problem) hamiltonian = self.electronic_structure_problem.second_q_ops()[0] qubit_op = self.qubit_converter.map(hamiltonian) ansatz = solver.get_solver(self.electronic_structure_problem, self.qubit_converter).ansatz circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point) mean = calc.evaluate_operators(circuit, qubit_op) self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)
def test_uccsd_hf_aer_statevector(self): """ uccsd hf test with Aer statevector """ try: # pylint: disable=import-outside-toplevel from qiskit import Aer backend = Aer.get_backend('statevector_simulator') except ImportError as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return ansatz = self._prepare_uccsd_hf(self.qubit_converter) optimizer = SLSQP(maxiter=100) solver = VQE(ansatz=ansatz, optimizer=optimizer, quantum_instance=QuantumInstance(backend=backend)) gsc = GroundStateEigensolver(self.qubit_converter, solver) result = gsc.solve(self.electronic_structure_problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=6)
def test_uccsd_hf_qpUCCD(self): """ paired uccd test """ optimizer = SLSQP(maxiter=100) initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles, self.qubit_converter) ansatz = PUCCD(self.qubit_converter, self.num_particles, self.num_spin_orbitals, initial_state=initial_state) solver = VQE( ansatz=ansatz, optimizer=optimizer, quantum_instance=QuantumInstance( backend=BasicAer.get_backend('statevector_simulator'))) gsc = GroundStateEigensolver(self.qubit_converter, solver) result = gsc.solve(self.electronic_structure_problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy_pUCCD, places=6)
def test_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver( self.get_resource_path('test_driver_hdf5.hdf5', 'drivers/hdf5d')) fermionic_transformation = \ FermionicTransformation(qubit_mapping=FermionicQubitMappingType.PARITY, two_qubit_reduction=False) qubit_op, _ = fermionic_transformation.transform(driver) optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( fermionic_transformation.molecule_info['num_orbitals'], fermionic_transformation.molecule_info['num_particles'], qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction) wavefunction = ExcitationPreserving(qubit_op.num_qubits) wavefunction.compose(initial_state, front=True, inplace=True) solver = VQE(var_form=wavefunction, optimizer=optimizer, quantum_instance=QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed)) gsc = GroundStateEigensolver(fermionic_transformation, solver) result = gsc.solve(driver) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=4)
def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( ansatz=TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz"), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend("statevector_simulator"), ) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest("User expectation kept."): self.assertEqual(vqe.expectation, user_expectation) vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") # works also if no expectation is set, since it will be determined automatically result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest( "Change backend with user expectation, it is kept."): self.assertEqual(vqe.expectation, user_expectation) with self.subTest("Check results."): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))
def test_uccsd_hf_qUCCD0full(self): """singlet full uccd test""" optimizer = SLSQP(maxiter=100) initial_state = HartreeFock(self.num_spin_orbitals, self.num_particles, self.qubit_converter) # TODO: add `full` option ansatz = SUCCD( self.qubit_converter, self.num_particles, self.num_spin_orbitals, initial_state=initial_state, ) solver = VQE( ansatz=ansatz, optimizer=optimizer, quantum_instance=QuantumInstance( backend=BasicAer.get_backend("statevector_simulator")), ) gsc = GroundStateEigensolver(self.qubit_converter, solver) result = gsc.solve(self.electronic_structure_problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy_UCCD0full, places=6)
def setUp(self): super().setUp() self.skipTest("Skip test until refactored.") self.reference_energy = -1.1373060356951838 self.seed = 700 algorithm_globals.random_seed = self.seed self.driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5', 'drivers/hdf5d')) fermionic_transformation = \ FermionicTransformation(qubit_mapping=FermionicQubitMappingType.PARITY, two_qubit_reduction=False) self.qubit_op, _ = fermionic_transformation.transform(self.driver) self.fermionic_transformation = fermionic_transformation self.optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( fermionic_transformation.molecule_info['num_orbitals'], fermionic_transformation.molecule_info['num_particles'], qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction) self.var_form = UCCSD( num_orbitals=fermionic_transformation.molecule_info['num_orbitals'], num_particles=fermionic_transformation.molecule_info['num_particles'], initial_state=initial_state, qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction)
def test_eval_op_qasm_aer(self): """Regression tests against https://github.com/Qiskit/qiskit-nature/issues/53.""" backend = qiskit.providers.aer.Aer.get_backend("aer_simulator") solver = VQEUCCFactory( optimizer=SLSQP(maxiter=100), expectation=AerPauliExpectation(), include_custom=True, quantum_instance=QuantumInstance( backend=backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) calc = GroundStateEigensolver(self.qubit_converter, solver) res_qasm = calc.solve(self.electronic_structure_problem) hamiltonian = self.electronic_structure_problem.second_q_ops()[ self.electronic_structure_problem.main_property_name] qubit_op = self.qubit_converter.map(hamiltonian) ansatz = solver.get_solver(self.electronic_structure_problem, self.qubit_converter).ansatz circuit = ansatz.assign_parameters(res_qasm.raw_result.optimal_point) mean = calc.evaluate_operators(circuit, qubit_op) self.assertAlmostEqual(res_qasm.eigenenergies[0], mean[0].real)
def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) vqe = VQE(self.h2_op, wavefunction, optimizer=optimizer) result = vqe.run(self.statevector_simulator) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5)
def __init__(self): # H2 self.molecule_name = "Li .0 .0 .0; H .0 .0 " self.backend = QuantumInstance( backend=Aer.get_backend("statevector_simulator")) self.optimizer = SLSQP(maxiter=5) self.vqe = VQE(ansatz=None, quantum_instance=self.backend, optimizer=self.optimizer)
def test_ibmq(self): """ IBMQ VQE Test """ from qiskit import IBMQ provider = IBMQ.load_account() backend = provider.get_backend('ibmq_qasm_simulator') ansatz = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') opt = SLSQP(maxiter=1) opt.set_max_evals_grouped(100) vqe = VQE(self.h2_op, ansatz, SLSQP(maxiter=2)) result = vqe.run(backend) print(result) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) np.testing.assert_array_almost_equal(result.eigenvalue.real, self.h2_energy, 5) self.assertEqual(len(result.optimal_point), 16) self.assertIsNotNone(result.cost_function_evals) self.assertIsNotNone(result.optimizer_time)
def test_mismatching_num_qubits(self): """Ensuring circuit and operator mismatch is caught""" wavefunction = QuantumCircuit(1) optimizer = SLSQP(maxiter=50) vqd = VQD( k=1, ansatz=wavefunction, optimizer=optimizer, quantum_instance=self.statevector_simulator, ) with self.assertRaises(AlgorithmError): _ = vqd.compute_eigenvalues(operator=self.h2_op)
def test_uccsd_hf(self): """ uccsd hf test """ ansatz = self._prepare_uccsd_hf(self.qubit_converter) optimizer = SLSQP(maxiter=100) backend = BasicAer.get_backend('statevector_simulator') solver = VQE(ansatz=ansatz, optimizer=optimizer, quantum_instance=QuantumInstance(backend=backend)) gsc = GroundStateEigensolver(self.qubit_converter, solver) result = gsc.solve(self.electronic_structure_problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=6)
def test_vqe_ucc_factory_with_user_initial_point(self): """Test VQEUCCFactory when using it with a user defined initial point.""" initial_point = np.asarray( [1.28074029e-19, 5.92226076e-08, 1.11762559e-01]) solver = VQEUCCFactory( quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator")), initial_point=initial_point, optimizer=SLSQP(maxiter=1), ) calc = GroundStateEigensolver(self.qubit_converter, solver) res = calc.solve(self.electronic_structure_problem) np.testing.assert_array_almost_equal(res.raw_result.optimal_point, initial_point)
def test_uccsd_hf_qUCCSD(self): """ uccsd tapering test using all double excitations """ fermionic_transformation = FermionicTransformation( transformation=FermionicTransformationType.FULL, qubit_mapping=FermionicQubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=True, orbital_reduction=[], z2symmetry_reduction='auto' ) qubit_op, _ = fermionic_transformation.transform(self.driver) # optimizer optimizer = SLSQP(maxiter=100) # initial state init_state = HartreeFock( num_orbitals=fermionic_transformation.molecule_info['num_orbitals'], qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction, num_particles=fermionic_transformation.molecule_info['num_particles'], sq_list=fermionic_transformation.molecule_info['z2_symmetries'].sq_list) var_form = UCCSD( num_orbitals=fermionic_transformation.molecule_info['num_orbitals'], num_particles=fermionic_transformation.molecule_info['num_particles'], active_occupied=None, active_unoccupied=None, initial_state=init_state, qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction, num_time_slices=1, z2_symmetries=fermionic_transformation.molecule_info['z2_symmetries'], shallow_circuit_concat=False, method_doubles='ucc', excitation_type='sd', skip_commute_test=True) solver = VQE(var_form=var_form, optimizer=optimizer, quantum_instance=QuantumInstance( backend=BasicAer.get_backend('statevector_simulator'))) raw_result = solver.compute_minimum_eigenvalue(qubit_op, None) result = fermionic_transformation.interpret(raw_result) self.assertAlmostEqual(result.total_energies[0], self.reference_energy_UCCSD, places=6)
def test_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver( self.get_resource_path("test_driver_hdf5.hdf5", "second_q/drivers/hdf5d")) converter = QubitConverter(ParityMapper()) problem = ElectronicStructureProblem(driver) _ = problem.second_q_ops() particle_number = cast( ParticleNumber, problem.grouped_property_transformed.get_property(ParticleNumber)) num_particles = (particle_number.num_alpha, particle_number.num_beta) num_spin_orbitals = particle_number.num_spin_orbitals optimizer = SLSQP(maxiter=100) initial_state = HartreeFock(num_spin_orbitals, num_particles, converter) wavefunction = ExcitationPreserving(num_spin_orbitals) wavefunction.compose(initial_state, front=True, inplace=True) solver = VQE( ansatz=wavefunction, optimizer=optimizer, quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator"), seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) gsc = GroundStateEigensolver(converter, solver) result = gsc.solve(problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=4)
def test_vqe_optimizer(self): """Test running same VQE twice to re-use optimizer, then switch optimizer""" vqe = VQE( optimizer=SLSQP(), quantum_instance=QuantumInstance(BasicAer.get_backend("statevector_simulator")), ) def run_check(): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() with self.subTest("Optimizer re-use"): run_check() with self.subTest("Optimizer replace"): vqe.optimizer = L_BFGS_B() run_check()
def test_plugin_configuration(self): """Tests plugin with a custom configuration.""" config = { "network_layout": "sequ", "connectivity_type": "full", "depth": 0, "seed": 12345, "optimizer": SLSQP(), } transpiler_pass = UnitarySynthesis( basis_gates=["rx", "ry", "rz", "cx"], method="aqc", plugin_config=config) dag = circuit_to_dag(self._qc) dag = transpiler_pass.run(dag) approx_circuit = dag_to_circuit(dag) approx_unitary = Operator(approx_circuit).data np.testing.assert_array_almost_equal(self._target_unitary, approx_unitary, 3)
def test_vqd_optimizer(self): """Test running same VQD twice to re-use optimizer, then switch optimizer""" vqd = VQD( k=2, optimizer=SLSQP(), quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator")), ) def run_check(): result = vqd.compute_eigenvalues(operator=self.h2_op) np.testing.assert_array_almost_equal(result.eigenvalues.real, self.h2_energy_excited, decimal=3) run_check() with self.subTest("Optimizer re-use"): run_check() with self.subTest("Optimizer replace"): vqd.optimizer = L_BFGS_B() run_check()
class TestVQE(QiskitAlgorithmsTestCase): """Test VQE""" def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed self.h2_op = (-1.052373245772859 * (I ^ I) + 0.39793742484318045 * (I ^ Z) - 0.39793742484318045 * (Z ^ I) - 0.01128010425623538 * (Z ^ Z) + 0.18093119978423156 * (X ^ X)) self.h2_energy = -1.85727503 self.ryrz_wavefunction = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") self.ry_wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") self.qasm_simulator = QuantumInstance( BasicAer.get_backend("qasm_simulator"), shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed, ) self.statevector_simulator = QuantumInstance( BasicAer.get_backend("statevector_simulator"), shots=1, seed_simulator=self.seed, seed_transpiler=self.seed, ) def test_basic_aer_statevector(self): """Test the VQE on BasicAer's statevector simulator.""" wavefunction = self.ryrz_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=L_BFGS_B(), quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator"), basis_gates=["u1", "u2", "u3", "cx", "id"], coupling_map=[[0, 1]], seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) with self.subTest(msg="test eigenvalue"): self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) with self.subTest(msg="test dimension of optimal point"): self.assertEqual(len(result.optimal_point), 16) with self.subTest(msg="assert cost_function_evals is set"): self.assertIsNotNone(result.cost_function_evals) with self.subTest(msg="assert optimizer_time is set"): self.assertIsNotNone(result.optimizer_time) def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, quantum_instance=self.statevector_simulator) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) @data( (MatrixExpectation(), 1), (AerPauliExpectation(), 1), (PauliExpectation(), 2), ) @unpack def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) vqe = VQE(ansatz=wavefunction, expectation=expectation) params = [0] * wavefunction.num_parameters circuits = vqe.construct_circuit(parameter=params, operator=self.h2_op) self.assertEqual(len(circuits), num_circuits) for circuit in circuits: self.assertIsInstance(circuit, QuantumCircuit) except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) return def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" circuit = QuantumCircuit(self.h2_op.num_qubits) vqe = VQE( ansatz=circuit, quantum_instance=BasicAer.get_backend("statevector_simulator")) with self.assertRaises(RuntimeError): vqe.compute_minimum_eigenvalue(operator=self.h2_op) @data( (SLSQP(maxiter=50), 5, 4), (SPSA(maxiter=150), 2, 2), # max_evals_grouped=n or =2 if n>2 ) @unpack def test_max_evals_grouped(self, optimizer, places, max_evals_grouped): """VQE Optimizers test""" vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=optimizer, max_evals_grouped=max_evals_grouped, quantum_instance=self.statevector_simulator, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=places) def test_basic_aer_qasm(self): """Test the VQE on BasicAer's QASM simulator.""" optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=self.qasm_simulator, ) # TODO benchmark this later. result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2) def test_qasm_eigenvector_normalized(self): """Test VQE with qasm_simulator returns normalized eigenvector.""" wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, quantum_instance=self.qasm_simulator) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) amplitudes = list(result.eigenstate.values()) self.assertAlmostEqual(np.linalg.norm(amplitudes), 1.0, places=4) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_statevector(self): """Test VQE with Aer's statevector_simulator.""" backend = Aer.get_backend("aer_simulator_statevector") wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_qasm(self): """Test VQE with Aer's qasm_simulator.""" backend = Aer.get_backend("aer_simulator") optimizer = SPSA(maxiter=200, last_avg=5) wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, expectation=PauliExpectation(), quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_qasm_snapshot_mode(self): """Test the VQE using Aer's qasm_simulator snapshot mode.""" backend = Aer.get_backend("aer_simulator") optimizer = L_BFGS_B() wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, expectation=AerPauliExpectation(), quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") @data( CG(maxiter=1), L_BFGS_B(maxfun=1), P_BFGS(maxfun=1, max_processes=0), SLSQP(maxiter=1), TNC(maxiter=1), ) def test_with_gradient(self, optimizer): """Test VQE using Gradient().""" quantum_instance = QuantumInstance( backend=Aer.get_backend("qasm_simulator"), shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=self.ry_wavefunction, optimizer=optimizer, gradient=Gradient(), expectation=AerPauliExpectation(), quantum_instance=quantum_instance, max_evals_grouped=1000, ) vqe.compute_minimum_eigenvalue(operator=self.h2_op) def test_with_two_qubit_reduction(self): """Test the VQE using TwoQubitReduction.""" qubit_op = PauliSumOp.from_list([ ("IIII", -0.8105479805373266), ("IIIZ", 0.17218393261915552), ("IIZZ", -0.22575349222402472), ("IZZI", 0.1721839326191556), ("ZZII", -0.22575349222402466), ("IIZI", 0.1209126326177663), ("IZZZ", 0.16892753870087912), ("IXZX", -0.045232799946057854), ("ZXIX", 0.045232799946057854), ("IXIX", 0.045232799946057854), ("ZXZX", -0.045232799946057854), ("ZZIZ", 0.16614543256382414), ("IZIZ", 0.16614543256382414), ("ZZZZ", 0.17464343068300453), ("ZIZI", 0.1209126326177663), ]) tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) for simulator in [self.qasm_simulator, self.statevector_simulator]: with self.subTest(f"Test for {simulator}."): vqe = VQE( self.ry_wavefunction, SPSA(maxiter=300, last_avg=5), quantum_instance=simulator, ) result = vqe.compute_minimum_eigenvalue(tapered_qubit_op) energy = -1.868 if simulator == self.qasm_simulator else self.h2_energy self.assertAlmostEqual(result.eigenvalue.real, energy, places=2) def test_callback(self): """Test the callback on VQE.""" history = {"eval_count": [], "parameters": [], "mean": [], "std": []} def store_intermediate_result(eval_count, parameters, mean, std): history["eval_count"].append(eval_count) history["parameters"].append(parameters) history["mean"].append(mean) history["std"].append(std) optimizer = COBYLA(maxiter=3) wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=optimizer, callback=store_intermediate_result, quantum_instance=self.qasm_simulator, ) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertTrue( all(isinstance(count, int) for count in history["eval_count"])) self.assertTrue( all(isinstance(mean, float) for mean in history["mean"])) self.assertTrue(all(isinstance(std, float) for std in history["std"])) for params in history["parameters"]: self.assertTrue(all(isinstance(param, float) for param in params)) def test_reuse(self): """Test re-using a VQE algorithm instance.""" vqe = VQE() with self.subTest(msg="assert running empty raises AlgorithmError"): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") vqe.ansatz = ansatz with self.subTest(msg="assert missing operator raises AlgorithmError"): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) vqe.expectation = MatrixExpectation() vqe.quantum_instance = self.statevector_simulator with self.subTest(msg="assert VQE works once all info is available"): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) operator = PrimitiveOp( np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) with self.subTest(msg="assert minimum eigensolver interface works"): result = vqe.compute_minimum_eigenvalue(operator=operator) self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5) def test_vqe_optimizer(self): """Test running same VQE twice to re-use optimizer, then switch optimizer""" vqe = VQE( optimizer=SLSQP(), quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator")), ) def run_check(): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() with self.subTest("Optimizer re-use"): run_check() with self.subTest("Optimizer replace"): vqe.optimizer = L_BFGS_B() run_check() @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( ansatz=TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz"), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend("statevector_simulator"), ) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest("User expectation kept."): self.assertEqual(vqe.expectation, user_expectation) vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") # works also if no expectation is set, since it will be determined automatically result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest( "Change backend with user expectation, it is kept."): self.assertEqual(vqe.expectation, user_expectation) with self.subTest("Check results."): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point)) def test_batch_evaluate_with_qnspsa(self): """Test batch evaluating with QNSPSA works.""" ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz") wrapped_backend = BasicAer.get_backend("qasm_simulator") inner_backend = BasicAer.get_backend("statevector_simulator") callcount = {"count": 0} def wrapped_run(circuits, **kwargs): kwargs["callcount"]["count"] += 1 return inner_backend.run(circuits) wrapped_backend.run = partial(wrapped_run, callcount=callcount) fidelity = QNSPSA.get_fidelity(ansatz, backend=wrapped_backend) qnspsa = QNSPSA(fidelity, maxiter=5) vqe = VQE( ansatz=ansatz, optimizer=qnspsa, max_evals_grouped=100, quantum_instance=wrapped_backend, ) _ = vqe.compute_minimum_eigenvalue(Z ^ Z) # 1 calibration + 1 stddev estimation + 1 initial blocking # + 5 (1 loss + 1 fidelity + 1 blocking) + 1 return loss + 1 VQE eval expected = 1 + 1 + 1 + 5 * 3 + 1 + 1 self.assertEqual(callcount["count"], expected) def test_set_ansatz_to_none(self): """Tests that setting the ansatz to None results in the default behavior""" vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=L_BFGS_B(), quantum_instance=self.statevector_simulator, ) vqe.ansatz = None self.assertIsInstance(vqe.ansatz, RealAmplitudes) def test_set_optimizer_to_none(self): """Tests that setting the optimizer to None results in the default behavior""" vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=L_BFGS_B(), quantum_instance=self.statevector_simulator, ) vqe.optimizer = None self.assertIsInstance(vqe.optimizer, SLSQP) def test_optimizer_scipy_callable(self): """Test passing a SciPy optimizer directly as callable.""" vqe = VQE( optimizer=partial(scipy_minimize, method="L-BFGS-B", options={"maxiter": 2}), quantum_instance=self.statevector_simulator, ) result = vqe.compute_minimum_eigenvalue(Z) self.assertEqual(result.cost_function_evals, 20) def test_optimizer_callable(self): """Test passing a optimizer directly as callable.""" ansatz = RealAmplitudes(1, reps=1) vqe = VQE(ansatz=ansatz, optimizer=_mock_optimizer, quantum_instance=self.statevector_simulator) result = vqe.compute_minimum_eigenvalue(Z) self.assertTrue( np.all(result.optimal_point == np.zeros(ansatz.num_parameters))) def test_aux_operators_list(self): """Test list-based aux_operators.""" wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, quantum_instance=self.statevector_simulator) # Start with an empty list result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=[]) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators aux_op1 = PauliSumOp.from_list([("II", 2.0)]) aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = [aux_op1, aux_op2] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0, places=6) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0) # Go again with additional None and zero operators extra_ops = [*aux_ops, None, 0] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0, places=6) self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0) self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0) def test_aux_operators_dict(self): """Test dictionary compatibility of aux_operators""" wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, quantum_instance=self.statevector_simulator) # Start with an empty dictionary result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators={}) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertIsNone(result.aux_operator_eigenvalues) # Go again with two auxiliary operators aux_op1 = PauliSumOp.from_list([("II", 2.0)]) aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = {"aux_op1": aux_op1, "aux_op2": aux_op2} result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=6) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][1], 0.0) # Go again with additional None and zero operators extra_ops = {**aux_ops, "None_operator": None, "zero_operator": 0} result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=extra_ops) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) self.assertEqual(len(result.aux_operator_eigenvalues), 3) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][0], 2, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][0], 0, places=6) self.assertEqual(result.aux_operator_eigenvalues["zero_operator"][0], 0.0) self.assertTrue( "None_operator" not in result.aux_operator_eigenvalues.keys()) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op1"][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues["aux_op2"][1], 0.0) self.assertAlmostEqual( result.aux_operator_eigenvalues["zero_operator"][1], 0.0) def test_aux_operator_std_dev_pauli(self): """Test non-zero standard deviations of aux operators with PauliExpectation.""" wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, expectation=PauliExpectation(), optimizer=COBYLA(maxiter=0), quantum_instance=self.qasm_simulator, ) # Go again with two auxiliary operators aux_op1 = PauliSumOp.from_list([("II", 2.0)]) aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = [aux_op1, aux_op2] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.6796875, places=6) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.02534712219145965, places=6) # Go again with additional None and zero operators aux_ops = [*aux_ops, None, 0] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.57421875, places=6) self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0) self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0) # # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.026562146577166837, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_aux_operator_std_dev_aer_pauli(self): """Test non-zero standard deviations of aux operators with AerPauliExpectation.""" wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, expectation=AerPauliExpectation(), optimizer=COBYLA(maxiter=0), quantum_instance=QuantumInstance( backend=Aer.get_backend("qasm_simulator"), shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) # Go again with two auxiliary operators aux_op1 = PauliSumOp.from_list([("II", 2.0)]) aux_op2 = PauliSumOp.from_list([("II", 0.5), ("ZZ", 0.5), ("YY", 0.5), ("XX", -0.5)]) aux_ops = [aux_op1, aux_op2] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertEqual(len(result.aux_operator_eigenvalues), 2) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.6698863565455391, places=6) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0, places=6) # Go again with additional None and zero operators aux_ops = [*aux_ops, None, 0] result = vqe.compute_minimum_eigenvalue(self.h2_op, aux_operators=aux_ops) self.assertEqual(len(result.aux_operator_eigenvalues), 4) # expectation values self.assertAlmostEqual(result.aux_operator_eigenvalues[0][0], 2.0, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][0], 0.6036400943063891, places=6) self.assertEqual(result.aux_operator_eigenvalues[2][0], 0.0) self.assertEqual(result.aux_operator_eigenvalues[3][0], 0.0) # standard deviations self.assertAlmostEqual(result.aux_operator_eigenvalues[0][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[1][1], 0.0, places=6) self.assertAlmostEqual(result.aux_operator_eigenvalues[2][1], 0.0) self.assertAlmostEqual(result.aux_operator_eigenvalues[3][1], 0.0) def test_2step_transpile(self): """Test the two-step transpiler pass.""" # count how often the pass for parameterized circuits is called pre_counter = LogPass("pre_passmanager") pre_pass = PassManager(pre_counter) config = PassManagerConfig(basis_gates=["u3", "cx"]) pre_pass += level_1_pass_manager(config) # ... and the pass for bound circuits bound_counter = LogPass("bound_pass_manager") bound_pass = PassManager(bound_counter) quantum_instance = QuantumInstance( backend=BasicAer.get_backend("statevector_simulator"), basis_gates=["u3", "cx"], pass_manager=pre_pass, bound_pass_manager=bound_pass, ) optimizer = SPSA(maxiter=5, learning_rate=0.01, perturbation=0.01) vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) _ = vqe.compute_minimum_eigenvalue(Z) with self.assertLogs(logger, level="INFO") as cm: _ = vqe.compute_minimum_eigenvalue(Z) expected = [ "pre_passmanager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "bound_pass_manager", "pre_passmanager", "bound_pass_manager", ] self.assertEqual([record.message for record in cm.records], expected) def test_construct_eigenstate_from_optpoint(self): """Test constructing the eigenstate from the optimal point, if the default ansatz is used.""" # use Hamiltonian yielding more than 11 parameters in the default ansatz hamiltonian = Z ^ Z ^ Z optimizer = SPSA(maxiter=1, learning_rate=0.01, perturbation=0.01) quantum_instance = QuantumInstance( backend=BasicAer.get_backend("statevector_simulator"), basis_gates=["u3", "cx"]) vqe = VQE(optimizer=optimizer, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(hamiltonian) optimal_circuit = vqe.ansatz.bind_parameters(result.optimal_point) self.assertTrue(Statevector(result.eigenstate).equiv(optimal_circuit))
def test_slsqp(self): """slsqp test""" optimizer = SLSQP(maxiter=1000, tol=1e-06) self.run_optimizer(optimizer, max_nfev=10000)
class TestVQE(QiskitAlgorithmsTestCase): """Test VQE""" def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed self.h2_op = (-1.052373245772859 * (I ^ I) + 0.39793742484318045 * (I ^ Z) - 0.39793742484318045 * (Z ^ I) - 0.01128010425623538 * (Z ^ Z) + 0.18093119978423156 * (X ^ X)) self.h2_energy = -1.85727503 self.ryrz_wavefunction = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") self.ry_wavefunction = TwoLocal(rotation_blocks="ry", entanglement_blocks="cz") self.qasm_simulator = QuantumInstance( BasicAer.get_backend("qasm_simulator"), shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed, ) self.statevector_simulator = QuantumInstance( BasicAer.get_backend("statevector_simulator"), shots=1, seed_simulator=self.seed, seed_transpiler=self.seed, ) def test_basic_aer_statevector(self): """Test the VQE on BasicAer's statevector simulator.""" wavefunction = self.ryrz_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=L_BFGS_B(), quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator"), basis_gates=["u1", "u2", "u3", "cx", "id"], coupling_map=[[0, 1]], seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) with self.subTest(msg="test eigenvalue"): self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) with self.subTest(msg="test dimension of optimal point"): self.assertEqual(len(result.optimal_point), 16) with self.subTest(msg="assert cost_function_evals is set"): self.assertIsNotNone(result.cost_function_evals) with self.subTest(msg="assert optimizer_time is set"): self.assertIsNotNone(result.optimizer_time) def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, quantum_instance=self.statevector_simulator) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) @data( (MatrixExpectation(), 1), (AerPauliExpectation(), 1), (PauliExpectation(), 2), ) @unpack def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) vqe = VQE(ansatz=wavefunction, expectation=expectation) params = [0] * wavefunction.num_parameters circuits = vqe.construct_circuit(parameter=params, operator=self.h2_op) self.assertEqual(len(circuits), num_circuits) for circuit in circuits: self.assertIsInstance(circuit, QuantumCircuit) except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) return def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" circuit = QuantumCircuit(self.h2_op.num_qubits) vqe = VQE( ansatz=circuit, quantum_instance=BasicAer.get_backend("statevector_simulator")) with self.assertRaises(RuntimeError): vqe.compute_minimum_eigenvalue(operator=self.h2_op) @data( (SLSQP(maxiter=50), 5, 4), (SPSA(maxiter=150), 3, 2), # max_evals_grouped=n or =2 if n>2 ) @unpack def test_max_evals_grouped(self, optimizer, places, max_evals_grouped): """VQE Optimizers test""" with self.assertWarns(DeprecationWarning): vqe = VQE( ansatz=self.ryrz_wavefunction, optimizer=optimizer, max_evals_grouped=max_evals_grouped, quantum_instance=self.statevector_simulator, sort_parameters_by_name=True, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=places) def test_basic_aer_qasm(self): """Test the VQE on BasicAer's QASM simulator.""" optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=self.qasm_simulator, ) # TODO benchmark this later. result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2) def test_qasm_aux_operators_normalized(self): """Test VQE with qasm_simulator returns normalized aux_operator eigenvalues.""" wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, quantum_instance=self.qasm_simulator) _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) opt_params = [ 3.50437328, 3.87415376, 0.93684363, 5.92219622, -1.53527887, 1.87941418, -4.5708326, 0.70187027, ] vqe._ret.optimal_point = opt_params vqe._ret.optimal_parameters = dict( zip(sorted(wavefunction.parameters, key=lambda p: p.name), opt_params)) with self.assertWarns(DeprecationWarning): optimal_vector = vqe.get_optimal_vector() self.assertAlmostEqual(sum(v**2 for v in optimal_vector.values()), 1.0, places=4) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_statevector(self): """Test VQE with Aer's statevector_simulator.""" backend = Aer.get_backend("aer_simulator_statevector") wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_qasm(self): """Test VQE with Aer's qasm_simulator.""" backend = Aer.get_backend("aer_simulator") optimizer = SPSA(maxiter=200, last_avg=5) wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, expectation=PauliExpectation(), quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") def test_with_aer_qasm_snapshot_mode(self): """Test the VQE using Aer's qasm_simulator snapshot mode.""" backend = Aer.get_backend("aer_simulator") optimizer = L_BFGS_B() wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=wavefunction, optimizer=optimizer, expectation=AerPauliExpectation(), quantum_instance=quantum_instance, ) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) @unittest.skipUnless(has_aer(), "qiskit-aer doesn't appear to be installed.") @data( CG(maxiter=1), L_BFGS_B(maxfun=1), P_BFGS(maxfun=1, max_processes=0), SLSQP(maxiter=1), TNC(maxiter=1), ) def test_with_gradient(self, optimizer): """Test VQE using Gradient().""" quantum_instance = QuantumInstance( backend=Aer.get_backend("qasm_simulator"), shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ) vqe = VQE( ansatz=self.ry_wavefunction, optimizer=optimizer, gradient=Gradient(), expectation=AerPauliExpectation(), quantum_instance=quantum_instance, max_evals_grouped=1000, ) vqe.compute_minimum_eigenvalue(operator=self.h2_op) def test_with_two_qubit_reduction(self): """Test the VQE using TwoQubitReduction.""" qubit_op = PauliSumOp.from_list([ ("IIII", -0.8105479805373266), ("IIIZ", 0.17218393261915552), ("IIZZ", -0.22575349222402472), ("IZZI", 0.1721839326191556), ("ZZII", -0.22575349222402466), ("IIZI", 0.1209126326177663), ("IZZZ", 0.16892753870087912), ("IXZX", -0.045232799946057854), ("ZXIX", 0.045232799946057854), ("IXIX", 0.045232799946057854), ("ZXZX", -0.045232799946057854), ("ZZIZ", 0.16614543256382414), ("IZIZ", 0.16614543256382414), ("ZZZZ", 0.17464343068300453), ("ZIZI", 0.1209126326177663), ]) tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) for simulator in [self.qasm_simulator, self.statevector_simulator]: with self.subTest(f"Test for {simulator}."): vqe = VQE( self.ry_wavefunction, SPSA(maxiter=300, last_avg=5), quantum_instance=simulator, ) result = vqe.compute_minimum_eigenvalue(tapered_qubit_op) energy = -1.868 if simulator == self.qasm_simulator else self.h2_energy self.assertAlmostEqual(result.eigenvalue.real, energy, places=2) def test_callback(self): """Test the callback on VQE.""" history = {"eval_count": [], "parameters": [], "mean": [], "std": []} def store_intermediate_result(eval_count, parameters, mean, std): history["eval_count"].append(eval_count) history["parameters"].append(parameters) history["mean"].append(mean) history["std"].append(std) optimizer = COBYLA(maxiter=3) wavefunction = self.ry_wavefunction vqe = VQE( ansatz=wavefunction, optimizer=optimizer, callback=store_intermediate_result, quantum_instance=self.qasm_simulator, ) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertTrue( all(isinstance(count, int) for count in history["eval_count"])) self.assertTrue( all(isinstance(mean, float) for mean in history["mean"])) self.assertTrue(all(isinstance(std, float) for std in history["std"])) for params in history["parameters"]: self.assertTrue(all(isinstance(param, float) for param in params)) def test_reuse(self): """Test re-using a VQE algorithm instance.""" vqe = VQE() with self.subTest(msg="assert running empty raises AlgorithmError"): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) ansatz = TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz") vqe.ansatz = ansatz with self.subTest(msg="assert missing operator raises AlgorithmError"): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) vqe.expectation = MatrixExpectation() vqe.quantum_instance = self.statevector_simulator with self.subTest(msg="assert VQE works once all info is available"): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) operator = PrimitiveOp( np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) with self.subTest(msg="assert minimum eigensolver interface works"): result = vqe.compute_minimum_eigenvalue(operator=operator) self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5) def test_vqe_optimizer(self): """Test running same VQE twice to re-use optimizer, then switch optimizer""" vqe = VQE( optimizer=SLSQP(), quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator")), ) def run_check(): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() with self.subTest("Optimizer re-use"): run_check() with self.subTest("Optimizer replace"): vqe.optimizer = L_BFGS_B() run_check() @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( ansatz=TwoLocal(rotation_blocks=["ry", "rz"], entanglement_blocks="cz"), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend("statevector_simulator"), ) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest("User expectation kept."): self.assertEqual(vqe.expectation, user_expectation) vqe.quantum_instance = BasicAer.get_backend("qasm_simulator") # works also if no expectation is set, since it will be determined automatically result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest( "Change backend with user expectation, it is kept."): self.assertEqual(vqe.expectation, user_expectation) with self.subTest("Check results."): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point)) def test_batch_evaluate_with_qnspsa(self): """Test batch evaluating with QNSPSA works.""" ansatz = TwoLocal(2, rotation_blocks=["ry", "rz"], entanglement_blocks="cz") wrapped_backend = BasicAer.get_backend("qasm_simulator") inner_backend = BasicAer.get_backend("statevector_simulator") callcount = {"count": 0} def wrapped_run(circuits, **kwargs): kwargs["callcount"]["count"] += 1 return inner_backend.run(circuits) wrapped_backend.run = partial(wrapped_run, callcount=callcount) fidelity = QNSPSA.get_fidelity(ansatz, backend=wrapped_backend) qnspsa = QNSPSA(fidelity, maxiter=5) vqe = VQE( ansatz=ansatz, optimizer=qnspsa, max_evals_grouped=100, quantum_instance=wrapped_backend, ) _ = vqe.compute_minimum_eigenvalue(Z ^ Z) # 1 calibration + 1 stddev estimation + 1 initial blocking # + 5 (1 loss + 1 fidelity + 1 blocking) + 1 return loss + 1 VQE eval expected = 1 + 1 + 1 + 5 * 3 + 1 + 1 self.assertEqual(callcount["count"], expected)
class TestVQE(QiskitAlgorithmsTestCase): """ Test VQE """ def setUp(self): super().setUp() self.seed = 50 aqua_globals.random_seed = self.seed self.h2_op = -1.052373245772859 * (I ^ I) \ + 0.39793742484318045 * (I ^ Z) \ - 0.39793742484318045 * (Z ^ I) \ - 0.01128010425623538 * (Z ^ Z) \ + 0.18093119978423156 * (X ^ X) self.h2_energy = -1.85727503 self.ryrz_wavefunction = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') self.ry_wavefunction = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz') self.qasm_simulator = QuantumInstance( BasicAer.get_backend('qasm_simulator'), shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed) self.statevector_simulator = QuantumInstance( BasicAer.get_backend('statevector_simulator'), shots=1, seed_simulator=self.seed, seed_transpiler=self.seed) def test_basic_aer_statevector(self): """Test the VQE on BasicAer's statevector simulator.""" wavefunction = self.ryrz_wavefunction vqe = VQE(self.h2_op, wavefunction, L_BFGS_B()) result = vqe.run( QuantumInstance(BasicAer.get_backend('statevector_simulator'), basis_gates=['u1', 'u2', 'u3', 'cx', 'id'], coupling_map=[[0, 1]], seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) with self.subTest(msg='test eigenvalue'): self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) with self.subTest(msg='test dimension of optimal point'): self.assertEqual(len(result.optimal_point), 16) with self.subTest(msg='assert cost_function_evals is set'): self.assertIsNotNone(result.cost_function_evals) with self.subTest(msg='assert optimizer_time is set'): self.assertIsNotNone(result.optimizer_time) def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) vqe = VQE(self.h2_op, wavefunction, optimizer=optimizer) result = vqe.run(self.statevector_simulator) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) @data( (MatrixExpectation(), 1), (AerPauliExpectation(), 1), (PauliExpectation(), 2), ) @unpack def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) vqe = VQE(self.h2_op, wavefunction, expectation=expectation) params = [0] * wavefunction.num_parameters circuits = vqe.construct_circuit(params) self.assertEqual(len(circuits), num_circuits) for circuit in circuits: self.assertIsInstance(circuit, QuantumCircuit) except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) return def test_legacy_operator(self): """Test the VQE accepts and converts the legacy WeightedPauliOperator.""" pauli_dict = { 'paulis': [{ "coeff": { "imag": 0.0, "real": -1.052373245772859 }, "label": "II" }, { "coeff": { "imag": 0.0, "real": 0.39793742484318045 }, "label": "IZ" }, { "coeff": { "imag": 0.0, "real": -0.39793742484318045 }, "label": "ZI" }, { "coeff": { "imag": 0.0, "real": -0.01128010425623538 }, "label": "ZZ" }, { "coeff": { "imag": 0.0, "real": 0.18093119978423156 }, "label": "XX" }] } h2_op = WeightedPauliOperator.from_dict(pauli_dict) vqe = VQE(h2_op) self.assertEqual(vqe.operator, self.h2_op) def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" circuit = QuantumCircuit(self.h2_op.num_qubits) vqe = VQE(self.h2_op, circuit) with self.assertRaises(RuntimeError): vqe.run(BasicAer.get_backend('statevector_simulator')) @data( (SLSQP(maxiter=50), 5, 4), (SPSA(maxiter=150), 3, 2), # max_evals_grouped=n or =2 if n>2 ) @unpack def test_max_evals_grouped(self, optimizer, places, max_evals_grouped): """ VQE Optimizers test """ vqe = VQE(self.h2_op, self.ryrz_wavefunction, optimizer, max_evals_grouped=max_evals_grouped, quantum_instance=self.statevector_simulator) result = vqe.run() self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=places) def test_basic_aer_qasm(self): """Test the VQE on BasicAer's QASM simulator.""" optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = self.ry_wavefunction vqe = VQE(self.h2_op, wavefunction, optimizer, max_evals_grouped=1) # TODO benchmark this later. result = vqe.run(self.qasm_simulator) self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2) def test_qasm_aux_operators_normalized(self): """Test VQE with qasm_simulator returns normalized aux_operator eigenvalues.""" wavefunction = self.ry_wavefunction vqe = VQE(self.h2_op, wavefunction, quantum_instance=self.qasm_simulator) opt_params = [ 3.50437328, 3.87415376, 0.93684363, 5.92219622, -1.53527887, 1.87941418, -4.5708326, 0.70187027 ] vqe._ret = {} vqe._ret['opt_params'] = opt_params vqe._ret['opt_params_dict'] = \ dict(zip(sorted(wavefunction.parameters, key=lambda p: p.name), opt_params)) optimal_vector = vqe.get_optimal_vector() self.assertAlmostEqual(sum([v**2 for v in optimal_vector.values()]), 1.0, places=4) def test_with_aer_statevector(self): """Test VQE with Aer's statevector_simulator.""" try: # pylint: disable=import-outside-toplevel from qiskit import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('statevector_simulator') wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() vqe = VQE(self.h2_op, wavefunction, optimizer, max_evals_grouped=1) quantum_instance = QuantumInstance( backend, seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed) result = vqe.run(quantum_instance) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) def test_with_aer_qasm(self): """Test VQE with Aer's qasm_simulator.""" try: # pylint: disable=import-outside-toplevel from qiskit import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') optimizer = SPSA(maxiter=200, last_avg=5) wavefunction = self.ry_wavefunction vqe = VQE(self.h2_op, wavefunction, optimizer, expectation=PauliExpectation()) quantum_instance = QuantumInstance( backend, seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed) result = vqe.run(quantum_instance) self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2) def test_with_aer_qasm_snapshot_mode(self): """Test the VQE using Aer's qasm_simulator snapshot mode.""" try: # pylint: disable=import-outside-toplevel from qiskit import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') optimizer = L_BFGS_B() wavefunction = self.ry_wavefunction vqe = VQE(self.h2_op, wavefunction, optimizer, expectation=AerPauliExpectation()) quantum_instance = QuantumInstance( backend, shots=1, seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed) result = vqe.run(quantum_instance) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) def test_callback(self): """Test the callback on VQE.""" history = {'eval_count': [], 'parameters': [], 'mean': [], 'std': []} def store_intermediate_result(eval_count, parameters, mean, std): history['eval_count'].append(eval_count) history['parameters'].append(parameters) history['mean'].append(mean) history['std'].append(std) optimizer = COBYLA(maxiter=3) wavefunction = self.ry_wavefunction vqe = VQE(self.h2_op, wavefunction, optimizer, callback=store_intermediate_result) vqe.run(self.qasm_simulator) self.assertTrue( all(isinstance(count, int) for count in history['eval_count'])) self.assertTrue( all(isinstance(mean, float) for mean in history['mean'])) self.assertTrue(all(isinstance(std, float) for std in history['std'])) for params in history['parameters']: self.assertTrue(all(isinstance(param, float) for param in params)) def test_reuse(self): """Test re-using a VQE algorithm instance.""" vqe = VQE() with self.subTest(msg='assert running empty raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() var_form = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') vqe.var_form = var_form with self.subTest(msg='assert missing operator raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() vqe.operator = self.h2_op with self.subTest(msg='assert missing backend raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.run() vqe.quantum_instance = self.statevector_simulator with self.subTest(msg='assert VQE works once all info is available'): result = vqe.run() self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) operator = PrimitiveOp( np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) with self.subTest(msg='assert minimum eigensolver interface works'): result = vqe.compute_minimum_eigenvalue(operator) self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5) def test_vqe_optimizer(self): """ Test running same VQE twice to re-use optimizer, then switch optimizer """ vqe = VQE(self.h2_op, optimizer=SLSQP(), quantum_instance=QuantumInstance( BasicAer.get_backend('statevector_simulator'))) def run_check(): result = vqe.compute_minimum_eigenvalue() self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() with self.subTest('Optimizer re-use'): run_check() with self.subTest('Optimizer replace'): vqe.optimizer = L_BFGS_B() run_check() def test_vqe_expectation_select(self): """Test expectation selection with Aer's qasm_simulator.""" try: # pylint: disable=import-outside-toplevel from qiskit import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') with self.subTest('Defaults'): vqe = VQE(self.h2_op, quantum_instance=backend) self.assertIsInstance(vqe.expectation, PauliExpectation) with self.subTest('Include custom'): vqe = VQE(self.h2_op, include_custom=True, quantum_instance=backend) self.assertIsInstance(vqe.expectation, AerPauliExpectation) with self.subTest('Set explicitly'): vqe = VQE(self.h2_op, expectation=AerPauliExpectation(), quantum_instance=backend) self.assertIsInstance(vqe.expectation, AerPauliExpectation) @unittest.skip(reason="IBMQ testing not available in general.") def test_ibmq(self): """ IBMQ VQE Test """ from qiskit import IBMQ provider = IBMQ.load_account() backend = provider.get_backend('ibmq_qasm_simulator') ansatz = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') opt = SLSQP(maxiter=1) opt.set_max_evals_grouped(100) vqe = VQE(self.h2_op, ansatz, SLSQP(maxiter=2)) result = vqe.run(backend) print(result) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) np.testing.assert_array_almost_equal(result.eigenvalue.real, self.h2_energy, 5) self.assertEqual(len(result.optimal_point), 16) self.assertIsNotNone(result.cost_function_evals) self.assertIsNotNone(result.optimizer_time) @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( operator=self.h2_op, var_form=TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz'), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend('statevector_simulator')) result0 = vqe.run() if user_expectation is not None: with self.subTest('User expectation kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest('Expectation created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) try: vqe.set_backend(BasicAer.get_backend('qasm_simulator')) except Exception as ex: # pylint: disable=broad-except self.fail("Failed to change backend. Error: '{}'".format(str(ex))) return result1 = vqe.run() if user_expectation is not None: with self.subTest( 'Change backend with user expectation, it is kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest( 'Change backend without user expectation, one created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) with self.subTest('Check results.'): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))
def test_slsqp(self): """ slsqp test """ optimizer = SLSQP(maxiter=1000, tol=1e-06) res = self._optimize(optimizer) self.assertLessEqual(res[2], 10000)
def optimizer(self, optimizer: Optional[Optimizer] = None): """Sets the optimizer to use in training process.""" if optimizer is None: optimizer = SLSQP() self._optimizer = optimizer
class TestVQE(QiskitAlgorithmsTestCase): """ Test VQE """ def setUp(self): super().setUp() self.seed = 50 algorithm_globals.random_seed = self.seed self.h2_op = -1.052373245772859 * (I ^ I) \ + 0.39793742484318045 * (I ^ Z) \ - 0.39793742484318045 * (Z ^ I) \ - 0.01128010425623538 * (Z ^ Z) \ + 0.18093119978423156 * (X ^ X) self.h2_energy = -1.85727503 self.ryrz_wavefunction = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') self.ry_wavefunction = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz') self.qasm_simulator = QuantumInstance( BasicAer.get_backend('qasm_simulator'), shots=1024, seed_simulator=self.seed, seed_transpiler=self.seed) self.statevector_simulator = QuantumInstance( BasicAer.get_backend('statevector_simulator'), shots=1, seed_simulator=self.seed, seed_transpiler=self.seed) def test_basic_aer_statevector(self): """Test the VQE on BasicAer's statevector simulator.""" wavefunction = self.ryrz_wavefunction vqe = VQE(ansatz=wavefunction, optimizer=L_BFGS_B(), quantum_instance=QuantumInstance( BasicAer.get_backend('statevector_simulator'), basis_gates=['u1', 'u2', 'u3', 'cx', 'id'], coupling_map=[[0, 1]], seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed)) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) with self.subTest(msg='test eigenvalue'): self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy) with self.subTest(msg='test dimension of optimal point'): self.assertEqual(len(result.optimal_point), 16) with self.subTest(msg='assert cost_function_evals is set'): self.assertIsNotNone(result.cost_function_evals) with self.subTest(msg='assert optimizer_time is set'): self.assertIsNotNone(result.optimizer_time) def test_circuit_input(self): """Test running the VQE on a plain QuantumCircuit object.""" wavefunction = QuantumCircuit(2).compose(EfficientSU2(2)) optimizer = SLSQP(maxiter=50) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, quantum_instance=self.statevector_simulator) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) @data( (MatrixExpectation(), 1), (AerPauliExpectation(), 1), (PauliExpectation(), 2), ) @unpack def test_construct_circuit(self, expectation, num_circuits): """Test construct circuits returns QuantumCircuits and the right number of them.""" try: wavefunction = EfficientSU2(2, reps=1) vqe = VQE(ansatz=wavefunction, expectation=expectation) params = [0] * wavefunction.num_parameters circuits = vqe.construct_circuit(parameter=params, operator=self.h2_op) self.assertEqual(len(circuits), num_circuits) for circuit in circuits: self.assertIsInstance(circuit, QuantumCircuit) except MissingOptionalLibraryError as ex: self.skipTest(str(ex)) return def test_missing_varform_params(self): """Test specifying a variational form with no parameters raises an error.""" circuit = QuantumCircuit(self.h2_op.num_qubits) vqe = VQE( ansatz=circuit, quantum_instance=BasicAer.get_backend('statevector_simulator')) with self.assertRaises(RuntimeError): vqe.compute_minimum_eigenvalue(operator=self.h2_op) @data( (SLSQP(maxiter=50), 5, 4), (SPSA(maxiter=150), 3, 2), # max_evals_grouped=n or =2 if n>2 ) @unpack def test_max_evals_grouped(self, optimizer, places, max_evals_grouped): """ VQE Optimizers test """ vqe = VQE(ansatz=self.ryrz_wavefunction, optimizer=optimizer, max_evals_grouped=max_evals_grouped, quantum_instance=self.statevector_simulator) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=places) def test_basic_aer_qasm(self): """Test the VQE on BasicAer's QASM simulator.""" optimizer = SPSA(maxiter=300, last_avg=5) wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=self.qasm_simulator) # TODO benchmark this later. result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86823, places=2) def test_qasm_aux_operators_normalized(self): """Test VQE with qasm_simulator returns normalized aux_operator eigenvalues.""" wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, quantum_instance=self.qasm_simulator) _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) opt_params = [ 3.50437328, 3.87415376, 0.93684363, 5.92219622, -1.53527887, 1.87941418, -4.5708326, 0.70187027 ] vqe._ret.optimal_point = opt_params vqe._ret.optimal_parameters = \ dict(zip(sorted(wavefunction.parameters, key=lambda p: p.name), opt_params)) optimal_vector = vqe.get_optimal_vector() self.assertAlmostEqual(sum([v**2 for v in optimal_vector.values()]), 1.0, places=4) def test_with_aer_statevector(self): """Test VQE with Aer's statevector_simulator.""" try: from qiskit.providers.aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('statevector_simulator') wavefunction = self.ry_wavefunction optimizer = L_BFGS_B() quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, max_evals_grouped=1, quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) def test_with_aer_qasm(self): """Test VQE with Aer's qasm_simulator.""" try: from qiskit.providers.aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') optimizer = SPSA(maxiter=200, last_avg=5) wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, expectation=PauliExpectation(), quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.86305, places=2) def test_with_aer_qasm_snapshot_mode(self): """Test the VQE using Aer's qasm_simulator snapshot mode.""" try: from qiskit.providers.aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') optimizer = L_BFGS_B() wavefunction = self.ry_wavefunction quantum_instance = QuantumInstance( backend, shots=1, seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed) vqe = VQE(ansatz=wavefunction, optimizer=optimizer, expectation=AerPauliExpectation(), quantum_instance=quantum_instance) result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=6) def test_with_two_qubit_reduction(self): """Test the VQE using TwoQubitReduction.""" qubit_op = PauliSumOp.from_list([ ("IIII", -0.8105479805373266), ("IIIZ", 0.17218393261915552), ("IIZZ", -0.22575349222402472), ("IZZI", 0.1721839326191556), ("ZZII", -0.22575349222402466), ("IIZI", 0.1209126326177663), ("IZZZ", 0.16892753870087912), ("IXZX", -0.045232799946057854), ("ZXIX", 0.045232799946057854), ("IXIX", 0.045232799946057854), ("ZXZX", -0.045232799946057854), ("ZZIZ", 0.16614543256382414), ("IZIZ", 0.16614543256382414), ("ZZZZ", 0.17464343068300453), ("ZIZI", 0.1209126326177663), ]) tapered_qubit_op = TwoQubitReduction(num_particles=2).convert(qubit_op) for simulator in [self.qasm_simulator, self.statevector_simulator]: with self.subTest(f"Test for {simulator}."): vqe = VQE( self.ry_wavefunction, SPSA(maxiter=300, last_avg=5), quantum_instance=simulator, ) result = vqe.compute_minimum_eigenvalue(tapered_qubit_op) energy = -1.868 if simulator == self.qasm_simulator else self.h2_energy self.assertAlmostEqual(result.eigenvalue.real, energy, places=2) def test_callback(self): """Test the callback on VQE.""" history = {'eval_count': [], 'parameters': [], 'mean': [], 'std': []} def store_intermediate_result(eval_count, parameters, mean, std): history['eval_count'].append(eval_count) history['parameters'].append(parameters) history['mean'].append(mean) history['std'].append(std) optimizer = COBYLA(maxiter=3) wavefunction = self.ry_wavefunction vqe = VQE(ansatz=wavefunction, optimizer=optimizer, callback=store_intermediate_result, quantum_instance=self.qasm_simulator) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertTrue( all(isinstance(count, int) for count in history['eval_count'])) self.assertTrue( all(isinstance(mean, float) for mean in history['mean'])) self.assertTrue(all(isinstance(std, float) for std in history['std'])) for params in history['parameters']: self.assertTrue(all(isinstance(param, float) for param in params)) def test_reuse(self): """Test re-using a VQE algorithm instance.""" vqe = VQE() with self.subTest(msg='assert running empty raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) ansatz = TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz') vqe.ansatz = ansatz with self.subTest(msg='assert missing operator raises AlgorithmError'): with self.assertRaises(AlgorithmError): _ = vqe.compute_minimum_eigenvalue(operator=self.h2_op) vqe.quantum_instance = self.statevector_simulator with self.subTest(msg='assert VQE works once all info is available'): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, self.h2_energy, places=5) operator = PrimitiveOp( np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) with self.subTest(msg='assert minimum eigensolver interface works'): result = vqe.compute_minimum_eigenvalue(operator=operator) self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5) def test_vqe_optimizer(self): """ Test running same VQE twice to re-use optimizer, then switch optimizer """ vqe = VQE(optimizer=SLSQP(), quantum_instance=QuantumInstance( BasicAer.get_backend('statevector_simulator'))) def run_check(): result = vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) run_check() with self.subTest('Optimizer re-use'): run_check() with self.subTest('Optimizer replace'): vqe.optimizer = L_BFGS_B() run_check() def test_vqe_expectation_select(self): """Test expectation selection with Aer's qasm_simulator.""" try: from qiskit.providers.aer import Aer except Exception as ex: # pylint: disable=broad-except self.skipTest( "Aer doesn't appear to be installed. Error: '{}'".format( str(ex))) return backend = Aer.get_backend('qasm_simulator') with self.subTest('Defaults'): vqe = VQE(quantum_instance=backend) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertIsInstance(vqe.expectation, PauliExpectation) with self.subTest('Include custom'): vqe = VQE(include_custom=True, quantum_instance=backend) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertIsInstance(vqe.expectation, AerPauliExpectation) with self.subTest('Set explicitly'): vqe = VQE(expectation=AerPauliExpectation(), quantum_instance=backend) vqe.compute_minimum_eigenvalue(operator=self.h2_op) self.assertIsInstance(vqe.expectation, AerPauliExpectation) @data(MatrixExpectation(), None) def test_backend_change(self, user_expectation): """Test that VQE works when backend changes.""" vqe = VQE( ansatz=TwoLocal(rotation_blocks=['ry', 'rz'], entanglement_blocks='cz'), optimizer=SLSQP(maxiter=2), expectation=user_expectation, quantum_instance=BasicAer.get_backend('statevector_simulator')) result0 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest('User expectation kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest('Expectation created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) try: vqe.quantum_instance = BasicAer.get_backend('qasm_simulator') except Exception as ex: # pylint: disable=broad-except self.fail("Failed to change backend. Error: '{}'".format(str(ex))) return result1 = vqe.compute_minimum_eigenvalue(operator=self.h2_op) if user_expectation is not None: with self.subTest( 'Change backend with user expectation, it is kept.'): self.assertEqual(vqe.expectation, user_expectation) else: with self.subTest( 'Change backend without user expectation, one created.'): self.assertIsInstance(vqe.expectation, ExpectationBase) with self.subTest('Check results.'): self.assertEqual(len(result0.optimal_point), len(result1.optimal_point))