def _build_single_hopping_operator(index, num_particles, num_orbitals, qubit_mapping, two_qubit_reduction, z2_symmetries): h_1 = np.zeros((num_orbitals, num_orbitals), dtype=complex) h_2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals), dtype=complex) if len(index) == 2: i, j = index h_1[i, j] = 4.0 elif len(index) == 4: i, j, k, m = index h_2[i, j, k, m] = 16.0 fer_op = FermionicOperator(h_1, h_2) qubit_op = fer_op.mapping(qubit_mapping) if qubit_mapping == 'parity' and two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) commutativities = [] if not z2_symmetries.is_empty(): for symmetry in z2_symmetries.symmetries: symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]]) commuting = qubit_op.commute_with(symmetry_op) anticommuting = qubit_op.anticommute_with(symmetry_op) if commuting != anticommuting: # only one of them is True if commuting: commutativities.append(True) elif anticommuting: commutativities.append(False) else: raise AquaError("Symmetry {} is nor commute neither anti-commute " "to exciting operator.".format(symmetry.to_label())) return qubit_op, commutativities
def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries): h_1 = np.zeros((num_orbitals, num_orbitals)) h_2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals)) if len(index) == 2: i, j = index h_1[i, j] = 1.0 h_1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h_2[i, j, k, m] = 1.0 h_2[m, k, j, i] = -1.0 dummpy_fer_op = FermionicOperator(h1=h_1, h2=h_2) qubit_op = dummpy_fer_op.mapping(qubit_mapping) if two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) if not z2_symmetries.is_empty(): symm_commuting = True for symmetry in z2_symmetries.symmetries: symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]]) symm_commuting = qubit_op.commute_with(symmetry_op) if not symm_commuting: break qubit_op = z2_symmetries.taper(qubit_op) if symm_commuting else None if qubit_op is None: logger.debug('Excitation (%s) is skipped since it is not commuted ' 'with symmetries', ','.join([str(x) for x in index])) return qubit_op, index
def _build_hopping_operator(self, index): def check_commutativity(op_1, op_2): com = op_1 * op_2 - op_2 * op_1 com.zeros_coeff_elimination() return True if com.is_empty() else False two_d_zeros = np.zeros((self._num_orbitals, self._num_orbitals)) four_d_zeros = np.zeros((self._num_orbitals, self._num_orbitals, self._num_orbitals, self._num_orbitals)) dummpy_fer_op = FermionicOperator(h1=two_d_zeros, h2=four_d_zeros) h1 = two_d_zeros.copy() h2 = four_d_zeros.copy() if len(index) == 2: i, j = index h1[i, j] = 1.0 h1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h2[i, j, k, m] = 1.0 h2[m, k, j, i] = -1.0 dummpy_fer_op.h1 = h1 dummpy_fer_op.h2 = h2 qubit_op = dummpy_fer_op.mapping(self._qubit_mapping) qubit_op = qubit_op.two_qubit_reduced_operator( self._num_particles) if self._two_qubit_reduction else qubit_op if self._qubit_tapering: for symmetry in self._symmetries: symmetry_op = Operator(paulis=[[1.0, symmetry]]) symm_commuting = check_commutativity(symmetry_op, qubit_op) if not symm_commuting: break if self._qubit_tapering: if symm_commuting: qubit_op = Operator.qubit_tapering(qubit_op, self._cliffords, self._sq_list, self._tapering_values) else: qubit_op = None if qubit_op is None: logger.debug('excitation ({}) is skipped since it is not commuted ' 'with symmetries'.format(','.join( [str(x) for x in index]))) return qubit_op
def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, qubit_tapering, symmetries, cliffords, sq_list, tapering_values): def check_commutativity(op_1, op_2): com = op_1 * op_2 - op_2 * op_1 com.zeros_coeff_elimination() return True if com.is_empty() else False h1 = np.zeros((num_orbitals, num_orbitals)) h2 = np.zeros((num_orbitals, num_orbitals, num_orbitals, num_orbitals)) if len(index) == 2: i, j = index h1[i, j] = 1.0 h1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h2[i, j, k, m] = 1.0 h2[m, k, j, i] = -1.0 dummpy_fer_op = FermionicOperator(h1=h1, h2=h2) qubit_op = dummpy_fer_op.mapping(qubit_mapping, num_workers=1) qubit_op = qubit_op.two_qubit_reduced_operator(num_particles) \ if two_qubit_reduction else qubit_op if qubit_tapering: for symmetry in symmetries: symmetry_op = Operator(paulis=[[1.0, symmetry]]) symm_commuting = check_commutativity(symmetry_op, qubit_op) if not symm_commuting: break if qubit_tapering: if symm_commuting: qubit_op = Operator.qubit_tapering(qubit_op, cliffords, sq_list, tapering_values) else: qubit_op = None if qubit_op is None: logger.debug('Excitation ({}) is skipped since it is not commuted ' 'with symmetries'.format(','.join( [str(x) for x in index]))) return index, qubit_op
def _map_fermionic_operator_to_qubit(fer_op: FermionicOperator, qubit_mapping: str, num_particles: List[int], two_qubit_reduction: bool) -> WeightedPauliOperator: """ Args: fer_op: Fermionic Operator qubit_mapping: fermionic to qubit mapping num_particles: number of particles two_qubit_reduction: two qubit reduction Returns: qubit operator """ qubit_op = fer_op.mapping(map_type=qubit_mapping, threshold=0.00000001) if qubit_mapping == 'parity' and two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles) return qubit_op
def _build_hopping_operator(index, num_orbitals, num_particles, qubit_mapping, two_qubit_reduction, z2_symmetries, skip_commute_test=False): """ Builds a hopping operator given the list of indices (index) that is a single or a double excitation. Args: index (list): a single or double excitation (e.g. double excitation [0,1,2,3] for a 4 spin-orbital system) num_orbitals (int): number of spin-orbitals num_particles (int): number of electrons qubit_mapping (str): qubit mapping type two_qubit_reduction (bool): reduce the number of qubits by 2 if parity qubit mapping is used z2_symmetries (Z2Symmetries): class that contains the symmetries of hamiltonian for tapering skip_commute_test (bool): when tapering excitation operators we test and exclude any that do not commute with symmetries. This test can be skipped to include all tapered excitation operators whether they commute or not. Returns: WeightedPauliOperator: qubit_op list: index """ h_1 = np.zeros((num_orbitals, num_orbitals)) h_2 = np.zeros( (num_orbitals, num_orbitals, num_orbitals, num_orbitals)) if len(index) == 2: i, j = index h_1[i, j] = 1.0 h_1[j, i] = -1.0 elif len(index) == 4: i, j, k, m = index h_2[i, j, k, m] = 1.0 h_2[m, k, j, i] = -1.0 dummpy_fer_op = FermionicOperator(h1=h_1, h2=h_2) qubit_op = dummpy_fer_op.mapping(qubit_mapping) if two_qubit_reduction: qubit_op = Z2Symmetries.two_qubit_reduction( qubit_op, num_particles) if not z2_symmetries.is_empty(): symm_commuting = True for symmetry in z2_symmetries.symmetries: symmetry_op = WeightedPauliOperator(paulis=[[1.0, symmetry]]) symm_commuting = qubit_op.commute_with(symmetry_op) if not symm_commuting: break if not skip_commute_test: qubit_op = z2_symmetries.taper( qubit_op) if symm_commuting else None else: qubit_op = z2_symmetries.taper(qubit_op) if qubit_op is None: logger.debug( 'Excitation (%s) is skipped since it is not commuted ' 'with symmetries', ','.join([str(x) for x in index])) return qubit_op, index