def test_uccsd_hf_aer_qasm_snapshot(self): """ uccsd hf test with Aer qasm_simulator snapshot. """ 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) solver = VQE(var_form=self.var_form, optimizer=optimizer, expectation=AerPauliExpectation(), quantum_instance=QuantumInstance(backend=backend)) gsc = GroundStateEigensolver(self.fermionic_transformation, solver) result = gsc.solve(self.driver) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=3)
def test_vqe_var_forms(self, depth, places): """ VQE Var Forms test """ aqua_globals.random_seed = self.seed result = VQE( self.qubit_op, RY(self.qubit_op.num_qubits, depth=depth, entanglement='sca', entanglement_gate='crx', skip_final_ry=True), L_BFGS_B()).run( QuantumInstance(BasicAer.get_backend('statevector_simulator'), shots=1, seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=places)
def test_exact_cover_vqe(self): """ Exact Cover VQE test """ aqua_globals.random_seed = 10598 result = VQE(self.qubit_op, RYRZ(self.qubit_op.num_qubits, depth=5), COBYLA(), max_evals_grouped=2).run( QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) x = sample_most_likely(result['eigvecs'][0]) ising_sol = exact_cover.get_solution(x) oracle = self._brute_force() self.assertEqual( exact_cover.check_solution_satisfiability(ising_sol, self.list_of_subsets), oracle)
def test_clique_vqe(self): """ VQE Clique test """ aqua_globals.random_seed = 10598 result = VQE(self.qubit_op, RY(self.qubit_op.num_qubits, depth=5, entanglement='linear'), COBYLA(), max_evals_grouped=2).run( QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) x = sample_most_likely(result.eigenstate) ising_sol = clique.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [1, 1, 1, 1, 1]) oracle = self._brute_force() self.assertEqual(clique.satisfy_or_not(ising_sol, self.w, self.k), oracle)
def test_vqe(self): """ VQE test """ result = VQE(self.qubit_op, RYRZ(self.qubit_op.num_qubits), L_BFGS_B()).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)) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503) np.testing.assert_array_almost_equal(result.eigenvalue.real, -1.85727503, 5) ref_opt_params = [-0.58294401, -1.86141794, -1.97209632, -0.54796022, -0.46945572, 2.60114794, -1.15637845, 1.40498879, 1.14479635, -0.48416694, -0.66608349, -1.1367579, -2.67097002, 3.10214631, 3.10000313, 0.37235089] np.testing.assert_array_almost_equal(result.optimal_point, ref_opt_params, 5) self.assertIsNotNone(result.cost_function_evals) self.assertIsNotNone(result.optimizer_time)
def get_solver(self, transformation): num_orbitals = transformation.molecule_info['num_orbitals'] num_particles = transformation.molecule_info['num_particles'] qubit_mapping = transformation.qubit_mapping two_qubit_reduction = transformation.molecule_info[ 'two_qubit_reduction'] z2_symmetries = transformation.molecule_info['z2_symmetries'] initial_state = HartreeFock(num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries.sq_list) var_form = UCCSD(num_orbitals=num_orbitals, num_particles=num_particles, initial_state=initial_state, qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, z2_symmetries=z2_symmetries) vqe = VQE(var_form=var_form, quantum_instance=self._quantum_instance, optimizer=L_BFGS_B()) return vqe
def test_graph_partition_vqe(self): """ Graph Partition VQE test """ aqua_globals.random_seed = 10598 result = VQE(self.qubit_op, RY(self.qubit_op.num_qubits, depth=5, entanglement='linear'), SPSA(max_trials=300), max_evals_grouped=2).run( QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) x = sample_most_likely(result['eigvecs'][0]) # check against the oracle ising_sol = graph_partition.get_graph_solution(x) np.testing.assert_array_equal(ising_sol, [0, 1, 0, 1]) oracle = self._brute_force() self.assertEqual(graph_partition.objective_value(x, self.w), oracle)
def test_uccsd_hf_aer_statevector(self): """ uccsd hf test with Aer statevector """ 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') solver = VQE(var_form=self.var_form, optimizer=self.optimizer, quantum_instance=QuantumInstance(backend=backend)) gsc = GroundStateEigensolver(self.fermionic_transformation, solver) result = gsc.solve(self.driver) self.assertAlmostEqual(result.energy, self.reference_energy, places=6)
def test_graph_partition_vqe(self): """ Graph Partition VQE test """ aqua_globals.random_seed = 10213 wavefunction = RealAmplitudes(self.qubit_op.num_qubits, insert_barriers=True, reps=5, entanglement='linear') result = VQE(self.qubit_op, wavefunction, SPSA(maxiter=300), max_evals_grouped=2).run( QuantumInstance(BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) x = sample_most_likely(result.eigenstate) # check against the oracle ising_sol = graph_partition.get_graph_solution(x) self.assertEqual(graph_partition.objective_value(np.array([0, 1, 0, 1]), self.w), graph_partition.objective_value(ising_sol, self.w)) oracle = self._brute_force() self.assertEqual(graph_partition.objective_value(x, self.w), oracle)
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.energy, self.reference_energy_pUCCD, places=6)
def test_tapered_op(self): """ tapered op test """ optimizer = SLSQP(maxiter=1000) init_state = HartreeFock( num_orbitals=self.fermionic_transformation. molecule_info['num_orbitals'], qubit_mapping=self.fermionic_transformation._qubit_mapping, two_qubit_reduction=self.fermionic_transformation. _two_qubit_reduction, num_particles=self.fermionic_transformation. molecule_info['num_particles'], sq_list=self.z2_symmetries.sq_list) 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=init_state, qubit_mapping=self.fermionic_transformation._qubit_mapping, two_qubit_reduction=self.fermionic_transformation. _two_qubit_reduction, num_time_slices=1, z2_symmetries=self.z2_symmetries) 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, places=6)
def test_set_packing_vqe(self): """ set packing vqe test """ 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 wavefunction = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz', reps=3, entanglement='linear') result = VQE(self.qubit_op, wavefunction, SPSA(maxiter=200), max_evals_grouped=2).run( QuantumInstance(Aer.get_backend('qasm_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) x = sample_most_likely(result.eigenstate) ising_sol = set_packing.get_solution(x) oracle = self._brute_force() self.assertEqual(np.count_nonzero(ising_sol), oracle)
def test_set_packing_vqe(self): """ set packing vqe test """ 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 result = VQE(self.qubit_op, RY(self.qubit_op.num_qubits, depth=5, entanglement='linear'), SPSA(max_trials=200), max_evals_grouped=2).run( QuantumInstance(Aer.get_backend('qasm_simulator'))) x = sample_most_likely(result['eigvecs'][0]) ising_sol = set_packing.get_solution(x) oracle = self._brute_force() self.assertEqual(np.count_nonzero(ising_sol), oracle)
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 set_vqe_circuit(self, backend = None): #Check https://qiskit.org/documentation/tutorials/algorithms/03_vqe_simulation_with_noise.html #seed = 170 iterations = self.vqe_options['maxiter'] #aqua_globals.random_seed = seed if backend is None: backend = 'statevector_simulator' backend = Aer.get_backend(backend) counts = [] values = [] stds = [] def store_intermediate_result(eval_count, parameters, mean, std): counts.append(eval_count) values.append(mean) stds.append(std) var_form = TwoLocal(reps = self.vqe_options['n_steps'], rotation_blocks = 'ry', entanglement_blocks = 'cx', entanglement = 'linear', insert_barriers = True) spsa = SPSA(maxiter=iterations) if self.vqe_options['noise']: os.environ['QISKIT_IN_PARALLEL'] = 'TRUE' device = QasmSimulator.from_backend(device_backend) coupling_map = device.configuration().coupling_map noise_model = NoiseModel.from_backend(device) basis_gates = noise_model.basis_gates qi = QuantumInstance(backend=backend, coupling_map=coupling_map, noise_model=noise_model) else: qi = QuantumInstance(backend=backend) vqe = VQE(var_form=var_form, optimizer=spsa, callback=store_intermediate_result, quantum_instance=qi) result = vqe.compute_minimum_eigenvalue(operator=self.H) return vqe.get_optimal_circuit(), vqe.optimal_params, vqe.get_optimal_vector(), vqe.get_optimal_cost()
def _compute_gradients(self, excitation_pool, theta, delta, var_form, operator, optimizer): """ Computes the gradients for all available excitation operators. Args: excitation_pool (list): pool of excitation operators theta (list): list of (up to now) optimal parameters delta (float): finite difference step size (for gradient computation) var_form (VariationalForm): current variational form operator (BaseOperator): system Hamiltonian optimizer (Optimizer): classical optimizer algorithm Returns: list: List of pairs consisting of gradient and excitation operator. """ res = [] # compute gradients for all excitation in operator pool for exc in excitation_pool: # push next excitation to variational form var_form.push_hopping_operator(exc) # construct auxiliary VQE instance vqe = VQE(operator, var_form, optimizer) vqe.quantum_instance = self.quantum_instance vqe._operator = vqe._config_the_best_mode( operator, self.quantum_instance.backend) vqe._use_simulator_snapshot_mode = self._use_simulator_snapshot_mode # evaluate energies parameter_sets = theta + [-delta] + theta + [delta] energy_results = vqe._energy_evaluation(np.asarray(parameter_sets)) # compute gradient gradient = (energy_results[0] - energy_results[1]) / (2 * delta) res.append((np.abs(gradient), exc)) # pop excitation from variational form var_form.pop_hopping_operator() return res
def test_vqe_2_iqpe(self, mode): """ vqe to iqpe test """ backend = BasicAer.get_backend('qasm_simulator') num_qbits = self.qubit_op.num_qubits wavefunction = TwoLocal(num_qbits, ['ry', 'rz'], 'cz', reps=3) optimizer = SPSA(maxiter=10) algo = VQE(self.qubit_op, wavefunction, optimizer) quantum_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) result = algo.run(quantum_instance) self.log.debug('VQE result: %s.', result) ref_eigenval = -1.85727503 # Known reference value num_time_slices = 1 num_iterations = 6 param_dict = result.optimal_parameters if mode == 'initial_state': with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=DeprecationWarning) state_in = VarFormBased(wavefunction, param_dict) else: state_in = wavefunction.assign_parameters(param_dict) iqpe = IQPE(self.qubit_op, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) quantum_instance = QuantumInstance(backend, shots=100, seed_transpiler=self.seed, seed_simulator=self.seed) result = iqpe.run(quantum_instance) self.log.debug('top result str label: %s', result.top_measurement_label) self.log.debug('top result in decimal: %s', result.top_measurement_decimal) self.log.debug('stretch: %s', result.stretch) self.log.debug('translation: %s', result.translation) self.log.debug('final eigenvalue from QPE: %s', result.eigenvalue) self.log.debug('reference eigenvalue: %s', ref_eigenval) self.log.debug('ref eigenvalue (transformed): %s', (ref_eigenval + result.translation) * result.stretch) self.log.debug( 'reference binary str label: %s', decimal_to_binary( (ref_eigenval.real + result.translation) * result.stretch, max_num_digits=num_iterations + 3, fractional_part_only=True)) self.assertAlmostEqual(result.eigenvalue.real, ref_eigenval.real, delta=1e-2)
def supports_aux_operators(self): return VQE.supports_aux_operators()
def test_readme_sample(self): """ readme sample test """ # pylint: disable=import-outside-toplevel,redefined-builtin def print(*args): """ overloads print to log values """ if args: self.log.debug(args[0], *args[1:]) # --- Exact copy of sample code ---------------------------------------- from qiskit.chemistry import FermionicOperator from qiskit.chemistry.drivers import PySCFDriver, UnitsType from qiskit.aqua.operators import Z2Symmetries # Use PySCF, a classical computational chemistry software # package, to compute the one-body and two-body integrals in # molecular-orbital basis, necessary to form the Fermionic operator driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735', unit=UnitsType.ANGSTROM, basis='sto3g') molecule = driver.run() num_particles = molecule.num_alpha + molecule.num_beta num_spin_orbitals = molecule.num_orbitals * 2 # Build the qubit operator, which is the input to the VQE algorithm in Aqua ferm_op = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals) map_type = 'PARITY' qubit_op = ferm_op.mapping(map_type) qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) num_qubits = qubit_op.num_qubits # setup a classical optimizer for VQE from qiskit.aqua.components.optimizers import L_BFGS_B optimizer = L_BFGS_B() # setup the initial state for the variational form from qiskit.chemistry.circuit.library import HartreeFock init_state = HartreeFock(num_spin_orbitals, num_particles) # setup the variational form for VQE from qiskit.circuit.library import TwoLocal var_form = TwoLocal(num_qubits, ['ry', 'rz'], 'cz') # add the initial state var_form.compose(init_state, front=True) # setup and run VQE from qiskit.aqua.algorithms import VQE algorithm = VQE(qubit_op, var_form, optimizer) # set the backend for the quantum computation from qiskit import Aer backend = Aer.get_backend('statevector_simulator') result = algorithm.run(backend) print(result.eigenvalue.real) # ---------------------------------------------------------------------- self.assertAlmostEqual(result.eigenvalue.real, -1.8572750301938803, places=6)
def test_vqe_callback(self): tmp_filename = 'vqe_callback_test.csv' is_file_exist = os.path.exists(self._get_resource_path(tmp_filename)) if is_file_exist: os.remove(self._get_resource_path(tmp_filename)) def store_intermediate_result(eval_count, parameters, mean, std): with open(self._get_resource_path(tmp_filename), 'a') as f: content = "{},{},{:.5f},{:.5f}".format(eval_count, parameters, mean, std) print(content, file=f, flush=True) backend = BasicAer.get_backend('qasm_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 1, initial_state=init_state) optimizer = COBYLA(maxiter=3) algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'paulis', callback=store_intermediate_result) aqua_globals.random_seed = 50 quantum_instance = QuantumInstance(backend, seed_mapper=50, shots=1024, seed=50) algo.run(quantum_instance) is_file_exist = os.path.exists(self._get_resource_path(tmp_filename)) self.assertTrue(is_file_exist, "Does not store content successfully.") # check the content ref_content = [[ '1', '[-0.03391886 -1.70850424 -1.53640265 -0.65137839]', '-0.61121', '0.01572' ], [ '2', '[ 0.96608114 -1.70850424 -1.53640265 -0.65137839]', '-0.79235', '0.01722' ], [ '3', '[ 0.96608114 -0.70850424 -1.53640265 -0.65137839]', '-0.82829', '0.01529' ]] try: with open(self._get_resource_path(tmp_filename)) as f: idx = 0 for record in f.readlines(): eval_count, parameters, mean, std = record.split(",") self.assertEqual(eval_count.strip(), ref_content[idx][0]) self.assertEqual(parameters, ref_content[idx][1]) self.assertEqual(mean.strip(), ref_content[idx][2]) self.assertEqual(std.strip(), ref_content[idx][3]) idx += 1 finally: if is_file_exist: os.remove(self._get_resource_path(tmp_filename))
class TestAppMGSE(QiskitChemistryTestCase): """Test molecular ground state energy application """ def setUp(self): super().setUp() try: self.driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735', unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto3g') except QiskitChemistryError: self.skipTest('PYSCF driver does not appear to be installed') self.npme = NumPyMinimumEigensolver() self.vqe = VQE(var_form=TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')) self.vqe.set_backend(BasicAer.get_backend('statevector_simulator')) self.reference_energy = -1.137306 def test_mgse_npme(self): """ Test Molecular Ground State Energy NumPy classical solver """ warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver, self.npme) result = mgse.compute_energy() self.assertAlmostEqual(result.energy, self.reference_energy, places=5) formatted = result.formatted # Check formatted output conforms, some substrings to avoid numbers whose digits may # vary slightly self.assertEqual(len(formatted), 19) self.assertEqual(formatted[0], '=== GROUND STATE ENERGY ===') self.assertEqual(formatted[4], ' - frozen energy part: 0.0') self.assertEqual(formatted[5], ' - particle hole part: 0.0') self.assertEqual(formatted[7][0:44], '> Total ground state energy (Hartree): -1.13') self.assertEqual(formatted[8], ' Measured:: # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.00000') self.assertEqual(formatted[10], '=== DIPOLE MOMENT ===') self.assertEqual(formatted[14], ' - frozen energy part: [0.0 0.0 0.0]') self.assertEqual(formatted[15], ' - particle hole part: [0.0 0.0 0.0]') self.assertEqual(formatted[18], ' (debye): [0.0 0.0 0.0] Total: 0.') warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_vqe(self): """ Test Molecular Ground State Energy VQE solver """ warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver, self.vqe) result = mgse.compute_energy() self.assertAlmostEqual(result.energy, self.reference_energy, places=5) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_solver(self): """ Test Molecular Ground State Energy setting solver """ warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver) with self.assertRaises(QiskitChemistryError): _ = mgse.compute_energy() mgse.solver = self.npme result = mgse.compute_energy() self.assertAlmostEqual(result.energy, self.reference_energy, places=5) mgse.solver = self.vqe result = mgse.compute_energy() self.assertAlmostEqual(result.energy, self.reference_energy, places=5) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_callback_ipqe(self): """ Callback test setting up Hartree Fock with IQPE """ def cb_create_solver(num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): state_in = HartreeFock(num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries.sq_list) iqpe = IQPE(None, state_in, num_time_slices=1, num_iterations=6, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) iqpe.quantum_instance = QuantumInstance(BasicAer.get_backend('qasm_simulator'), shots=100) return iqpe warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver) result = mgse.compute_energy(cb_create_solver) np.testing.assert_approx_equal(result.energy, self.reference_energy, significant=2) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_callback_vqe_uccsd(self): """ Callback test setting up Hartree Fock with UCCSD and VQE """ def cb_create_solver(num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): initial_state = HartreeFock(num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries.sq_list) var_form = UCCSD(num_orbitals=num_orbitals, num_particles=num_particles, initial_state=initial_state, qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, z2_symmetries=z2_symmetries) vqe = VQE(var_form=var_form, optimizer=SLSQP(maxiter=500)) vqe.quantum_instance = BasicAer.get_backend('statevector_simulator') return vqe warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver) result = mgse.compute_energy(cb_create_solver) self.assertAlmostEqual(result.energy, self.reference_energy, places=5) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_callback(self): """ Callback testing """ warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver) result = mgse.compute_energy(lambda *args: NumPyMinimumEigensolver()) self.assertAlmostEqual(result.energy, self.reference_energy, places=5) result = mgse.compute_energy(lambda *args: self.vqe) self.assertAlmostEqual(result.energy, self.reference_energy, places=5) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_default_solver(self): """ Callback testing using default solver """ warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(self.driver) result = mgse.compute_energy(mgse.get_default_solver( BasicAer.get_backend('statevector_simulator'))) self.assertAlmostEqual(result.energy, self.reference_energy, places=5) q_inst = QuantumInstance(BasicAer.get_backend('statevector_simulator')) result = mgse.compute_energy(mgse.get_default_solver(q_inst)) self.assertAlmostEqual(result.energy, self.reference_energy, places=5) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_callback_vqe_uccsd_z2(self): """ Callback test setting up Hartree Fock with UCCSD and VQE, plus z2 symmetries """ def cb_create_solver(num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): initial_state = HartreeFock(num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries.sq_list) var_form = UCCSD(num_orbitals=num_orbitals, num_particles=num_particles, initial_state=initial_state, qubit_mapping=qubit_mapping, two_qubit_reduction=two_qubit_reduction, z2_symmetries=z2_symmetries) vqe = VQE(var_form=var_form, optimizer=SLSQP(maxiter=500)) vqe.quantum_instance = BasicAer.get_backend('statevector_simulator') return vqe driver = PySCFDriver(atom='Li .0 .0 -0.8; H .0 .0 0.8') warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(driver, qubit_mapping=QubitMappingType.JORDAN_WIGNER, two_qubit_reduction=False, freeze_core=True, z2symmetry_reduction='auto') result = mgse.compute_energy(cb_create_solver) self.assertAlmostEqual(result.energy, -7.882, places=3) warnings.filterwarnings('always', category=DeprecationWarning) def test_mgse_callback_vqe_uccsd_z2_nosymm(self): """ This time we reduce the operator so it has symmetries left. Whether z2 symmetry reduction is set to auto, or left turned off, the results should be same. We explicitly check the Z2 symmetry to ensure it empty and use classical solver to ensure the operators via the subsequent result computation are correct. """ z2_symm = None def cb_create_solver(num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): nonlocal z2_symm z2_symm = z2_symmetries return NumPyMinimumEigensolver() driver = PySCFDriver(atom='Li .0 .0 -0.8; H .0 .0 0.8') warnings.filterwarnings('ignore', category=DeprecationWarning) mgse = MolecularGroundStateEnergy(driver, qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=True, orbital_reduction=[-3, -2], z2symmetry_reduction='auto') result = mgse.compute_energy(cb_create_solver) # Check a couple of values are as expected, energy for main operator and number of # particles and dipole from auxiliary operators. self.assertEqual(z2_symm.is_empty(), True) self.assertAlmostEqual(result.energy, -7.881, places=3) self.assertAlmostEqual(result.num_particles, 2) self.assertAlmostEqual(result.total_dipole_moment_in_debye, 4.667, places=3) # Run with no symmetry reduction, which should match the prior result since there # are no symmetries to be found. mgse1 = MolecularGroundStateEnergy(driver, qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=True, freeze_core=True, orbital_reduction=[-3, -2]) result1 = mgse1.compute_energy(cb_create_solver) self.assertEqual(z2_symm.is_empty(), True) self.assertEqual(str(result), str(result1)) # Compare string form of results warnings.filterwarnings('always', category=DeprecationWarning)
def test_vqe_2_iqpe(self, wavefunction_type): """ vqe to iqpe test """ backend = BasicAer.get_backend('qasm_simulator') num_qbits = self.qubit_op.num_qubits if wavefunction_type == 'wrapped': warnings.filterwarnings('ignore', category=DeprecationWarning) wavefunction = RYRZ(num_qbits, 3) else: wavefunction = TwoLocal(num_qbits, ['ry', 'rz'], 'cz', reps=3, insert_barriers=True) theta = ParameterVector('theta', wavefunction.num_parameters) wavefunction.assign_parameters(theta, inplace=True) if wavefunction_type == 'circuit': wavefunction = QuantumCircuit(num_qbits).compose(wavefunction) optimizer = SPSA(max_trials=10) algo = VQE(self.qubit_op, wavefunction, optimizer) if wavefunction_type == 'wrapped': warnings.filterwarnings('always', category=DeprecationWarning) quantum_instance = QuantumInstance(backend, seed_simulator=self.seed, seed_transpiler=self.seed) result = algo.run(quantum_instance) self.log.debug('VQE result: %s.', result) ref_eigenval = -1.85727503 # Known reference value num_time_slices = 1 num_iterations = 6 if wavefunction_type == 'wrapped': param_dict = result.optimal_point else: param_dict = result.optimal_parameters state_in = VarFormBased(wavefunction, param_dict) iqpe = IQPE(self.qubit_op, state_in, num_time_slices, num_iterations, expansion_mode='suzuki', expansion_order=2, shallow_circuit_concat=True) quantum_instance = QuantumInstance(backend, shots=100, seed_transpiler=self.seed, seed_simulator=self.seed) result = iqpe.run(quantum_instance) self.log.debug('top result str label: %s', result.top_measurement_label) self.log.debug('top result in decimal: %s', result.top_measurement_decimal) self.log.debug('stretch: %s', result.stretch) self.log.debug('translation: %s', result.translation) self.log.debug('final eigenvalue from QPE: %s', result.eigenvalue) self.log.debug('reference eigenvalue: %s', ref_eigenval) self.log.debug('ref eigenvalue (transformed): %s', (ref_eigenval + result.translation) * result.stretch) self.log.debug( 'reference binary str label: %s', decimal_to_binary( (ref_eigenval.real + result.translation) * result.stretch, max_num_digits=num_iterations + 3, fractional_part_only=True)) np.testing.assert_approx_equal(result.eigenvalue.real, ref_eigenval, significant=2)
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'))
class SeparableInitialStateReal(InitialState): """An initial state constructed from a completely separable VQE ansatz.""" CONFIGURATION = { 'name': 'VQE-Separable-State', 'description': 'VQE Separable initial state', 'input_schema': { '$schema': 'http://json-schema.org/schema#', 'id': 'separable_state_schema', 'type': 'object', 'properties': {}, 'additionalProperties': False } } def __init__(self, operator, optimizer, **vqe_kwargs): """Initialize separable state object. Parameters ---------- operator : Operator Operator to minimize the separable state with respect to. optimizer : Optimzer Optimizer to use for determining optimal separable state. **vqe_kwargs : type Options for VQE that determines optimal initial state. """ super().__init__() self.vqe = VQE(operator=operator, var_form=SingleQubitRotationsReal(operator.num_qubits), optimizer=optimizer, **vqe_kwargs) self._circuit = None self._result = None def initialize(self, quantum_instance): """Initialize the separable initial state. Parameters ---------- quantum_instance : QuantumInstance What device/simulator to use for determining the optimal separable state. """ if self._circuit is None: self._result = self.vqe.run(quantum_instance) logger.info('Found initial separable state cost {}'.format( self.vqe.get_optimal_cost())) self._circuit = self.vqe.get_optimal_circuit() return self._circuit else: return self._circuit def construct_circuit(self, mode='circuit', register=None): """Return the optimal separable state. Parameters ---------- mode : str Mode to use for construction. register : type Register to use for constructing circuit. Currently unused. Returns ------- QuantumCircuit Circuit that prepares optimal separable state. """ if mode != 'circuit': raise ValueError('Selected mode {} is not supported'.format(mode)) if self._circuit is None: raise ValueError('Initial state has not yet been initialized.') circuit = self._circuit return circuit
backend = BasicAer.get_backend("statevector_simulator") distances = np.arange(0.5) exact_energies = [] vqe_energies = [] optimizer = SLSQP(maxiter=5) for dist in distances: qubitOp, num_particles, num_spin_orbitals, shift = get_qubit_op(dist) result = ExactEigensolver(qubitOp).run() exact_energies.append(result['energy'] + shift) initial_state = HartreeFock( qubitOp.num_qubits, num_spin_orbitals, num_particles, 'parity' ) var_form = UCCSD( qubitOp.num_qubits, depth=1, num_orbitals=num_spin_orbitals, num_particles=num_particles, initial_state=initial_state, qubit_mapping='parity' ) vqe = VQE(qubitOp, var_form, optimizer, 'matrix') results = vqe.run(backend)['energy'] + shift vqe_energies.append(results) print("Interatomic Distance:", np.round(dist, 2), "VQE Result:", results, "Exact Energy:", exact_energies[-1]) print("All energies have been calculated")
def test_vqe_reuse(self): """ Test vqe reuse """ vqe = VQE() with self.assertRaises(AquaError): _ = vqe.run() num_qubits = self.qubit_op.num_qubits var_form = RY(num_qubits, depth=3) vqe.var_form = var_form with self.assertRaises(AquaError): _ = vqe.run() vqe.operator = self.qubit_op with self.assertRaises(AquaError): _ = vqe.run() qinst = QuantumInstance(BasicAer.get_backend('statevector_simulator')) vqe.quantum_instance = qinst result = vqe.run() self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5) operator = MatrixOperator(np.array([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]])) vqe.operator = operator result = vqe.run() self.assertAlmostEqual(result.eigenvalue.real, -1.0, places=5)
return qubitOp, num_particles, num_spin_orbitals, nuc_energy # Now, we load a device coupling map and noise model from the IBMQ provider # and create a quantum instance, enabling error mitigation: IBMQ.load_account() provider = IBMQ.get_provider(hub='ibm-q') backend = Aer.get_backend("qasm_simulator") device = provider.get_backend("ibmqx2") coupling_map = device.configuration().coupling_map noise_model = NoiseModel.from_backend(device.properties()) quantum_instance = QuantumInstance( backend=backend, shots=1000, noise_model=noise_model, coupling_map=coupling_map, measurement_error_mitigation_cls=CompleteMeasFitter, cals_matrix_refresh_period=30, ) dist = 0.725 qubitOp, num_particles, num_spin_orbitals, nuc_energy = get_qubit_op(dist) exact_solution = ExactEigensolver(qubitOp).run() print("Exact Result:", exact_solution['energy']) optimizer = SPSA(max_trials=100) var_form = RYRZ(qubitOp.num_qubits, depth=1, entanglement="linear") vqe = VQE(qubitOp, var_form, optimizer=optimizer) ret = vqe.run(quantum_instance) print("VQE Result:", ret['energy'])
def test_vqe_mes(self): """ Test vqe minimum eigen solver interface """ vqe = VQE(var_form=RY(self.qubit_op.num_qubits, depth=3), optimizer=COBYLA()) vqe.set_backend(BasicAer.get_backend('statevector_simulator')) result = vqe.compute_minimum_eigenvalue(self.qubit_op) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=5)
def _run(self) -> 'VQEAdaptResult': """ Run the algorithm to compute the minimum eigenvalue. Returns: dict: Dictionary of results Raises: AquaError: wrong setting of operator and backend. """ self._ret = {} # TODO should be eliminated # self._operator = VQE._config_the_best_mode(self, self._operator, # self._quantum_instance.backend) self._quantum_instance.circuit_summary = True threshold_satisfied = False alternating_sequence = False max_iterations_exceeded = False prev_op_indices = [] theta = [] # type: List max_grad = (0, 0) iteration = 0 while self._max_iterations is None or iteration < self._max_iterations: iteration += 1 logger.info('--- Iteration #%s ---', str(iteration)) # compute gradients cur_grads = self._compute_gradients(self._excitation_pool, theta, self._delta, self._var_form_base, self._operator, self._optimizer) # pick maximum gradient max_grad_index, max_grad = max(enumerate(cur_grads), key=lambda item: np.abs(item[1][0])) # store maximum gradient's index for cycle detection prev_op_indices.append(max_grad_index) # log gradients gradlog = "\nGradients in iteration #{}".format(str(iteration)) gradlog += "\nID: Excitation Operator: Gradient <(*) maximum>" for i, grad in enumerate(cur_grads): gradlog += '\n{}: {}: {}'.format(str(i), str(grad[1]), str(grad[0])) if grad[1] == max_grad[1]: gradlog += '\t(*)' logger.info(gradlog) if np.abs(max_grad[0]) < self._threshold: logger.info( "Adaptive VQE terminated succesfully with a final maximum gradient: %s", str(np.abs(max_grad[0]))) threshold_satisfied = True break # check indices of picked gradients for cycles if VQEAdapt._check_cyclicity(prev_op_indices): logger.info("Alternating sequence found. Finishing.") logger.info("Final maximum gradient: %s", str(np.abs(max_grad[0]))) alternating_sequence = True break # add new excitation to self._var_form_base self._var_form_base.push_hopping_operator(max_grad[1]) theta.append(0.0) # run VQE on current Ansatz algorithm = VQE(self._operator, self._var_form_base, self._optimizer, initial_point=theta) vqe_result = algorithm.run(self._quantum_instance) self._ret['opt_params'] = vqe_result.optimal_point theta = vqe_result.optimal_point.tolist() else: # reached maximum number of iterations max_iterations_exceeded = True logger.info("Maximum number of iterations reached. Finishing.") logger.info("Final maximum gradient: %s", str(np.abs(max_grad[0]))) # once finished evaluate auxiliary operators if any if self._aux_operators is not None and self._aux_operators: algorithm = VQE(self._operator, self._var_form_base, self._optimizer, initial_point=theta, aux_operators=self._aux_operators) vqe_result = algorithm.run(self._quantum_instance) self._ret['opt_params'] = vqe_result.optimal_point if threshold_satisfied: finishing_criterion = 'Threshold converged' elif alternating_sequence: finishing_criterion = 'Aborted due to cyclicity' elif max_iterations_exceeded: finishing_criterion = 'Maximum number of iterations reached' else: raise AquaError( 'The algorithm finished due to an unforeseen reason!') # extend VQE returned information with additional outputs result = VQEAdaptResult() result.combine(vqe_result) result.num_iterations = iteration result.final_max_gradient = max_grad[0] result.finishing_criterion = finishing_criterion logger.info('The final energy is: %s', str(result.optimal_value.real)) return result
def _run(self) -> 'VQEAdaptResult': """ Run the algorithm to compute the minimum eigenvalue. Returns: dict: Dictionary of results Raises: AquaError: wrong setting of operator and backend. """ self._ret = {} # TODO should be eliminated self._operator = VQE._config_the_best_mode( self, self._operator, self._quantum_instance.backend) self._use_simulator_snapshot_mode = \ is_aer_statevector_backend(self._quantum_instance.backend) \ and isinstance(self._operator, (WeightedPauliOperator, TPBGroupedWeightedPauliOperator)) self._quantum_instance.circuit_summary = True cycle_regex = re.compile(r'(.+)( \1)+') # reg-ex explanation: # 1. (.+) will match at least one number and try to match as many as possible # 2. the match of this part is placed into capture group 1 # 3. ( \1)+ will match a space followed by the contents of capture group 1 # -> this results in any number of repeating numbers being detected threshold_satisfied = False alternating_sequence = False prev_op_indices = [] theta = [] max_grad = () iteration = 0 while not threshold_satisfied and not alternating_sequence: iteration += 1 logger.info('--- Iteration #%s ---', str(iteration)) # compute gradients cur_grads = self._compute_gradients(self._excitation_pool, theta, self._delta, self._var_form_base, self._operator, self._optimizer) # pick maximum gradient max_grad_index, max_grad = max(enumerate(cur_grads), key=lambda item: np.abs(item[1][0])) # store maximum gradient's index for cycle detection prev_op_indices.append(max_grad_index) # log gradients gradlog = "\nGradients in iteration #{}".format(str(iteration)) gradlog += "\nID: Excitation Operator: Gradient <(*) maximum>" for i, grad in enumerate(cur_grads): gradlog += '\n{}: {}: {}'.format(str(i), str(grad[1]), str(grad[0])) if grad[1] == max_grad[1]: gradlog += '\t(*)' logger.info(gradlog) if np.abs(max_grad[0]) < self._threshold: logger.info( "Adaptive VQE terminated succesfully with a final maximum gradient: %s", str(np.abs(max_grad[0]))) threshold_satisfied = True break # check indices of picked gradients for cycles if cycle_regex.search(' '.join(map(str, prev_op_indices))) is not None: logger.info("Alternating sequence found. Finishing.") logger.info("Final maximum gradient: %s", str(np.abs(max_grad[0]))) alternating_sequence = True break # add new excitation to self._var_form_base self._var_form_base.push_hopping_operator(max_grad[1]) theta.append(0.0) # run VQE on current Ansatz algorithm = VQE(self._operator, self._var_form_base, self._optimizer, initial_point=theta) vqe_result = algorithm.run(self._quantum_instance) self._ret['opt_params'] = vqe_result.optimal_point theta = vqe_result.optimal_point.tolist() # once finished evaluate auxiliary operators if any if self._aux_operators is not None and self._aux_operators: algorithm = VQE(self._operator, self._var_form_base, self._optimizer, initial_point=theta, aux_operators=self._aux_operators) vqe_result = algorithm.run(self._quantum_instance) self._ret['opt_params'] = vqe_result.optimal_point if threshold_satisfied: finishing_criterion = 'Threshold converged' elif alternating_sequence: finishing_criterion = 'Aborted due to cyclicity' else: raise AquaError( 'The algorithm finished due to an unforeseen reason!') # extend VQE returned information with additional outputs result = VQEAdaptResult() result.combine(vqe_result) result.num_iterations = iteration result.final_max_gradient = max_grad[0] result.finishing_criterion = finishing_criterion logger.info('The final energy is: %s', str(result.optimal_value.real)) return result