def hartree_fock_bitstring_mapped( num_spin_orbitals: int, num_particles: Tuple[int, int], qubit_converter: QubitConverter, match_convert: bool = True, ) -> List[bool]: """Compute the bitstring representing the mapped Hartree-Fock state for the specified system. Args: num_spin_orbitals: The number of spin orbitals, has a min. value of 1. num_particles: The number of particles as a tuple (alpha, beta) containing the number of alpha- and beta-spin electrons, respectively. qubit_converter: A QubitConverter instance. match_convert: Whether to use `convert_match` method of the qubit converter (default), or just do mapping and possibly two qubit reduction but no tapering. The latter is an advanced usage - e.g. if we are trying to auto-select the tapering sector then we would not want any match conversion done on a converter that was set to taper. Returns: The bitstring representing the mapped state of the Hartree-Fock state as array of bools. """ # get the bitstring encoding the Hartree Fock state bitstr = hartree_fock_bitstring(num_spin_orbitals, num_particles) # encode the bitstring as a `FermionicOp` label = ["+" if bit else "I" for bit in bitstr] bitstr_op = FermionicOp("".join(label), display_format="sparse") # map the `FermionicOp` to a qubit operator qubit_op: PauliSumOp = ( qubit_converter.convert_match(bitstr_op, check_commutes=False) if match_convert else qubit_converter.convert_only(bitstr_op, num_particles) ) # We check the mapped operator `x` part of the paulis because we want to have particles # i.e. True, where the initial state introduced a creation (`+`) operator. bits = [] for bit in qubit_op.primitive.paulis.x[0]: bits.append(bit) return bits
def _build_single_hopping_operator( excitation: Tuple[Tuple[int, ...], Tuple[int, ...]], num_spin_orbitals: int, qubit_converter: QubitConverter, ) -> Tuple[PauliSumOp, List[bool]]: label = ["I"] * num_spin_orbitals for occ in excitation[0]: label[occ] = "+" for unocc in excitation[1]: label[unocc] = "-" fer_op = FermionicOp(("".join(label), 4.0**len(excitation[0])), display_format="sparse") qubit_op: PauliSumOp = qubit_converter.convert_only( fer_op, qubit_converter.num_particles) z2_symmetries = qubit_converter.z2symmetries commutativities = [] if not z2_symmetries.is_empty(): for symmetry in z2_symmetries.symmetries: symmetry_op = PauliSumOp.from_list([(symmetry.to_label(), 1.0)]) paulis = qubit_op.primitive.paulis len_paulis = len(paulis) commuting = len( paulis.commutes_with_all( symmetry_op.primitive.paulis)) == len_paulis anticommuting = (len( paulis.anticommutes_with_all( symmetry_op.primitive.paulis)) == len_paulis) if commuting != anticommuting: # only one of them is True if commuting: commutativities.append(True) elif anticommuting: commutativities.append(False) else: raise QiskitNatureError( f"Symmetry {symmetry.to_label()} neither commutes nor anti-commutes " "with excitation operator.") return qubit_op, commutativities