def mapping(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: Operator: 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 = self._jordan_wigner_mode(n) elif map_type == 'parity': a = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a = 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 = Operator(paulis=[]) if logger.isEnabledFor(logging.DEBUG): logger.debug("Mapping one-body terms to Qubit Hamiltonian:") TextProgressBar(output_handler=sys.stderr) results = parallel_map( FermionicOperator._one_body_mapping, [(self._h1[i, j], a[i], a[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) results = parallel_map( FermionicOperator._two_body_mapping, [(self._h2[i, j, k, m], a[i], a[j], a[k], a[m]) for i, j, k, m in itertools.product(range(n), repeat=4) if self._h2[i, j, k, m] != 0], task_args=(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 += Operator(paulis=[pauli_term]) return pauli_list
def mapping(self, map_type, threshold=0.00000001, num_workers=4): """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 num_workers (int): number of processes used to map. Returns: Operator: 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 = self._jordan_wigner_mode(n) elif map_type == 'parity': a = self._parity_mode(n) elif map_type == 'bravyi_kitaev': a = 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 ################ #################################################################### """ max_workers = min(num_workers, multiprocessing.cpu_count()) pauli_list = Operator(paulis=[]) with concurrent.futures.ProcessPoolExecutor( max_workers=max_workers) as executor: # One-body futures = [ executor.submit(FermionicOperator._one_body_mapping, self._h1[i, j], a[i], a[j], threshold) for i, j in itertools.product(range(n), repeat=2) if self._h1[i, j] != 0 ] for future in futures: result = future.result() pauli_list += result pauli_list.chop(threshold=threshold) # Two-body futures = [ executor.submit(FermionicOperator._two_body_mapping, self._h2[i, j, k, m], a[i], a[j], a[k], a[m], threshold) for i, j, k, m in itertools.product(range(n), repeat=4) if self._h2[i, j, k, m] != 0 ] for future in futures: result = future.result() 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 += Operator(paulis=[pauli_term]) return pauli_list