class TestInitialStateZero(QiskitAquaTestCase): def test_qubits_2_vector(self): self.zero = Zero(2) cct = self.zero.construct_circuit('vector') np.testing.assert_array_equal(cct, [1.0, 0.0, 0.0, 0.0]) def test_qubits_5_vector(self): self.zero = Zero(5) cct = self.zero.construct_circuit('vector') np.testing.assert_array_equal(cct, [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ]) def test_qubits_2_circuit(self): self.zero = Zero(2) cct = self.zero.construct_circuit('circuit') self.assertEqual(cct.qasm(), 'OPENQASM 2.0;\ninclude "qelib1.inc";\nqreg q[2];\n') def test_qubits_5_circuit(self): self.zero = Zero(5) cct = self.zero.construct_circuit('circuit') self.assertEqual(cct.qasm(), 'OPENQASM 2.0;\ninclude "qelib1.inc";\nqreg q[5];\n')
def test_qubits_5_circuit(self): """ Qubits 5 circuit test """ zero = Zero(5) cct = zero.construct_circuit('circuit') # pylint: disable=no-member self.assertEqual(cct.qasm(), 'OPENQASM 2.0;\ninclude "qelib1.inc";\nqreg q[5];\n')
def test_qubits_5_vector(self): self.zero = Zero(5) cct = self.zero.construct_circuit('vector') np.testing.assert_array_equal(cct, [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
def test_saving_and_loading_e2e(self): backend = BasicAer.get_backend('statevector_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 = L_BFGS_B(maxiter=10) algo = VQE(self.algo_input.qubit_op, var_form, optimizer) with tempfile.NamedTemporaryFile(suffix='.inp', delete=True) as cache_tmp_file: cache_tmp_file_name = cache_tmp_file.name quantum_instance_caching = QuantumInstance( backend, circuit_caching=True, cache_file=cache_tmp_file_name, skip_qobj_deepcopy=True, skip_qobj_validation=True, optimization_level=self.optimization_level) algo.run(quantum_instance_caching) self.assertLessEqual(quantum_instance_caching.circuit_cache.misses, 0) is_file_exist = os.path.exists(cache_tmp_file_name) self.assertTrue(is_file_exist, "Does not store content successfully.") circuit_cache_new = CircuitCache(skip_qobj_deepcopy=True, cache_file=cache_tmp_file_name) self.assertEqual(quantum_instance_caching.circuit_cache.mappings, circuit_cache_new.mappings) self.assertLessEqual(circuit_cache_new.misses, 0)
def test_saving_and_loading(self): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix') fd, cache_tmp_file = tempfile.mkstemp(suffix='.inp') os.close(fd) quantum_instance_caching = QuantumInstance(backend, circuit_caching=True, cache_file=cache_tmp_file, skip_qobj_deepcopy=True, skip_qobj_validation=True) algo.run(quantum_instance_caching) self.assertLessEqual(quantum_instance_caching.circuit_cache.misses, 0) is_file_exist = os.path.exists(cache_tmp_file) self.assertTrue(is_file_exist, "Does not store content successfully.") circuit_cache_new = CircuitCache(skip_qobj_deepcopy=True, cache_file=cache_tmp_file) self.assertEqual(quantum_instance_caching.circuit_cache.mappings, circuit_cache_new.mappings) self.assertLessEqual(circuit_cache_new.misses, 0) if is_file_exist: os.remove(cache_tmp_file)
def test_vqe_callback(self, var_form_type): """ VQE Callback test """ 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) backend = BasicAer.get_backend('qasm_simulator') num_qubits = self.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, depth=1, initial_state=init_state) if var_form_type is QuantumCircuit: params = ParameterVector('θ', var_form.num_parameters) var_form = var_form.construct_circuit(params) optimizer = COBYLA(maxiter=3) algo = VQE(self.qubit_op, var_form, optimizer, callback=store_intermediate_result, auto_conversion=False) aqua_globals.random_seed = 50 quantum_instance = QuantumInstance(backend, seed_transpiler=50, shots=1024, seed_simulator=50) algo.run(quantum_instance) 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_state_preparation_type_error(self): """Test InitialState state_preparation with QuantumCircuit oracle""" init_state = Zero(2) oracle = QuantumCircuit(2) oracle.cz(0, 1) with self.assertRaises(TypeError): Grover(oracle=oracle, state_preparation=init_state)
def test_vqe_caching_direct(self, max_evals_grouped): self._build_refrence_result(backends=['statevector_simulator']) backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, max_evals_grouped=max_evals_grouped) quantum_instance_caching = QuantumInstance( backend, circuit_caching=True, skip_qobj_deepcopy=True, skip_qobj_validation=True, optimization_level=self.optimization_level) result_caching = algo.run(quantum_instance_caching) self.assertLessEqual(quantum_instance_caching.circuit_cache.misses, 0) self.assertAlmostEqual( self.reference_vqe_result['statevector_simulator']['energy'], result_caching['energy']) speedup_min = 3 speedup = result_caching['eval_time'] / self.reference_vqe_result[ 'statevector_simulator']['eval_time'] self.assertLess(speedup, speedup_min)
def test_vqe_caching_direct(self, batch_mode=True): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix', batch_mode=batch_mode) quantum_instance_caching = QuantumInstance(backend, circuit_caching=True, skip_qobj_deepcopy=True, skip_qobj_validation=True) result_caching = algo.run(quantum_instance_caching) self.assertLessEqual(quantum_instance_caching.circuit_cache.misses, 0) self.assertAlmostEqual( self.reference_vqe_result['statevector_simulator']['energy'], result_caching['energy']) speedup_check = 3 self.log.info( result_caching['eval_time'], self.reference_vqe_result['statevector_simulator']['eval_time'] / speedup_check)
def test_qaoa_initial_state(self, w, init_state): """ QAOA initial state test """ optimizer = COBYLA() qubit_op, _ = max_cut.get_operator(w) init_pt = [0.0, 0.0] # Avoid generating random initial point if init_state is None: initial_state = None else: initial_state = Custom(num_qubits=4, state_vector=init_state) quantum_instance = QuantumInstance( BasicAer.get_backend('statevector_simulator')) qaoa_zero_init_state = QAOA(qubit_op, optimizer, initial_point=init_pt, initial_state=Zero(qubit_op.num_qubits), quantum_instance=quantum_instance) qaoa = QAOA(qubit_op, optimizer, initial_point=init_pt, initial_state=initial_state, quantum_instance=quantum_instance) zero_circuits = qaoa_zero_init_state.construct_circuit(init_pt) custom_circuits = qaoa.construct_circuit(init_pt) self.assertEqual(len(zero_circuits), len(custom_circuits)) backend = BasicAer.get_backend('statevector_simulator') for zero_circ, custom_circ in zip(zero_circuits, custom_circuits): z_length = len(zero_circ.data) c_length = len(custom_circ.data) self.assertGreaterEqual(c_length, z_length) self.assertTrue(zero_circ.data == custom_circ.data[-z_length:]) custom_init_qc = custom_circ.copy() custom_init_qc.data = custom_init_qc.data[0:c_length - z_length] if initial_state is None: original_init_qc = QuantumCircuit(qubit_op.num_qubits) original_init_qc.h(range(qubit_op.num_qubits)) else: original_init_qc = initial_state.construct_circuit() job_init_state = execute(original_init_qc, backend) job_qaoa_init_state = execute(custom_init_qc, backend) statevector_original = job_init_state.result().get_statevector( original_init_qc) statevector_custom = job_qaoa_init_state.result().get_statevector( custom_init_qc) self.assertEqual(statevector_original.tolist(), statevector_custom.tolist())
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 = get_aer_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) algo.random_seed = 50 run_config = RunConfig(shots=1024, seed=50) quantum_instance = QuantumInstance(backend, seed_mapper=50, run_config=run_config) 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.59622", "0.01546" ], [ "2", "[ 0.96608114 -1.70850424 -1.53640265 -0.65137839]", "-0.77452", "0.01692" ], [ "3", "[ 0.96608114 -0.70850424 -1.53640265 -0.65137839]", "-0.80327", "0.01519" ]] 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 if is_file_exist: os.remove(self._get_resource_path(tmp_filename))
def __init__( self, operator_pool: OperatorPool, initial_state: Union[InitialState, None], vqe_optimizer: Optimizer, hamiltonian: BaseOperator, max_iters: int = 10, grad_tol: float = 1e-3, max_evals_grouped=1, aux_operators=None, auto_conversion=True, use_zero_initial_parameters=False ): super().__init__() self.operator_pool = copy.deepcopy(operator_pool) if initial_state is None: self.initial_state = Zero(num_qubits=operator_pool.num_qubits) else: self.initial_state = initial_state self.vqe_optimizer = vqe_optimizer self.hamiltonian = hamiltonian self.max_iters = max_iters self.grad_tol = grad_tol self.max_evals_grouped = max_evals_grouped self.aux_operators = aux_operators self.auto_conversion = auto_conversion self.use_zero_initial_parameters = use_zero_initial_parameters self.parameters_per_step = 1 self._coms = None self.first_step = False self._current_max_grad = None self._optimal_circuit = None self._ret = {} self.adapt_step_history = { 'gradient_list': [], # updated in _compute_gradients 'max_gradient': [], # updated in _ansatz_operator_list 'optimal_parameters': [], # updated in _run 'circuit': [], # updated in _run 'operators': [], # updated in _ansatz_operator_list 'vqe_ret': [], # updated in _run 'energy_history': [], # updated in _run 'Total Eval Time': 0, #added by WillB 'Total num evals': 0 #added by WillB }
def __init__( self, operator_pool, initial_state, vqe_optimizer, hamiltonian, max_iters, energy_step_tol= 1e-8, auto_conversion=True, use_zero_initial_parameters=False, postprocessing = False, include_parameter = True ): #most of these params no longer matter, should edit to remove necessity self._quantum_instance = None super().__init__(operator_pool, initial_state, vqe_optimizer, hamiltonian, max_iters, #mximum number of iterations grad_tol = 1e-3, #stopping criteria if we were using gradient tolerance (we're not) max_evals_grouped=1,#unsure what this means aux_operators=None, #additional operators in pool auto_conversion=True, #when using VQE algorithm auto converts operators to best representaiton for backend use_zero_initial_parameters=False #Make your parameters start at zero before gradient based optimization ) #initialization from ADAPTVQE self.energy_step_tol = energy_step_tol #the stopping criteria for energy step self.hamiltonian = hamiltonian self.postprocessing = postprocessing self.include_parameter = include_parameter if initial_state is None: #creates new initial state if none passed self.initial_state = Zero(num_qubits=operator_pool.num_qubits) #Custom(hamiltonian.num_qubits, state='uniform') else: self.initial_state = initial_state #clean up old dictionary del self.adapt_step_history['gradient_list'] del self.adapt_step_history['max_gradient'] #del self.adapt_step_history['vqe_ret'] #self.adapt_step_history.update({'Total Eval Time': 0}) #self.adapt_step_history.update({'Total num Evals': 0}) self.adapt_step_history.update({'Total number energy iterations': 0}) self.adapt_step_history.update({'Max Energy Step': 0})
def test_vqe_callback(self): """ VQE Callback test """ 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 file: content = "{},{},{:.5f},{:.5f}".format(eval_count, parameters, mean, std) print(content, file=file, flush=True) backend = BasicAer.get_backend('qasm_simulator') num_qubits = self.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.qubit_op, var_form, optimizer, callback=store_intermediate_result, auto_conversion=False) aqua_globals.random_seed = 50 quantum_instance = QuantumInstance(backend, seed_transpiler=50, shots=1024, seed_simulator=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 file: idx = 0 for record in file.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))
def test_vqe_direct(self, max_evals_grouped): backend = BasicAer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'paulis', max_evals_grouped=max_evals_grouped) quantum_instance = QuantumInstance(backend) result = algo.run(quantum_instance) self.assertAlmostEqual(result['energy'], -1.85727503) if quantum_instance.has_circuit_caching: self.assertLess(quantum_instance._circuit_cache.misses, 3)
def test_vqe_direct(self, batch_mode): backend = get_aer_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'paulis', batch_mode=batch_mode) quantum_instance = QuantumInstance(backend) result = algo.run(quantum_instance) self.assertAlmostEqual(result['energy'], -1.85727503)
def test_vqe_aer_mode(self): try: from qiskit import Aer except Exception as e: self.skipTest("Aer doesn't appear to be installed. Error: '{}'".format(str(e))) return backend = Aer.get_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, max_evals_grouped=1) quantum_instance = QuantumInstance(backend) result = algo.run(quantum_instance) self.assertAlmostEqual(result['energy'], -1.85727503, places=6)
def test_state_preparation_type_error(self): """Test InitialState state_preparation with QuantumCircuit oracle""" init_state = Zero(2) oracle = QuantumCircuit(2) oracle.cz(0, 1) # filtering the following: # DeprecationWarning: Passing an InitialState component is deprecated as of 0.8.0, # and will be removed no earlier than 3 months after the release date. # You should pass a QuantumCircuit instead. try: warnings.filterwarnings(action="ignore", category=DeprecationWarning) with self.assertRaises(TypeError): Grover(oracle=oracle, state_preparation=init_state) finally: warnings.filterwarnings(action="always", category=DeprecationWarning)
def test_vqe_qasm_snapshot_mode(self): """ VQE Aer qasm_simulator snapshot mode 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 backend = Aer.get_backend('qasm_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, max_evals_grouped=1) quantum_instance = QuantumInstance(backend, shots=1) result = algo.run(quantum_instance) self.assertAlmostEqual(result['energy'], -1.85727503, places=6)
def test_vqe_caching_direct(self, batch_mode): backend = get_aer_backend('statevector_simulator') num_qubits = self.algo_input.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, 3, initial_state=init_state) optimizer = L_BFGS_B() algo = VQE(self.algo_input.qubit_op, var_form, optimizer, 'matrix', batch_mode=batch_mode) circuit_cache = CircuitCache(skip_qobj_deepcopy=True) quantum_instance_caching = QuantumInstance(backend, circuit_cache=circuit_cache, skip_qobj_validation=True) result_caching = algo.run(quantum_instance_caching) self.assertLessEqual(circuit_cache.misses, 1) self.assertAlmostEqual( self.reference_vqe_result['statevector_simulator']['energy'], result_caching['energy'])
def test_vqe_qasm_snapshot_mode(self, var_form_type): """ VQE Aer qasm_simulator snapshot mode 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 backend = Aer.get_backend('qasm_simulator') num_qubits = self.qubit_op.num_qubits init_state = Zero(num_qubits) var_form = RY(num_qubits, depth=3, initial_state=init_state) if var_form_type is QuantumCircuit: params = ParameterVector('θ', var_form.num_parameters) var_form = var_form.construct_circuit(params) optimizer = L_BFGS_B() algo = VQE(self.qubit_op, var_form, optimizer, max_evals_grouped=1) quantum_instance = QuantumInstance(backend, shots=1, seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed) result = algo.run(quantum_instance) self.assertAlmostEqual(result.eigenvalue.real, -1.85727503, places=6)
"real": 0.18093119978423156 }, "label": "XX" }] } qubit_op = WeightedPauliOperator.from_dict(pauli_dict) num_qubits = qubit_op.num_qubits print('Number of qubits: {}'.format(num_qubits)) # ### Picking Quantum Circuit to Represent Wavefunction # We will be discussing details on these waveforms tomorrow # In[3]: init_state = Zero(num_qubits) var_form = RY(num_qubits, initial_state=init_state) # # Using Simulator Backend # In[4]: backend = BasicAer.get_backend('statevector_simulator') # ## Import Different Optimizers and Compare # In[10]: from qiskit.aqua.components.optimizers import COBYLA, L_BFGS_B, SLSQP, SPSA import numpy as np from qiskit.aqua import QuantumInstance, aqua_globals
def test_qubits_5_circuit(self): self.zero = Zero(5) cct = self.zero.construct_circuit('circuit') self.assertEqual(cct.qasm(), 'OPENQASM 2.0;\ninclude "qelib1.inc";\nqreg q[5];\n')
warnings.simplefilter("ignore") backend = Aer.get_backend('statevector_simulator') qi = QuantumInstance(backend) pool_info = {'names': [], 'exp vals': []} evals = 0 num_qubits = 4 pool = PauliPool.from_all_pauli_strings( num_qubits) #all possible pauli strings q = QuantumRegister(num_qubits, name='q') circ = Zero(num_qubits).construct_circuit('circuit', q) for op in pool.pool: pool_info['names'].append(op.print_details()) pool_info['exp vals'], evals = multi_circuit_eval(circ, pool.pool, qi, True) for i in range(0, (len(pool_info['exp vals']))): pool_info['exp vals'][i] = complex(pool_info['exp vals'][i][0]) print('evals', evals) out_file = open("Pauli_values.csv", "w+") pool_info_df = pd.DataFrame(pool_info) pool_info_df.to_csv('Pauli_values.csv')
class ADAPTVQE(QuantumAlgorithm): CONFIGURATION = { 'name': 'ADAPTVQE', 'description': 'ADAPT-VQE Algorithm', } def __init__( self, operator_pool: OperatorPool, initial_state: Union[InitialState, None], vqe_optimizer: Optimizer, hamiltonian: BaseOperator, max_iters: int = 10, grad_tol: float = 1e-3, max_evals_grouped=1, aux_operators=None, auto_conversion=True, use_zero_initial_parameters=False ): super().__init__() self.operator_pool = copy.deepcopy(operator_pool) if initial_state is None: self.initial_state = Zero(num_qubits=operator_pool.num_qubits) else: self.initial_state = initial_state self.vqe_optimizer = vqe_optimizer self.hamiltonian = hamiltonian self.max_iters = max_iters self.grad_tol = grad_tol self.max_evals_grouped = max_evals_grouped self.aux_operators = aux_operators self.auto_conversion = auto_conversion self.use_zero_initial_parameters = use_zero_initial_parameters self.parameters_per_step = 1 self._coms = None self.first_step = False self._current_max_grad = None self._optimal_circuit = None self._ret = {} self.adapt_step_history = { 'gradient_list': [], # updated in _compute_gradients 'max_gradient': [], # updated in _ansatz_operator_list 'optimal_parameters': [], # updated in _run 'circuit': [], # updated in _run 'operators': [], # updated in _ansatz_operator_list 'vqe_ret': [], # updated in _run 'energy_history': [], # updated in _run 'Total Eval Time': 0, #added by WillB 'Total num evals': 0 #added by WillB } @property def _new_param(self): if self.use_zero_initial_parameters: if self.first_step: return [0.0] return [0.0 for i in range(self.parameters_per_step)] else: if self.first_step: return [np.random.uniform(-np.pi, +np.pi)] return [np.random.uniform(-np.pi, +np.pi) for i in range(self.parameters_per_step)] def _run(self) -> dict: start_time = time.time() #Added by WillB logger.info('Starting ADAPT step {} of maximum {}'.format(1, self.max_iters)) circuit = self.initial_state.construct_circuit(mode='circuit') params = self._new_param op_list = self._ansatz_operator_list(current_circuit=circuit, current_ops=[]) vqe = self._vqe_run(operator_list=op_list, initial_parameters=params) self.adapt_step_history['optimal_parameters'].append(vqe['optimal_params']) self.adapt_step_history['circuit'].append(vqe['optimal_circuit']) self.adapt_step_history['vqe_ret'].append(vqe['_ret']) self.adapt_step_history['Total num evals'] += vqe['_ret']['num_optimizer_evals'] #added by WillB self.adapt_step_history['energy_history'].append(vqe['_ret']['energy']) logger.info('Finished ADAPT step {} of maximum {} with energy {}'.format(1, self.max_iters, vqe['_ret']['energy'])) iters = 1 print(iters) while iters <= self.max_iters: #and self._current_max_grad > self.grad_tol: #removed by WillB logger.info('Starting ADAPT step {} of maximum {}'.format(iters, self.max_iters)) circuit = vqe['optimal_circuit'] params = np.concatenate((vqe['optimal_params'], self._new_param)) op_list = self._ansatz_operator_list(current_circuit=circuit, current_ops=op_list) #if self._current_max_grad < self.grad_tol: #removed by willB # break vqe = self._vqe_run(operator_list=op_list, initial_parameters=params) self.adapt_step_history['optimal_parameters'].append(vqe['optimal_params']) self.adapt_step_history['circuit'].append(vqe['optimal_circuit']) self.adapt_step_history['vqe_ret'].append(vqe['_ret']) self.adapt_step_history['Total num evals'] += vqe['_ret']['num_optimizer_evals'] #added by WillB self.adapt_step_history['energy_history'].append(vqe['_ret']['energy']) logger.info( 'Finished ADAPT step {} of maximum {} with energy {}'.format(iters, self.max_iters, vqe['_ret']['energy'])) iters += 1 print(iters) logger.info('Finished final ADAPT step {} of maximum {}, with final energy {}'.format( iters, self.max_iters, vqe['_ret']['energy'] )) logger.info('Final gradient is {} where tolerance is {}'.format( self._current_max_grad, self.grad_tol )) self._optimal_circuit = circuit self._ret = vqe['_ret'] del self.adapt_step_history['vqe_ret'] #added by WillB stop_time = time.time() - start_time #added by WillB self.adapt_step_history['Total Eval Time'] = stop_time #added by WillB return self.adapt_step_history def _compute_gradients(self, circuit: QuantumCircuit) -> List[Tuple[complex, complex]]: kwargs = {'statevector_mode': self.quantum_instance.is_statevector} logger.info('Constructing evaluation circuits...') total_evaluation_circuits = list(parallel_map( _circ_eval, self.commutators, task_kwargs={**kwargs, 'wave_function': circuit}, num_processes=aqua_globals.num_processes )) total_evaluation_circuits = [item for sublist in total_evaluation_circuits for item in sublist] logger.info('Removing duplicate circuits') final_circs = [] for circ in total_evaluation_circuits: if not fast_circuit_inclusion(circ, final_circs): final_circs.append(circ) logger.info('Finished removing duplicate circuits') logger.debug('Executing {} circuits for gradient evaluation...'.format(len(final_circs))) result = self.quantum_instance.execute(final_circs) logger.debug('Computing {} gradients...'.format(len(self.commutators))) grads = list(parallel_map( _compute_grad, self.commutators, task_kwargs={**kwargs, 'result': result}, num_processes=aqua_globals.num_processes )) self.adapt_step_history['Total num evals'] += len(final_circs) logger.debug('Computed gradients: {}'.format(grads)) return [abs(tup[0]) for tup in grads] @property def commutators(self) -> List[BaseOperator]: if self._coms is not None: return self._coms logger.info('Computing commutators...') self._coms = list(parallel_map( _commutator, self.operator_pool.pool, task_kwargs={'hamiltonian': self.hamiltonian, 'gradient_tolerance': self.grad_tol}, num_processes=aqua_globals.num_processes )) # type: List[BaseOperator] logger.info('Computed {} commutators'.format(len(self._coms))) if all(isinstance(op, WeightedPauliOperator) for op in self._coms): new_coms = [] new_pool = [] for com, op in zip(self._coms, self.operator_pool.pool): if len(com.paulis) > 0: new_coms.append(com) new_pool.append(op) self._coms = new_coms self.operator_pool._pool = new_pool logger.info('Dropped commuting terms, new pool has size {}'.format(len(self._coms))) else: logger.info( 'Dropping commuting terms currently only supported for WeightedPauliOperator class') if len(self._coms) == 0: raise ValueError('List of commutators is empty.') return self._coms def _ansatz_operator_list(self, current_circuit: QuantumCircuit, current_ops: List[BaseOperator]) -> List[BaseOperator]: grads = self._compute_gradients(circuit=current_circuit) self._current_max_grad = np.max(grads) self.adapt_step_history['max_gradient'].append(self._current_max_grad) new_op = self.operator_pool.pool[np.argmax(grads)] # type: BaseOperator logger.info('New operator with gradient {} added to ansatz: {}'.format( self._current_max_grad, str(new_op) )) self.adapt_step_history['operators'].append(new_op.print_details()) return current_ops + [new_op] def _vqe_run(self, operator_list: List[BaseOperator], initial_parameters: np.ndarray, **kwargs) -> dict: self._current_operator_list = operator_list self._current_initial_parameters = initial_parameters var_form = self.variational_form() vqe = VQE( operator=self.hamiltonian, var_form=var_form, optimizer=self.vqe_optimizer, initial_point=initial_parameters, max_evals_grouped=self.max_evals_grouped, aux_operators=self.aux_operators, callback=None, auto_conversion=self.auto_conversion ) vqe_result = vqe.run(self.quantum_instance, **kwargs) # == vqe._ret return { 'optimal_circuit': vqe.get_optimal_circuit(), 'optimal_params': vqe.optimal_params, '_ret': vqe_result } def variational_form(self): return ADAPTVariationalForm( operator_pool=self._current_operator_list, bounds=[(-np.pi, +np.pi)] * len(self._current_operator_list), initial_state=self.initial_state ) def get_optimal_circuit(self): if self._optimal_circuit is None: raise AquaError( "Cannot find optimal circuit before running the algorithm to find optimal params.") return self._optimal_circuit
cvqe_dict = {'2': [], '3': [], '4': [], '5': [], '6': [], '7': [], '8': [], '9': [], '10': []} vqe_dict = {'2': [], '3': [], '4': [], '5': [], '6': [], '7': [], '8': [], '9': [], '10': []} exact_dict = {'2': [], '3': [], '4': [], '5': [], '6': [], '7': [], '8': [], '9': [], '10': []} num_qubits = 4 #test = random_diagonal_hermitian(2) #print(test.print_details()) #mat = to_matrix_operator(test) #print(mat.print_details()) for i in range(0,1): k = 0 runtime_sum = 0 exact_time_sum = 0 vqeruntime_sum = 0 print('num_qubits', num_qubits) while k < runs: initial_state = Zero(num_qubits) op_list = [] wop = 0*WeightedPauliOperator.from_list(paulis=[Pauli.from_label('I'*num_qubits)], weights=[1.0]) #mat = np.random.uniform(0, 1, size=(2**num_qubits, 2**num_qubits)) + 1j * np.random.uniform(0, 1, size=(2**num_qubits, 2**num_qubits)) #mat = np.conjugate(np.transpose(mat)) + mat #ham = to_weighted_pauli_operator(MatrixOperator(mat)) #creates random hamiltonian from random matrix "mat" ham = get_h_4_hamiltonian(0.25, 2, "jw") #ham = retrieve_ham(0, num_qubits = num_qubits) print('old_ham', ham.print_details()) #ham = get_h_4_hamiltonian(0.5,2,'jw') #op_list = retrieve_op_list(0, rev = True, num_qubits = num_qubits) #for op in op_list: # print(op.print_details()) op_list = [WeightedPauliOperator.from_list([Pauli.from_label('IIXX')]), WeightedPauliOperator.from_list([Pauli.from_label('XXXY')])] #op_list = [WeightedPauliOperator.from_list([Pauli.from_label('YYZZ')],[1.0]),
class ADAPTVQEROTO(ADAPTVQE): def __init__( self, operator_pool, initial_state, vqe_optimizer, hamiltonian, max_iters, energy_step_tol= 1e-8, auto_conversion=True, use_zero_initial_parameters=False, postprocessing = False, include_parameter = True ): #most of these params no longer matter, should edit to remove necessity self._quantum_instance = None super().__init__(operator_pool, initial_state, vqe_optimizer, hamiltonian, max_iters, #mximum number of iterations grad_tol = 1e-3, #stopping criteria if we were using gradient tolerance (we're not) max_evals_grouped=1,#unsure what this means aux_operators=None, #additional operators in pool auto_conversion=True, #when using VQE algorithm auto converts operators to best representaiton for backend use_zero_initial_parameters=False #Make your parameters start at zero before gradient based optimization ) #initialization from ADAPTVQE self.energy_step_tol = energy_step_tol #the stopping criteria for energy step self.hamiltonian = hamiltonian self.postprocessing = postprocessing self.include_parameter = include_parameter if initial_state is None: #creates new initial state if none passed self.initial_state = Zero(num_qubits=operator_pool.num_qubits) #Custom(hamiltonian.num_qubits, state='uniform') else: self.initial_state = initial_state #clean up old dictionary del self.adapt_step_history['gradient_list'] del self.adapt_step_history['max_gradient'] #del self.adapt_step_history['vqe_ret'] #self.adapt_step_history.update({'Total Eval Time': 0}) #self.adapt_step_history.update({'Total num Evals': 0}) self.adapt_step_history.update({'Total number energy iterations': 0}) self.adapt_step_history.update({'Max Energy Step': 0}) def find_optim_param_energy(self, preferred_op = None, preferred_op_mode = False, previous_circuit = None) -> dict: """method: find_optim_param_energy finds the optimum operator+parameter pair for the next iteration of the ansatz args: preferred_op - an operator (weightedpaulioperator) predetermined to be the next operator in the ansatz (essentially converts this method to rotosolve instead of rotoselect) preferred_op_mode - a flag (boolean) to choose whether or not preferred op should be used returns: dictionary with: optimal operator, name of optimal operator (for output purposes), optimal parameter, optimal energy, A, B, and C for Asin(theta + B) + C """ A = np.empty(0) C = np.empty(0) final_circs = [] E_list = [] #measure energies (theta = 0, theta = pi/4, theta = -pi/4) if(self.adapt_step_history['Total number energy iterations'] == 0): wavefunc = self.initial_state.construct_circuit() Energy_0_circ = self.hamiltonian.construct_evaluation_circuit(wavefunc, True) result = self.quantum_instance.execute(Energy_0_circ) Energy_0 = np.real(self.hamiltonian.evaluate_with_result(result, True)[0]) self.adapt_step_history['Total num evals'] += 1 else: op_list = self._current_operator_list bounds=[(-np.pi, +np.pi)]*len(op_list) vf = ADAPTVariationalForm(op_list, bounds, self.initial_state) wavefunc = vf.construct_circuit(self.adapt_step_history['optimal_parameters'][-1]) Energy_0 = self.adapt_step_history['energy_history'][-1] if preferred_op_mode: pool = preferred_op else: pool = self.operator_pool.pool args = [] kwargs = {'ham': self.hamiltonian, 'energy_step_tol': self.energy_step_tol, 'parameter': np.pi/4} op_list_pi4 = list(parallel_map( Generate_op, pool, args, kwargs )) kwargs['parameter'] = -np.pi/4 op_list_negpi4 = list(parallel_map( Generate_op, self.operator_pool.pool, args, kwargs )) op_list = op_list_pi4 + op_list_negpi4 kwargs = {'statevector_mode': self.quantum_instance.is_statevector} total_evaluation_circuits = list(parallel_map( _circ_eval, op_list, task_kwargs={**kwargs, 'wave_function': wavefunc}, num_processes=aqua_globals.num_processes )) total_evaluation_circuits = [item for sublist in total_evaluation_circuits for item in sublist] logger.info('Removing duplicate circuits') for circ in total_evaluation_circuits: if not fast_circuit_inclusion(circ, final_circs): final_circs.append(circ) result = self.quantum_instance.execute(final_circs) Energies = list(parallel_map( _compute_energy, op_list, task_kwargs={**kwargs, 'result': result}, num_processes=aqua_globals.num_processes )) for entry in Energies: E_list.append(np.real(entry[0])) cutoff = int(len(E_list)/2) Energy_pi4 = np.array(E_list[0:cutoff]) Energy_negpi4 = np.array(E_list[cutoff:]) #calculate minimum energy + A,B, and C from measured energies B = np.arctan2(( -Energy_negpi4 - Energy_pi4 + 2*Energy_0),(Energy_pi4 - Energy_negpi4)) Optim_param_array = (-B - np.pi/2)/2 X = np.sin(B) Y = np.sin(B + np.pi/2) Z = np.sin(B - np.pi/2) for i in range(0,(len(Energy_negpi4)-1)): if Y[i] != 0: C = np.append(C, (Energy_0-Energy_pi4[i]*(X[i]/Y[i]))/(1-X[i]/Y[i])) A = np.append(A, (Energy_pi4[i] - C[-1])/Y[i]) else: C = np.append(C, Energy_pi4[i]) A = np.append(A, (Energy_0 - C[-1])/X[i]) Optim_energy_array = C - A #find minimum energy index Optim_param_pos = np.argmin(Optim_energy_array) min_energy = Optim_energy_array[Optim_param_pos] Optim_param = Optim_param_array[Optim_param_pos] #CPU has limit on smallest number to be calculated - looks like its somewhere around 1e-16 #manually set this to zero as it should be zero. if min_energy > Energy_0 and abs(Optim_param) < 2e-16: Optim_param = 0 min_energy = Energy_0 #find optimum operator Optim_operator = self.operator_pool.pool[Optim_param_pos] Optim_operator_name = self.operator_pool.pool[Optim_param_pos].print_details() #keep track of number of quantum evaluations self.adapt_step_history['Total num evals'] += len(final_circs) return {'Newly Minimized Energy': min_energy, 'Next Parameter value': Optim_param, 'Next Operator identity': Optim_operator, 'Next Operator Name': Optim_operator_name, 'A': A[Optim_param_pos], 'B': B[Optim_param_pos], 'C': C[Optim_param_pos]} def recent_energy_step(self): return abs(self.adapt_step_history['energy_history'][-1] - self.adapt_step_history['energy_history'][-2]) #Our new run function, this will take time to edit def run(self, quantum_instance) -> dict: #we'll keep this structure of returning a dictionary, though maybe I'll return the full changelog, start = time.time() self._current_operator_list = [] self._quantum_instance = quantum_instance while self.adapt_step_history['Total number energy iterations'] <= 1: logger.info('Starting ADAPTROTO step {} of maximum {}'.format(self.adapt_step_history['Total number energy iterations'], self.max_iters)) New_minimizing_data = self.find_optim_param_energy() if self.adapt_step_history['Total number energy iterations'] > 1: #and New_minimizing_data['Newly Minimized Energy'] > self.adapt_step_history['energy_history'][-1]: break self._current_operator_list.append(New_minimizing_data['Next Operator identity']) if self.include_parameter == True: new_parameter = float(New_minimizing_data['Next Parameter value']) else: new_parameter = 0 if self.adapt_step_history['Total number energy iterations'] == 0: self.adapt_step_history['optimal_parameters'].append([new_parameter]) else: new_list = self.adapt_step_history['optimal_parameters'][-1] + [new_parameter] self.adapt_step_history['optimal_parameters'].append(new_list) self.adapt_step_history['operators'].append(New_minimizing_data['Next Operator Name']) if self.postprocessing: vqe_rotosolve_result = self._vqe_run(self._current_operator_list,np.array(self.adapt_step_history['optimal_parameters'][-1])) self.adapt_step_history['optimal_parameters'].append(list(vqe_rotosolve_result['optimal_params'])) self.adapt_step_history['energy_history'].append(vqe_rotosolve_result['_ret']['energy']) self.adapt_step_history['Total num evals'] += vqe_rotosolve_result['_ret']['num_optimizer_evals'] else: self.adapt_step_history['energy_history'].append(New_minimizing_data['Newly Minimized Energy']) logger.info('Finished ADAPTROTO step {} of maximum {} with energy {}'.format(self.adapt_step_history['Total number energy iterations'], self.max_iters, self.adapt_step_history['energy_history'][-1])) self.adapt_step_history['Total number energy iterations'] += 1 print(self.adapt_step_history['Total number energy iterations']) if self.recent_energy_step() > self.adapt_step_history['Max Energy Step']: self.adapt_step_history['Max Energy Step'] = self.recent_energy_step() while self.adapt_step_history['Total number energy iterations'] <= self.max_iters: #and self.recent_energy_step() >= self.energy_step_tol: logger.info('Starting ADAPTROTO step {} of maximum {}'.format(self.adapt_step_history['Total number energy iterations'], self.max_iters)) New_minimizing_data = self.find_optim_param_energy() #if New_minimizing_data['Newly Minimized Energy'] > self.adapt_step_history['energy_history'][-1]: # break self._current_operator_list.append(New_minimizing_data['Next Operator identity']) if self.include_parameter == True: new_parameter = float(New_minimizing_data['Next Parameter value']) else: new_parameter = 0 self.adapt_step_history['optimal_parameters'].append(self.adapt_step_history['optimal_parameters'][-1] + [new_parameter]) self.adapt_step_history['operators'].append(New_minimizing_data['Next Operator Name']) if self.postprocessing: vqe_rotosolve_result = self._vqe_run(self._current_operator_list, np.array(self.adapt_step_history['optimal_parameters'][-1])) self.adapt_step_history['optimal_parameters'].append(list(vqe_rotosolve_result['optimal_params'])) self.adapt_step_history['energy_history'].append(vqe_rotosolve_result['_ret']['energy']) self.adapt_step_history['Total num evals'] += vqe_rotosolve_result['_ret']['num_optimizer_evals'] else: self.adapt_step_history['energy_history'].append(New_minimizing_data['Newly Minimized Energy']) logger.info('Finished ADAPTROTO step {} of maximum {} with energy {}'.format(self.adapt_step_history['Total number energy iterations'], self.max_iters, self.adapt_step_history['energy_history'][-1])) self.adapt_step_history['Total number energy iterations'] += 1 print(self.adapt_step_history['Total number energy iterations']) if self.recent_energy_step() > self.adapt_step_history['Max Energy Step']: self.adapt_step_history['Max Energy Step'] = self.recent_energy_step() logger.info('Final energy step is {} where tolerance is {}'.format( self.recent_energy_step(), self.energy_step_tol )) eval_time = time.time() - start self.adapt_step_history['Total Eval Time'] = eval_time return self.adapt_step_history #return final minimized energy list
def __init__(self, operator_pool: OperatorPool, initial_state: Union[InitialState, None], vqe_optimizer: Optimizer, hamiltonian: BaseOperator, max_iters: int = 10, grad_tol: float = 1e-3, max_evals_grouped=1, aux_operators=None, auto_conversion=True, use_zero_initial_parameters: Union[bool, float] = True, callback=None, step_callbacks=[], drop_duplicate_circuits=True, return_best_result: bool = False, parameter_tolerance=None, compute_hessian: bool = False, operator_selector: OperatorSelector = None): super().__init__(return_best_result) self.operator_pool = deepcopy(operator_pool) if initial_state is None: self.initial_state = Zero(num_qubits=operator_pool.num_qubits) else: self.initial_state = initial_state self.vqe_optimizer = vqe_optimizer self.hamiltonian = hamiltonian self.max_iters = max_iters self.grad_tol = grad_tol self.max_evals_grouped = max_evals_grouped self.aux_operators = aux_operators self.auto_conversion = auto_conversion self._compute_hessian = compute_hessian self._drop_duplicate_circuits = drop_duplicate_circuits self.callback = callback self.step_callbacks = step_callbacks if operator_selector is None: self._operator_selector = ADAPTOperatorSelector( self.hamiltonian, operator_pool=self.operator_pool, drop_duplicate_circuits=self._drop_duplicate_circuits) else: self._operator_selector = operator_selector if type(use_zero_initial_parameters) is bool: self.use_zero_initial_parameters = use_zero_initial_parameters self.__new_par = 0.0 elif type(use_zero_initial_parameters) is float: self.use_zero_initial_parameters = True self.__new_par = use_zero_initial_parameters else: raise ValueError( 'Invalid option for new parameters supplied: {}'.format( use_zero_initial_parameters)) self.parameters_per_step = 1 self._coms = None self._dcoms = None self._parameter_tolerance = parameter_tolerance if len(self.step_callbacks) == 0: self.step_callbacks.append(MaxGradientStopper(self.grad_tol))
def __init__(self, operator_pool: OperatorPool, initial_state: Union[InitialState, None], vqe_optimizer: Optimizer, hamiltonian: BaseOperator, max_iters: int = 10, energy_tol: float = 1e-3, max_evals_grouped=1, aux_operators=None, auto_conversion=True, initial_parameters: Union[int, float] = 0, callback=None, step_callbacks=[], drop_duplicate_circuits=True, return_best_result: bool = False, parameter_tolerance=None, compute_hessian: bool = False, operator_selector: OperatorSelector = None, parameters_per_step: int = 1): super().__init__(return_best_result) self.operator_pool = deepcopy(operator_pool) if initial_state is None: self.initial_state = Zero(num_qubits=operator_pool.num_qubits) else: self.initial_state = initial_state self.vqe_optimizer = vqe_optimizer self.hamiltonian = hamiltonian self.max_iters = max_iters self.energy_tol = energy_tol self.max_evals_grouped = max_evals_grouped self.aux_operators = aux_operators self.auto_conversion = auto_conversion self._compute_hessian = compute_hessian self._drop_duplicate_circuits = drop_duplicate_circuits self.callback = callback self.step_callbacks = step_callbacks self.ham_list = split_into_paulis(self.hamiltonian) if operator_selector is None: #need to change, should be roto self._operator_selector = Ha_max_OperatorSelector( self.hamiltonian, operator_pool=self.operator_pool, drop_duplicate_circuits=self._drop_duplicate_circuits, ) else: self._operator_selector = operator_selector self._parameter_tolerance = parameter_tolerance if initial_parameters == 0: self.initial_parameters = 0 self.__new_par = 0.0 elif initial_parameters == 1: self.initial_parameters = 1 self.__new_par = 0.0 elif initial_parameters == 2: self.initial_parameters = 2 else: raise ValueError( 'Invalid option for new parameters supplied: {}'.format( initial_parameters))
def test_qubits_2_vector(self): """ Qubits 2 vector test """ zero = Zero(2) cct = zero.construct_circuit('vector') np.testing.assert_array_equal(cct, [1.0, 0.0, 0.0, 0.0])