def reconstruct_multi_energy_expression(self, operator, op_list = None, tree = None): """ returns: ham_list: list of nonzero weighted pauli operators. is (typically) an exponentially (with ansatz length) sized list of separate terms. When measured and multiplied by sines and cosines, it can be used to evaluate the energy nonzero_term list: used to keep track of when terms in the ham_list correspond to which term in the overall energy expression, as empty or zero terms are not included in the ham_list. """ #can we take nonzero terms to tree list? ham = split_into_paulis(operator) term_list = [[ham, 1]] for num, op in enumerate(op_list): args = [op, num, self.zero_term] meta_term_list = parallel_map(create_new_term_list, term_list, args) new_term_list = [] for term in meta_term_list: new_term_list = new_term_list + term if tree is not None: for term in new_term_list: i = 0 if term[1] == 3*(term_list[i] - 1) + 1: tree[num + 1].append(0) i = i + 1 if term[1] == 3*(term_list[i] - 1) + 2: tree[num + 1] = tree[num + 1] + [1,2] i = i+2 if tree is not None: ham_list = parallel_map(return_first_entry, ham_list) return ham_list, tree else: return ham_list, nonzero_terms
def get_next_op_param(self, result): """ method: get_energy_param_lists args: result- the data for the recently calculated result returns: dict with number of energy evaluations required, array of optimized energies for each operator in pool, array of optimized parameters for the energy values in energy array """ if self.parameters_per_step == 1: args = tuple() kwargs = {'hp': self.ham_list, 'he': result['expec list']} Ha_list = list(parallel_map(get_Ha, self._operator_pool.pool, task_kwargs = kwargs, num_processes = len(psutil.Process().cpu_affinity()))) Hc_list = list(parallel_map(get_Hc, self._operator_pool.pool, task_kwargs = kwargs, num_processes = len(psutil.Process().cpu_affinity()))) grads, evals = multi_circuit_eval( result['current_circuit'], self.commutators, qi=self.quantum_instance, drop_dups=self._drop_duplicate_circuits ) #ziplist = list(zip(Hc_list, Ha_list, grads)) ziplist = list(zip(Hc_list, Ha_list, grads)) energy_array = list(parallel_map(get_optimal_array, ziplist, num_processes = len(psutil.Process().cpu_affinity()))) optimal_energy_index = np.argmin(energy_array) #optimal_energy_index = np.where(np.array(energy_array) == np.array(energy_array).min()) #optimal_energy_index = optimal_energy_index[0] #print(optimal_energy_index) #if len(optimal_energy_index) > 1: # entry = np.random.randint(0,len(optimal_energy_index) - 1) # optimal_energy_index = optimal_energy_index[entry] #else: # optimal_energy_index = optimal_energy_index[0] optimal_op = self._operator_pool.pool[optimal_energy_index] optimal_param = -np.arctan2(np.real(Ha_list[optimal_energy_index]),2*np.real(grads[optimal_energy_index][0])) return evals, optimal_op, optimal_param
def mapping(self, map_type, threshold=0.00000001, idx=[None] * 4): self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError( 'Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') pauli_list = WeightedPauliOperator(paulis=[]) for m, h in enumerate(self._hs): if (h is not None): if (idx[m] is None): results = parallel_map( FermionicOperatorNBody._n_body_mapping, [ FermionicOperatorNBody._prep_mapping( h[indexes], a_list, indexes) for indexes in list( itertools.product(range(n), repeat=len(h.shape))) if h[indexes] != 0 ], num_processes=aqua_globals.num_processes) else: results = parallel_map( FermionicOperatorNBody._n_body_mapping, [ FermionicOperatorNBody._prep_mapping( h[indexes], a_list, indexes) for indexes in idx[m] if np.abs(h[indexes]) > threshold ], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_term = [ self._ph_trans_shift, Pauli.from_label('I' * self._modes) ] pauli_list += WeightedPauliOperator(paulis=[pauli_term]) return pauli_list
def calculateEnergy(self, transpiledCircuit): if self.useNoiseModel == True: p_reset = 0.003 p_meas = 0.01 p_gate1 = 0.05 # QuantumError objects error_reset = pauli_error([('X', p_reset), ('I', 1 - p_reset)]) error_meas = pauli_error([('X', p_meas), ('I', 1 - p_meas)]) error_gate1 = pauli_error([('X', p_gate1), ('I', 1 - p_gate1)]) error_gate2 = error_gate1.tensor(error_gate1) noise_bit_flip = NoiseModel() noise_bit_flip.add_all_qubit_quantum_error(error_reset, "reset") noise_bit_flip.add_all_qubit_quantum_error(error_meas, "measure") noise_bit_flip.add_all_qubit_quantum_error(error_gate1, ["u1", "u2", "u3"]) noise_bit_flip.add_all_qubit_quantum_error(error_gate2, ["cx"]) simulator = QasmSimulator() job = execute(transpiledCircuit, backend=simulator, basis_gates=noise_bit_flip.basis_gates, noise_model=noise_bit_flip) results = job.result() counts = results.get_counts() _paulis, sgift = get_pauliList(self.ising, self.qubits) _basis = [(pauli[1], [i]) for i, pauli in enumerate(_paulis)] num_shots = sum(list(results.get_counts().values())) results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var, [([_paulis[idx] for idx in indices], results.get_counts()) for basis, indices in _basis], num_processes=aqua_globals.num_processes) return results[0][0] else: _paulis, sgift = get_pauliList(self.ising, self.qubits) _basis = [(pauli[1], [i]) for i, pauli in enumerate(_paulis)] job = execute(transpiledCircuit, backend=self.backend) results = job.result() counts = results.get_counts() num_shots = sum(list(results.get_counts().values())) results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var, [([_paulis[idx] for idx in indices], results.get_counts()) for basis, indices in _basis], num_processes=aqua_globals.num_processes) return results[0][0]
def multi_circuit_eval(circuit: QuantumCircuit, op_list: List[BaseOperator], qi: QuantumInstance, drop_dups: bool = True): num_processes = 8 kwargs = {'statevector_mode': qi.is_statevector} logger.info('Constructing evaluation circuits...') start = time.time() print('about to get eval circs') total_evaluation_circuits = list( parallel_map(_circ_eval, op_list, task_kwargs={ **kwargs, 'wave_function': circuit }, num_processes=num_processes)) total_evaluation_circuits = [ item for sublist in total_evaluation_circuits for item in sublist ] logger.info('Removing duplicate circuits') start = time.time() print('about to drop dups') if drop_dups: 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') else: final_circs = deepcopy(total_evaluation_circuits) del total_evaluation_circuits evals = len(final_circs) #will added logger.debug('Executing {} circuits for evaluation...'.format( len(final_circs))) start = time.time() #print('about to execute multi circuit evals') result = qi.execute(final_circs) #print('finished executing multi circuit evals') logger.debug('Computing {} expectations...'.format(len(op_list))) start = time.time() print('about to compute expecs') exp_vals = list( parallel_map(_compute_grad, op_list, task_kwargs={ **kwargs, 'result': result }, num_processes=num_processes)) logger.debug('Computed expectations: {}'.format(exp_vals)) return exp_vals, evals #will added
def construct_circuits(data_to_predict, training_data) -> qk.QuantumCircuit: """Constructs all quantum circuits for each datum to classify. Args: data_to_predict (array): data points, 2-D array, of shape ``(N, D)``, where ``N`` is the number of data points and ``D`` is the dimensionality of the vector. ``D`` should coincide with the provided training data. training_data (array): data points which you want to know the distance of between :py:attr:`data_to_predict`. Returns: numpy.ndarray: The constructed circuits. Raises: AquaError: Quantum instance is not present. """ measurement = True # can be adjusted if statevector_sim oracle = qc.create_oracle(training_data) # parallel_map() creates QuantumCircuits in parallel to be executed by # a QuantumInstance logger.info("Starting parallel map for constructing circuits.") circuits = qktools.parallel_map( QKNeighborsClassifier.construct_circuit, data_to_predict, task_args=[oracle, measurement]) logger.info("Done.") return circuits
def _build_one_sector(available_hopping_ops, untapered_op, z2_symmetries): to_be_computed_list = [] for idx, _ in enumerate(mus): m_u = mus[idx] n_u = nus[idx] left_op = available_hopping_ops.get('E_{}'.format(m_u)) right_op_1 = available_hopping_ops.get('E_{}'.format(n_u)) right_op_2 = available_hopping_ops.get('Edag_{}'.format(n_u)) to_be_computed_list.append( (m_u, n_u, left_op, right_op_1, right_op_2)) if logger.isEnabledFor(logging.INFO): logger.info("Building all commutators:") TextProgressBar(sys.stderr) results = parallel_map( self._build_commutator_routine, to_be_computed_list, task_args=(untapered_op, z2_symmetries), num_processes=algorithm_globals.num_processes) for result in results: m_u, n_u, q_mat_op, w_mat_op, m_mat_op, v_mat_op = result if q_mat_op is not None: all_matrix_operators['q_{}_{}'.format(m_u, n_u)] = q_mat_op if w_mat_op is not None: all_matrix_operators['w_{}_{}'.format(m_u, n_u)] = w_mat_op if m_mat_op is not None: all_matrix_operators['m_{}_{}'.format(m_u, n_u)] = m_mat_op if v_mat_op is not None: all_matrix_operators['v_{}_{}'.format(m_u, n_u)] = v_mat_op
def _build_hopping_operators(self): if logger.isEnabledFor(logging.DEBUG): TextProgressBar(sys.stderr) results = parallel_map( UCCSD._build_hopping_operator, self._single_excitations + self._double_excitations, task_args=(self._num_orbitals, self._num_particles, self._qubit_mapping, self._two_qubit_reduction, self._z2_symmetries, self._skip_commute_test), num_processes=aqua_globals.num_processes) hopping_ops = [] s_e_list = [] d_e_list = [] for op, index in results: if op is not None and not op.is_empty(): hopping_ops.append(op) if len(index) == 2: # for double excitation s_e_list.append(index) else: # for double excitation d_e_list.append(index) self._single_excitations = s_e_list self._double_excitations = d_e_list num_parameters = len(hopping_ops) * self._depth return hopping_ops, num_parameters
def construct_circuit( self, parameters: Union[np.ndarray, List[Parameter], ParameterVector], q: Optional[QuantumRegister] = None) -> QuantumCircuit: """Construct the variational form, given its parameters. Args: parameters: circuit parameters q: Quantum Register for the circuit. Returns: Quantum Circuit a quantum circuit with given `parameters` Raises: ValueError: the number of parameters is incorrect. ValueError: if num_qubits has not been set and is still None """ if len(parameters) != self._num_parameters: raise ValueError('The number of parameters has to be {}'.format( self._num_parameters)) if self._num_qubits is None: raise ValueError( 'The number of qubits is None and must be set before the circuit ' 'can be created.') if q is None: q = QuantumRegister(self._num_qubits, name='q') if isinstance(self._initial_state, QuantumCircuit): circuit = QuantumCircuit(q) circuit.append(self._initial_state.to_gate(), range(self._initial_state.num_qubits)) elif self._initial_state is not None: circuit = self._initial_state.construct_circuit('circuit', q) else: circuit = QuantumCircuit(q) if logger.isEnabledFor( logging.DEBUG) and self._logging_construct_circuit: logger.debug("Evolving hopping operators:") TextProgressBar(sys.stderr) self._logging_construct_circuit = False num_excitations = len(self._hopping_ops) results = parallel_map( UVCC._construct_circuit_for_one_excited_operator, [(self._hopping_ops[index % num_excitations], parameters[index]) for index in range(self._reps * num_excitations)], task_args=(q, self._num_time_slices), num_processes=aqua_globals.num_processes) for qc in results: if self._shallow_circuit_concat: circuit.data += qc.data else: circuit += qc return circuit
def _build_one_sector(available_hopping_ops): to_be_computed_list = [] for idx, _ in enumerate(mus): m_u = mus[idx] n_u = nus[idx] left_op = available_hopping_ops.get( '_'.join([str(x) for x in excitations_list[m_u]]), None) right_op_1 = available_hopping_ops.get( '_'.join([str(x) for x in excitations_list[n_u]]), None) right_op_2 = available_hopping_ops.get( '_'.join([str(x) for x in reversed(excitations_list[n_u])]), None) to_be_computed_list.append((m_u, n_u, left_op, right_op_1, right_op_2)) if logger.isEnabledFor(logging.INFO): logger.info("Building all commutators:") TextProgressBar(sys.stderr) results = parallel_map(QEquationOfMotion._build_commutator_rountine, to_be_computed_list, task_args=(self._untapered_op, self._z2_symmetries)) for result in results: m_u, n_u, q_mat_op, w_mat_op, m_mat_op, v_mat_op = result q_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator( q_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \ if q_mat_op is not None else q_commutators[m_u][n_u] w_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator( w_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \ if w_mat_op is not None else w_commutators[m_u][n_u] m_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator( m_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \ if m_mat_op is not None else m_commutators[m_u][n_u] v_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator( v_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \ if v_mat_op is not None else v_commutators[m_u][n_u]
def _hessian(self, circuit: QuantumCircuit): kwargs = {'statevector_mode': self.quantum_instance.is_statevector} logger.info('Constructing evaluation circuits for Hessian...') dcoms = self.double_commutators.flatten().tolist() total_evaluation_circuits = list( parallel_map(_circ_eval, dcoms, task_kwargs={ **kwargs, 'wave_function': circuit }, num_processes=len(psutil.Process().cpu_affinity()))) total_evaluation_circuits = [ item for sublist in total_evaluation_circuits for item in sublist ] logger.info('Removing duplicate circuits') if self._drop_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') else: final_circs = total_evaluation_circuits logger.debug('Executing {} circuits for Hessian evaluation...'.format( len(final_circs))) result = self.quantum_instance.execute(final_circs) logger.debug('Computing Hessian...') n_ops = len(self._operator_pool.pool) hess = np.zeros((n_ops, n_ops)) for i, j in product(range(n_ops), repeat=2): hess[i, j], _ = self.double_commutators[i, j].evaluate_with_result( result=result, **kwargs) logger.debug('Computed Hessian') return hess
def test_binding_parameterized_circuits_built_in_multiproc(self): """Verify subcircuits built in a subprocess can still be bound.""" # ref: https://github.com/Qiskit/qiskit-terra/issues/2429 num_processes = 4 qr = QuantumRegister(3) cr = ClassicalRegister(3) circuit = QuantumCircuit(qr, cr) parameters = [Parameter('x{}'.format(i)) for i in range(num_processes)] results = parallel_map(_construct_circuit, parameters, task_args=(qr, ), num_processes=num_processes) for qc in results: circuit += qc parameter_values = [{x: 1 for x in parameters}] qobj = assemble(circuit, backend=BasicAer.get_backend('qasm_simulator'), parameter_binds=parameter_values) self.assertEqual(len(qobj.experiments), 1) self.assertEqual(len(qobj.experiments[0].instructions), 4) self.assertTrue( all( len(inst.params) == 1 and isinstance(inst.params[0], ParameterExpression) and float(inst.params[0]) == 1 for inst in qobj.experiments[0].instructions))
def evaluate_with_result(self, result, statevector_mode, use_simulator_operator_mode=False, circuit_name_prefix=''): """ This method can be only used with the circuits generated by the `construct_evaluation_circuit` method with the same `circuit_name_prefix` since the circuit names are tied to some meanings. Calculate the evaluated value with the measurement results. Args: result (qiskit.Result): the result from the backend. statevector_mode (bool): indicate which type of simulator are used. use_simulator_operator_mode (bool): if aer_provider is used, we can do faster evaluation for pauli mode on statevector simulation circuit_name_prefix (str): a prefix of circuit name Returns: float: the mean value float: the standard deviation Raises: AquaError: if Operator is empty """ if self.is_empty(): raise AquaError("Operator is empty, check the operator.") avg, std_dev, variance = 0.0, 0.0, 0.0 if statevector_mode: if use_simulator_operator_mode: temp = \ result.data( circuit_name_prefix + 'aer_mode')[ 'snapshots']['expectation_value']['test'][0]['value'] avg = temp[0] + 1j * temp[1] else: quantum_state = np.asarray(result.get_statevector(circuit_name_prefix + 'psi')) for weight, pauli in self._paulis: # all I if np.all(np.logical_not(pauli.z)) and np.all(np.logical_not(pauli.x)): avg += weight else: quantum_state_i = \ result.get_statevector(circuit_name_prefix + pauli.to_label()) avg += (weight * (np.vdot(quantum_state, quantum_state_i))) else: if logger.isEnabledFor(logging.DEBUG): logger.debug("Computing the expectation from measurement results:") TextProgressBar(sys.stderr) # pick the first result to get the total number of shots num_shots = sum(list(result.get_counts(0).values())) results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var, [([self._paulis[idx] for idx in indices], result.get_counts(circuit_name_prefix + basis.to_label())) for basis, indices in self._basis], num_processes=aqua_globals.num_processes) for res in results: avg += res[0] variance += res[1] std_dev = np.sqrt(variance / num_shots) return avg, std_dev
def build_hopping_operators(self, excitations: Union[str, List[List[int]]] = 'sd' ) -> Tuple[Dict[str, WeightedPauliOperator], Dict[str, List[bool]], Dict[str, List[Any]]]: """Builds the product of raising and lowering operators (basic excitation operators) Args: excitations: The excitations to be included in the eom pseudo-eigenvalue problem. If a string ('s', 'd' or 'sd') then all excitations of the given type will be used. Otherwise a list of custom excitations can directly be provided. Returns: A tuple containing the hopping operators, the types of commutativities and the excitation indices. """ num_alpha, num_beta = self._molecule_info['num_particles'] num_orbitals = self._molecule_info['num_orbitals'] if isinstance(excitations, str): se_list, de_list = UCCSD.compute_excitation_lists([num_alpha, num_beta], num_orbitals, excitation_type=excitations) excitations_list = se_list+de_list else: excitations_list = excitations size = len(excitations_list) # # get all to-be-processed index # mus, nus = np.triu_indices(size) # build all hopping operators hopping_operators: Dict[str, WeightedPauliOperator] = {} type_of_commutativities: Dict[str, List[bool]] = {} excitation_indices = {} to_be_executed_list = [] for idx in range(size): to_be_executed_list += [excitations_list[idx], list(reversed(excitations_list[idx]))] hopping_operators['E_{}'.format(idx)] = None hopping_operators['Edag_{}'.format(idx)] = None type_of_commutativities['E_{}'.format(idx)] = None type_of_commutativities['Edag_{}'.format(idx)] = None excitation_indices['E_{}'.format(idx)] = excitations_list[idx] excitation_indices['Edag_{}'.format(idx)] = list(reversed(excitations_list[idx])) result = parallel_map(self._build_single_hopping_operator, to_be_executed_list, task_args=(num_alpha + num_beta, num_orbitals, self._qubit_mapping, self._two_qubit_reduction, self._molecule_info['z2_symmetries']), num_processes=aqua_globals.num_processes) for key, res in zip(hopping_operators.keys(), result): hopping_operators[key] = res[0] type_of_commutativities[key] = res[1] return hopping_operators, type_of_commutativities, excitation_indices
def reconstruct_single_energy_expression(self, op, ham = None, zero_term): """ H_c: a weighted pauli operator of the terms in the passed hamiltonian that commute with the passed operator H_a: a weighted pauli operator of the terms in the passed hamiltonian that anticommute with the passed operator comm: a weighted pauli operator of the commutator [H_a, op] """ kwargs = {'op_2': op} args = [] H_c = parallel_map(commute_yes, ham, args, kwargs) H_a = parallel_map(commute_no, ham, args, kwargs) comm = parallel_map(find_commutator,H_a,args,kwargs) if not H_c: H_c.append(zero_term) if not H_a: H_a.append(zero_term) return H_c, H_a, comm
def build_vibrational_ops( num_modals: List[int], qubit_converter: QubitConverter, excitations: str | int | list[int] | Callable[[int, tuple[int, int]], list[tuple[tuple[int, ...], tuple[int, ...]]], ] = "sd", ) -> Tuple[Dict[str, PauliSumOp], Dict[str, List[bool]], Dict[str, Tuple[Tuple[ int, ...], Tuple[int, ...]]], ]: """ Args: num_modals: the number of modals per mode. qubit_converter: the `QubitConverter` to use for mapping and symmetry reduction. The Z2 symmetries stored in this instance are the basis for the commutativity information returned by this method. excitations: the types of excitations to consider. The simple cases for this input are: - a `str` containing any of the following characters: `s`, `d`, `t` or `q`. - a single, positive `int` denoting the excitation type (1 == `s`, etc.). - a list of positive integers. - and finally a callable which can be used to specify a custom list of excitations. For more details on how to write such a function refer to the default method, :meth:`generate_vibrational_excitations`. Returns: Dict of hopping operators, dict of commutativity types and dict of excitation indices """ ansatz = UVCC(qubit_converter, num_modals, excitations) excitations_list = ansatz._get_excitation_list() size = len(excitations_list) hopping_operators: Dict[str, PauliSumOp] = {} excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {} to_be_executed_list = [] for idx in range(size): to_be_executed_list += [ excitations_list[idx], excitations_list[idx][::-1] ] hopping_operators[f"E_{idx}"] = None hopping_operators[f"Edag_{idx}"] = None excitation_indices[f"E_{idx}"] = excitations_list[idx] excitation_indices[f"Edag_{idx}"] = excitations_list[idx][::-1] result = parallel_map( _build_single_hopping_operator, to_be_executed_list, task_args=(num_modals, qubit_converter), num_processes=algorithm_globals.num_processes, ) for key, res in zip(hopping_operators.keys(), result): hopping_operators[key] = res # This variable is required for compatibility with the ElectronicStructureProblem # at the moment we do not have any type of commutativity in the bosonic case. type_of_commutativities: Dict[str, List[bool]] = {} return hopping_operators, type_of_commutativities, excitation_indices
def build_hopping_operators(self, excitations: Union[str, List[List[int]]] = 'sd') \ -> Tuple[Dict[str, WeightedPauliOperator], Dict, Dict[str, List[List[int]]]]: """ Args: excitations: Returns: Dict of hopping operators, dict of commutativity types and dict of excitation indices """ exctn_types = {'s': 0, 'd': 1} if isinstance(excitations, str): degrees = [exctn_types[letter] for letter in excitations] excitations_list = UVCC.compute_excitation_lists( self._basis_size, degrees) else: excitations_list = excitations size = len(excitations_list) def _dag_list(extn_lst): dag_lst = [] for lst in extn_lst: dag_lst.append([lst[0], lst[2], lst[1]]) return dag_lst hopping_operators: Dict[str, WeightedPauliOperator] = {} excitation_indices = {} to_be_executed_list = [] for idx in range(size): to_be_executed_list += [ excitations_list[idx], _dag_list(excitations_list[idx]) ] hopping_operators['E_{}'.format(idx)] = None hopping_operators['Edag_{}'.format(idx)] = None excitation_indices['E_{}'.format(idx)] = excitations_list[idx] excitation_indices['Edag_{}'.format(idx)] = _dag_list( excitations_list[idx]) result = parallel_map(self._build_single_hopping_operator, to_be_executed_list, task_args=(self._basis_size, self._qubit_mapping), num_processes=aqua_globals.num_processes) for key, res in zip(hopping_operators.keys(), result): hopping_operators[key] = res # This variable is required for compatibility with the FermionicTransformation # at the moment we do not have any type of commutativity in the bosonic case. type_of_commutativities: Dict[str, List[bool]] = {} return hopping_operators, type_of_commutativities, excitation_indices
def split_into_paulis(ham): args = [ham.num_qubits] ham_list = ham.paulis separated_ham_list = list( parallel_map(convert_to_wpauli_list, ham_list, args, num_processes=len(psutil.Process().cpu_affinity()))) return separated_ham_list
def mapping(self, map_type, threshold=0.00000001): self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError('Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') pauli_list = WeightedPauliOperator(paulis=[]) for h in self._hs: if(h is not None): results = parallel_map(FermionicOperatorNBody._n_body_mapping, [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes) for indexes in list(itertools.product(range(n), repeat=len(h.shape))) if h[indexes] != 0], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result ''' for h in self._hs: if h is not None: indexes_list = np.argwhere(np.abs(h)>threshold) print(h.shape,len(indexes_list)) for indexes in indexes_list: h_a = [h[tuple(indexes)]] for i in indexes: h_a.append(a_list[i]) pauli_list += FermionicOperatorNBody._n_body_mapping(h_a) for h in self._hs: if(h is not None): results = parallel_map(FermionicOperatorNBody._n_body_mapping, [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes) for indexes in np.argwhere(np.abs(h)>threshold)], num_processes=aqua_globals.num_processes) for result in results: pauli_list += result ''' pauli_list.chop(threshold=threshold) if self._ph_trans_shift is not None: pauli_term = [self._ph_trans_shift, Pauli.from_label('I' * self._modes)] pauli_list += WeightedPauliOperator(paulis=[pauli_term]) return pauli_list
def build_hopping_operators(self, excitations_list): """Building all hopping operators defined in excitation list. Args: excitations_list (list): single excitations list + double excitation list Returns: dict: all hopping operators based on excitations_list, key is the string of single/double excitation; value is corresponding operator. """ size = len(excitations_list) # NOTE: build pairs of excitation operators (mu,nu of EOM!) # get all to-be-processed index if self._is_eom_matrix_symmetric: mus, nus = np.triu_indices(size) else: mus, nus = np.indices((size, size)) mus = np.asarray(mus.flat) nus = np.asarray(nus.flat) # build all hopping operators hopping_operators = {} type_of_commutativities = {} to_be_executed_list = [] for idx in range(len(mus)): mu = mus[idx] nu = nus[idx] for excitations in [ excitations_list[mu], excitations_list[nu], list(reversed(excitations_list[nu])) ]: key = '_'.join([str(x) for x in excitations]) if key not in hopping_operators: to_be_executed_list.append(excitations) hopping_operators[key] = None type_of_commutativities[key] = None # NOTE just a wrapper to this result = parallel_map( QEquationOfMotion._build_single_hopping_operator, to_be_executed_list, task_args=(self._num_particles, self._num_orbitals, self._qubit_mapping, self._two_qubit_reduction, self._z2_symmetries), num_processes=aqua_globals.num_processes) for excitations, res in zip(to_be_executed_list, result): key = '_'.join([str(x) for x in excitations]) hopping_operators[key] = res[0] type_of_commutativities[key] = res[1] return hopping_operators, type_of_commutativities
def _build_hopping_operators(self): if logger.isEnabledFor(logging.DEBUG): TextProgressBar(sys.stderr) results = parallel_map(UVCC._build_hopping_operator, self._excitations, task_args=(self._basis, 'direct'), num_processes=algorithm_globals.num_processes) hopping_ops = [qubit_op for qubit_op in results if qubit_op is not None] num_parameters = len(hopping_ops) * self._reps return hopping_ops, num_parameters
def split_into_paulis(ham): """ Used to split the given hamiltonian into lists of constituent parts: weight_list: list of complex floats that are the weights of terms in the hamiltonian pauli_list: a list of the Weighted_pauli_operator representations of the pauli strings in the hamiltonian (does not include weights) name_list: a list of strings that correspond to the names of the operators in the hamiltonian """ ham_list = ham.paulis separated_ham_list = parallel_map(convert_to_wpauli_list, ham_list, args, num_processes = aqua_globals.num_processes) return separated_ham_list
def _measure_energies(self, wavefunc, *current_ops): """ method: measure_energies finds the meausred energy for each new operator at pi/2 and -pi/2 args: circuit - the current optimal circuit current_ops - the current optimal operators returns: dictionary with: evaluation energy lists with parameter values at pi/2 and -pi/2 """ #measure energies (theta = 0, theta = pi/4, theta = -pi/4) args = [] kwargs = { 'ham': self._hamiltonian, 'energy_step_tol': self.energy_tol, 'parameter': np.pi / 4 } op_list_pi4 = list( parallel_map(Generate_roto_op, self._operator_pool.pool, args, kwargs, aqua_globals.num_processes)) kwargs['parameter'] = -np.pi / 4 op_list_negpi4 = list( parallel_map(Generate_roto_op, self._operator_pool.pool, args, kwargs, aqua_globals.num_processes)) op_list = op_list_pi4 + op_list_negpi4 del op_list_pi4 del op_list_negpi4 E_list, evals = np.real( multi_circuit_eval(wavefunc, op_list, self.quantum_instance, self._drop_duplicate_circuits)) del op_list E_list, E_list_std = list(zip(*E_list)) cutoff = int(len(E_list) / 2) Energy_pi4 = np.array(E_list[0:cutoff]) Energy_negpi4 = np.array(E_list[cutoff:]) return { 'energy pi4': Energy_pi4, 'energy negpi4': Energy_negpi4, 'num evals': evals }
def _build_hopping_operators(self): if logger.isEnabledFor(logging.DEBUG): TextProgressBar(sys.stderr) results = parallel_map(UCCSD._build_hopping_operator, self._single_excitations + self._double_excitations, task_args=(self._num_orbitals, self._num_particles, self._qubit_mapping, self._two_qubit_reduction, self._z2_symmetries), num_processes=aqua_globals.num_processes) hopping_ops = [qubit_op for qubit_op in results if qubit_op is not None] num_parameters = len(hopping_ops) * self._depth return hopping_ops, num_parameters
def print_UCCSD_parameters(molecule, core, var_form, algo_result, z2syms, sqlist, deleted_orbitals, outfile): sd, dd = UCCSD.compute_excitation_lists( [var_form._num_alpha, var_form._num_beta], var_form._num_orbitals, None, None, same_spin_doubles=var_form.same_spin_doubles, method_singles=var_form._method_singles, method_doubles=var_form._method_doubles, excitation_type=var_form._excitation_type) kept_orbitals = [ x for x in range(molecule.num_orbitals) if x not in deleted_orbitals ] ed = sd + dd results = parallel_map(UCCSD._build_hopping_operator, ed, task_args=(var_form._num_orbitals, [ var_form._num_alpha, var_form._num_beta ], core._qubit_mapping, core._two_qubit_reduction, z2syms), num_processes=aqua_globals.num_processes) def convert_index(idx): idx_converted = [] for i in idx: if (i < len(kept_orbitals)): idx_converted.append(str(kept_orbitals[i]) + 'u') else: idx_converted.append( str(kept_orbitals[i - len(kept_orbitals)]) + 'd') return idx_converted t = PrettyTable(['excitation', 'amplitude']) lst = [] im = 0 for m, (op, index) in enumerate(results): if op is not None and not op.is_empty(): lst.append( [convert_index(index), algo_result['optimal_point'][im]]) im += 1 for i in range(len(lst)): for j in range(i + 1, len(lst)): if (np.abs(lst[j][1]) > np.abs(lst[i][1])): lst[i], lst[j] = lst[j], lst[i] t.add_row([str(lst[i][0])] + [str(lst[i][1])]) outfile.write(str(t)) outfile.write("\n")
def split_into_paulis_minus_weight(ham): """ Used to split the given hamiltonian into lists of constituent parts: weight_list: list of complex floats that are the weights of terms in the hamiltonian pauli_list: a list of the Weighted_pauli_operator representations of the pauli strings in the hamiltonian (does not include weights) name_list: a list of strings that correspond to the names of the operators in the hamiltonian """ args = [ham.num_qubits] ham_list = ham.paulis separated_ham_list = parallel_map(convert_to_wpauli_list, ham_list, args, num_processes=len( psutil.Process().cpu_affinity())) return separated_ham_list
def construct_circuit(self, parameters, q=None): """ Construct the variational form, given its parameters. Args: parameters (numpy.ndarray): circuit parameters q (QuantumRegister): Quantum Register for the circuit. Returns: QuantumCircuit: a quantum circuit with given `parameters` Raises: ValueError: the number of parameters is incorrect. """ from .uccsd import UCCSD if len(parameters) != self._num_parameters: raise ValueError('The number of parameters has to be {}'.format( self._num_parameters)) if q is None: q = QuantumRegister(self._num_qubits, name='q') if self._initial_state is not None: circuit = self._initial_state.construct_circuit('circuit', q) else: circuit = QuantumCircuit(q) if logger.isEnabledFor( logging.DEBUG) and self._logging_construct_circuit: logger.debug("Evolving hopping operators:") TextProgressBar(sys.stderr) self._logging_construct_circuit = False num_excitations = len(self._hopping_ops) results = parallel_map( UCCSD._construct_circuit_for_one_excited_operator, [(self._hopping_ops[index % num_excitations], parameters[index]) for index in range(self._depth * num_excitations)], task_args=(q, self._num_time_slices), num_processes=aqua_globals.num_processes) for qc in results: if self._shallow_circuit_concat: circuit.data += qc.data else: circuit += qc return circuit
def _build_hopping_operators(self): from .uccsd import UCCSD hopping_ops = [] if logger.isEnabledFor(logging.DEBUG): TextProgressBar(sys.stderr) results = parallel_map( UCCSD._build_hopping_operator, self._single_excitations + self._double_excitations, task_args=(self._num_orbitals, self._num_particles, self._qubit_mapping, self._two_qubit_reduction, self._qubit_tapering, self._symmetries, self._cliffords, self._sq_list, self._tapering_values)) hopping_ops = [ qubit_op for qubit_op in results if qubit_op is not None ] num_parameters = len(hopping_ops) * self._depth return hopping_ops, num_parameters
def _reconstruct_op_descendants(self, ham_term_list = None): """ """ if ham_term_list == None: ham_list= split_into_paulis(self._operator) for term in ham_list: ham_term_list.append({'term': term, 'descendants': [term], 'tree': []}) if self.starting_point: op_list = self.op_list[-1] else: op_list = self.op_list for num, op in enumerate(op_list): #make sure op list in right direction print('num', num) if self.starting_point: prev_op_list = self.op_list[:-1] else: prev_op_list = self.op_list[:num] ham_term_list = parallel_map(sort_term, ham_term_list, num_processes = aqua_globals.num_processes) return ham_term_list
def mapping_new(self, map_type, threshold=0.00000001): """Map fermionic operator to qubit operator. Using multiprocess to speedup the mapping, the improvement can be observed when h2 is a non-sparse matrix. Args: map_type (str): case-insensitive mapping type. "jordan_wigner", "parity", "bravyi_kitaev", "bksf" threshold (float): threshold for Pauli simplification Returns: WeightedPauliOperator: create an Operator object in Paulis form. Raises: QiskitChemistryError: if the `map_type` can not be recognized. """ # ################################################################### # ########### DEFINING MAPPED FERMIONIC OPERATORS ############## # ################################################################### self._map_type = map_type n = self._modes # number of fermionic modes / qubits map_type = map_type.lower() if map_type == 'jordan_wigner': a_list = self._jordan_wigner_mode(n) elif map_type == 'parity': a_list = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a_list = self._bravyi_kitaev_mode(n) elif map_type == 'bksf': return bksf_mapping(self) else: raise QiskitChemistryError('Please specify the supported modes: ' 'jordan_wigner, parity, bravyi_kitaev, bksf') # ################################################################### # ########### BUILDING THE MAPPED HAMILTONIAN ################ # ################################################################### pauli_list = WeightedPauliOperator(paulis=[]) if logger.isEnabledFor(logging.DEBUG): logger.debug("Mapping one-body terms to Qubit Hamiltonian:") TextProgressBar(output_handler=sys.stderr) results = parallel_map(FermionicOperator._n_body_mapping, [(self._h1[i, j], a_list[i], a_list[j]) for i, j in itertools.product(range(n), repeat=2) if self._h1[i, j] != 0], task_args=(threshold,), num_processes=aqua_globals.num_processes) for result in results: pauli_list += result pauli_list.chop(threshold=threshold) if logger.isEnabledFor(logging.DEBUG): logger.debug("Mapping two-body terms to Qubit Hamiltonian:") TextProgressBar(output_handler=sys.stderr)