tangelo.toolboxes.qubit_mappings package

Subpackages

Submodules

tangelo.toolboxes.qubit_mappings.bravyi_kitaev module

Tools for performing Bravyi-Kitaev Transformation, as prescribed via the Fenwick Tree mapping. This implementation accommodates mapping of qubit registers where the number of qubits is not a power of two.

NB: this is a minimal implementation, just wrapping around current openfermion code (v 1.0.1). This wrapper enables future refactoring to utilize our own implementation, as needed.

tangelo.toolboxes.qubit_mappings.bravyi_kitaev.bravyi_kitaev(fermion_operator, n_qubits)

Execute transformation of FermionOperator to QubitOperator using the Bravyi-Kitaev transformation. Important note: there are several implementations of “Bravyi Kitaev” transformation, in both the literature, and historical versions of openfermion. This function executes the transformaton defined in arXiv:quant-ph/0003137. Different versions are not necessarily the same, and result in undesirable performance. This method is a simple wrapper around openfermion’s bravyi_kitaev, but we are forcing the user to pass n_qubits to avoid unexpected behaviour.

Parameters:
  • fermion_operator (FermionOperator) – input fermionic operator to be transformed.

  • n_qubits (int) – number of qubits associated with the operator.

Returns:

QubitOperator – output bravyi-kitaev encoded qubit operator.

tangelo.toolboxes.qubit_mappings.combinatorial module

Combinatorial mapping as described in references (1) and (2). In contrast to qubit mappings such as JW, BK that use occupation/parity, the mappings in this file use the Fock configurations as the elements of the basis set. Thus, the number of required qubits scales with the number of electronic configuration instead of the number of spinorbitals.

References

  1. Streltsov, A. I., Alon, O. E. & Cederbaum, L. S. General mapping for

    bosonic and fermionic operators in Fock space. Phys. Rev. A 81, 022124 (2010).

  2. Chamaki, D., Metcalf, M. & de Jong, W. A. Compact Molecular Simulation on

    Quantum Computers via Combinatorial Mapping and Variational State Preparation. Preprint at https://doi.org/10.48550/arXiv.2205.11742 (2022).

tangelo.toolboxes.qubit_mappings.combinatorial.basis(M, N)

Function to construct the combinatorial basis set, i.e. a basis set respecting the number of electrons and the total spin.

Parameters:
  • M (int) – Number of spatial orbitals.

  • N (int) – Number of alpha or beta electrons.

Returns:

OrderedDict – Lexicographically sorted basis set, mapping electronic configuration to unique integers.

tangelo.toolboxes.qubit_mappings.combinatorial.combinatorial(ferm_op, n_modes, n_electrons)

Function to transform the fermionic Hamiltonian into a basis constructed in the Fock space.

Parameters:
  • ferm_op (FermionOperator) – as followed in the openfermion package

  • n_modes (int) – Number of relevant molecular orbitals, i.e. active molecular orbitals.

  • n_electrons (int) – Number of active electrons.

Returns:

QubitOperator – Self-explanatory.

tangelo.toolboxes.qubit_mappings.combinatorial.conf_to_integer(sigma, M)

Function to map an electronic configuration to a unique integer, as done in arXiv.2205.11742 eq. (14).

Parameters:
  • sigma (tuple of int) – Orbital indices where the electron are in the electronic configuration.

  • M (int) – Number of modes, i.e. number of spatial orbitals.

Returns:

int – Unique integer for the input electronic state.

tangelo.toolboxes.qubit_mappings.combinatorial.int_to_tuple(integer, n_qubits)

Convert a qubit Hamiltonian term in integer encoding (stabilizer representation) into an Openfermion-style tuple.

Bits in the binary representation of the integer encode the Pauli operators that need to be applied to each qubit. Each consecutive pair of bits encode information for a specific qubit.

Parameters:
  • integer (int) – integer to decode. Its binary representation has 2*n_qubits bits

  • n_qubits (int) – number of qubits in the term

Returns:

tuple – OpenFermion-style term including up to n_qubits qubits

tangelo.toolboxes.qubit_mappings.combinatorial.one_body_op_on_state(op, state_in)

Function to apply a a^{dagger}_i a_j operator as described in Phys. Rev. A 81, 022124 (2010) eq. (8).

Parameters:
  • op (tuple) – Operator, written as ((qubit_i, 1), (qubit_j, 0)), where 0/1 means annihilation/creation on the specified qubit.

  • state_in (tuple) – Electronic configuration described as tuple of spinorbital indices where there is an electron.

Returns:
  • tuple – Resulting state with the same form as in the input state. Can be 0.

  • int – Phase shift. Can be -1 or 1.

tangelo.toolboxes.qubit_mappings.combinatorial.recursive_mapping(M)

Maps an arbitrary square matrix representing an operator via Pauli decomposition.

Parameters:

M (np.array(np, complex, np.complex)) – Square matrix representing the operator.

Returns:

dict[int -> complex] – Pauli operator encoded as a dictionary

tangelo.toolboxes.qubit_mappings.combinatorial.tensor_product_pauli_dicts(pa, pb)

Perform the tensor product of 2 Pauli operators by using their underlying dictionary of terms.

Parameters:
  • pa (dict[int -> complex]) – first Pauli dictionary

  • pb (dict[int -> complex]) – second Pauli dictionary

Returns:

dict[int -> complex] – tensor product of Pauli operators

tangelo.toolboxes.qubit_mappings.hcb module

Module that defines function to convert a fermionic operator to a boson operator. For electronic system, it means to couple all the electrons by pair.

tangelo.toolboxes.qubit_mappings.hcb.boson_to_qubit_mapping(bos_op)

Function to convert a Bosonic operator to a qubit operator. As qubits are bosons, the mapping is similar to the Jordan-Wigner mapping, but without the trailing Pauli-Z to account for anticommutation of the creation and annihilation operators.

In short, every creation operator b^{dagger} (resp. annihilation b) are mapped to X-iY strings (resp. X+iY), where X and Y are referring to the Pauli matrices.

Parameters:

bos_op (BosonOperator) – Self-explanatory.

Returns:

QubitOperator – Self-explanatory.

tangelo.toolboxes.qubit_mappings.hcb.hard_core_boson_operator(ferm_op)

Function to extract the coefficient of the Hard-Core Bosonic (HCB) Hamiltonian.

Refs:
  • V.E. Elfving, M. Millaruelo, J.A. Gámez, and C. Gogolin. Phys. Rev. A

    103, 032605 (2021).

  • N.T. Thang and P.T.T. Nga, Communications in Physics 21, 301 (2011).

Parameters:

ferm_op (FermionOperator) – Self-explanatory.

Returns:

BosonOperator – Self-explanatory.

tangelo.toolboxes.qubit_mappings.jkmn module

tangelo.toolboxes.qubit_mappings.jkmn.jkmn(fermion_operator, n_qubits)

The JKMN mapping of a fermion operator as described in arXiv:1910.10746v2

Parameters:
  • fermion_operator (FermionOperator) – The fermion operator to transform to a qubit operator

  • n_qubits (int) – The number of qubits in the system

Returns:

QubitOperator – The qubit operator corresponding to the Fermion Operator

tangelo.toolboxes.qubit_mappings.jkmn.jkmn_prep_vector(vector)

Apply JKMN mapping to fermion occupation vector.

Each fermionic mode i is generated by applying gamma_{2*i} = a_i^{dagger} + a_i. The returned vector is defined by which qubits have X or Y operations applied.

Parameters:

vector (list of int) – The occupation of each spinorbital

Returns:

numpy array of int – The state preparation vector that defines which qubits to apply X gates to

tangelo.toolboxes.qubit_mappings.jordan_wigner module

Jordan-Wigner transform on fermionic operators.

tangelo.toolboxes.qubit_mappings.jordan_wigner.jordan_wigner(operator)

Apply the Jordan-Wigner transform to a FermionOperator, InteractionOperator, or DiagonalCoulombHamiltonian to convert to a QubitOperator.

Operators are mapped as follows: a_j^dagger -> Z_0 .. Z_{j-1} (X_j - iY_j) / 2 a_j -> Z_0 .. Z_{j-1} (X_j + iY_j) / 2

Returns:

QubitOperator – An instance of the QubitOperator class.

Warning

The runtime of this method is exponential in the maximum locality of the original FermionOperator.

Raises:
  • TypeError – Operator must be a FermionOperator,

  • DiagonalCoulombHamiltonian, or InteractionOperator.

tangelo.toolboxes.qubit_mappings.mapping_transform module

This module provides a common point for mapping operators and statevectors from Fermionic to Qubit encodings via any of: - Jordan-Wigner - Bravyi-Kitaev (Fenwick Tree implementation) - symmetry-conserving Bravyi-Kitaev (2-qubit reduction via Z2 taper)

tangelo.toolboxes.qubit_mappings.mapping_transform.fermion_to_qubit_mapping(fermion_operator, mapping, n_spinorbitals=None, n_electrons=None, up_then_down=False, spin=0)

Perform mapping of fermionic operator to qubit operator. This function is mostly a wrapper around standard openfermion code, with some important distinctions. We strictly enforce the specification of n_qubits for Bravyi-Kitaev type transformations, and n_electrons for scBK. In the absence of this information, these methods can return unexpected results if the input operator does not specifically address the highest-orbital/qubit index.

Parameters:
  • fermion_operator (FermionOperator) – operator to translate to qubit representation.

  • mapping (string) – options are – “JW” (Jordan Wigner), “BK” (Bravyi Kitaev), “scBK” (symmetry-conserving Bravyi Kitaev).

  • n_spinorbitals (int) – number of spin-orbitals for problem. Not required for Jordan-Wigner.

  • n_electrons (int) – number of occupied electron modes in problem. Required for symmetry conserving Bravyi-Kitaev only.

  • up_then_down (bool) – flag to change basis ordering, putting all spin up then all spin down.

  • spin (int) – The spin number (n_alpha - n_beta)

Returns:

QubitOperator – input operator, encoded in the qubit space.

tangelo.toolboxes.qubit_mappings.mapping_transform.get_fermion_operator(operator)

Cast operator to FermionOperator datatype. Input is of SymbolicOperator type, but term words must be valid input for FermionOperator, as for example for InteractionOperator.

Parameters:

operator (SymbolicOperator) – input operator to be cast.

Returns:

FermionOperator – Self-explanatory.

tangelo.toolboxes.qubit_mappings.mapping_transform.get_qubit_number(mapping, n_spinorbitals)

Get the number of qubits for a specified number of spin orbitals, after passing through the qubit mapping. Symmetry-conserving Bravyi-Kitaev reduces the qubit number by 2.

Parameters:
  • mapping (string) – qubit-mapping, JW, BK or SCBK.

  • n_spinorbitals (int) – number of spin-orbitals for molecule.

Returns:

int – number of qubits.

tangelo.toolboxes.qubit_mappings.mapping_transform.make_up_then_down(fermion_operator, n_spinorbitals)
Re-order the orbital indexing to force all spin up, followed by all spin

down. The default ordering alternates between spin up and down.

Parameters:
  • fermion_operator (FermionOperator) – input operator.

  • n_spinorbitals (int) – number of spin-orbitals in register.

Returns:

FermionOperator – operator with all spin up followed by all spin down.

tangelo.toolboxes.qubit_mappings.statevector_mapping module

Tools to define a reference state under a specified qubit-mapping, and translate into a Circuit.

tangelo.toolboxes.qubit_mappings.statevector_mapping.do_bk_transform(vector)

Apply Bravyi-Kitaev transformation to fermion occupation vector. Currently, simple wrapper on openfermion tools.

Parameters:

vector (numpy array of int) – fermion occupation vector.

Returns:

numpy array of int – qubit-encoded occupation vector.

tangelo.toolboxes.qubit_mappings.statevector_mapping.do_jkmn_transform(vector)

Instantiate qubit vector for JKMN transformation.

Parameters:

vector (numpy array of int) – fermion occupation vector.

Returns:

numpy array of int – qubit-encoded occupation vector.

tangelo.toolboxes.qubit_mappings.statevector_mapping.do_scbk_transform(vector, n_spinorbitals)

Instantiate qubit vector for symmetry-conserving Bravyi-Kitaev Generate Majorana mode for each occupied spin-orbital and apply X gate to each non-Z operator in the Pauli word.

Parameters:
  • vector (numpy array of int) – fermion occupation vector.

  • n_spinorbitals (int) – number of qubits in register.

Returns:

numpy array of int – qubit-encoded occupation vector.

tangelo.toolboxes.qubit_mappings.statevector_mapping.get_mapped_vector(vector, mapping, up_then_down=False)

Return vector to generate circuit for a given occupation vector and mapping

Parameters:
  • vector (array of int) – fermion occupation vector with up_then_down=False ordering. Number of spin-orbitals is assumed by length of array.

  • mapping (str) – One of the supported qubit mappings

  • up_then_down (bool) – if True, all up, then all down, if False, alternating spin up/down.

Returns:

array – The vector that generates the mapping occupations

tangelo.toolboxes.qubit_mappings.statevector_mapping.get_reference_circuit(n_spinorbitals, n_electrons, mapping, up_then_down=False, spin=None)

Build the Hartree-Fock state preparation circuit for the designated mapping.

Parameters:
  • n_spinorbitals (int) – number of qubits in register.

  • n_electrons (int) – number of electrons in system.

  • mapping (string) – specify mapping, see mapping_transform.py for options “JW” (Jordan Wigner), or “BK” (Bravyi Kitaev), or “SCBK” (symmetry-conserving Bravyi Kitaev).

  • up_then_down (boolean) – if True, all up, then all down, if False, alternating spin up/down.

  • spin (int) – 2*S = n_alpha - n_beta.

Returns:

Circuit – instance of tangelo.linq Circuit class.

tangelo.toolboxes.qubit_mappings.statevector_mapping.get_vector(n_spinorbitals, n_electrons, mapping, up_then_down=False, spin=None)

Get integer vector corresponding to Hartree Fock reference state. Reference state will occupy up to the n_electron-th molecular orbital. Depending on convention, basis is ordered alternating spin-up/spin-down (updown = False), or all up, then all down (updown = True).

Parameters:
  • n_spinorbitals (int) – number of spin-orbitals in register.

  • n_electrons (int) – number of electrons in system.

  • mapping (string) – specify mapping, see mapping_transform.py for options “JW” (Jordan Wigner), or “BK” (Bravyi Kitaev), or “SCBK” (symmetry-conserving Bravyi Kitaev) or “JKMN” (Jiang Kalev Mruczkiewicz Neven)

  • up_then_down (boolean) –

    if True, all up, then all down, if False,

    alternating spin up/down.

    spin (int): 2*S = n_alpha - n_beta.

Returns:

numpy array of int – binary integer array indicating occupation of each spin-orbital.

tangelo.toolboxes.qubit_mappings.statevector_mapping.vector_to_circuit(vector)

Translate occupation vector into a circuit. Each occupied state corresponds to an X-gate on the associated qubit index.

Parameters:

vector (numpy array of int) – occupation vector.

Returns:

Circuit – instance of tangelo.linq Circuit class.

tangelo.toolboxes.qubit_mappings.symmetry_conserving_bravyi_kitaev module

Module to remove two qubits from the problem space using conservation of electron number and conservation of electron spin. As described in arXiv:1701.08213 and Phys. Rev. X 6, 031007.

tangelo.toolboxes.qubit_mappings.symmetry_conserving_bravyi_kitaev.check_operator(fermion_operator, num_orbitals=None, up_then_down=False)

Check if the input fermion operator is suitable for application of symmetry-consering BK qubit reduction. Excitation must: preserve parity of fermion occupation, and parity of spin expectation value. This assumes alternating spin-up/spin-down ordering of input operator.

Parameters:
  • fermion_operator (FermionOperator) – input fermionic operator.

  • num_orbitals (int) – specify number of orbitals (number of modes / 2), required for up then down ordering.

  • up_then_down (bool) – True if all spin up before all spin down, otherwise alternates.

tangelo.toolboxes.qubit_mappings.symmetry_conserving_bravyi_kitaev.edit_operator_for_spin(qubit_operator, spin_orbital, orbital_parity)

Removes the Z terms acting on the orbital from the operator. For qubits to be tapered out, the action of Z-operators in operator terms are reduced to the associated eigenvalues. This simply corresponds to multiplying term coefficients by the related eigenvalue +/-1.

Parameters:
  • qubit_operator (QubitOperator) – input operator.

  • spin_orbital (int) – index of qubit encoding (spin/occupation) parity.

  • orbital_parity (int) – plus/minus one, parity of eigenvalue.

Returns:

QubitOperator – updated operator, with relevant coefficients multiplied by +/-1.

tangelo.toolboxes.qubit_mappings.symmetry_conserving_bravyi_kitaev.prune_unused_indices(qubit_operator, prune_indices, n_qubits)

Rewritten from openfermion implementation. This uses the number of qubits, rather than the operator itself to specify the number of qubits relevant to the problem. This is especially important for, e.g. terms in the ansatz which may not individually pertain to all qubits in the problem.

Remove indices that do not appear in any terms.

Indices will be renumbered such that if an index i does not appear in any terms, then the next largest index that appears in at least one term will be renumbered to i.

Parameters:
  • qubit_operator (QubitOperator) – input operator.

  • prune_indices (tuple of int) – indices to be removed from qubit register.

  • n_qubits (int) – number of qubits in register.

Returns:

QubitOperator – output operator, with designated qubit indices excised.

tangelo.toolboxes.qubit_mappings.symmetry_conserving_bravyi_kitaev.symmetry_conserving_bravyi_kitaev(fermion_operator, n_spinorbitals, n_electrons, up_then_down=False, spin=0)

Returns the QubitOperator for the FermionOperator supplied, with two qubits removed using conservation of (parity) of electron spin and number, as described in arXiv:1701.08213. This function has been modified from its analogous implementation in openfermion in order to circumvent failures when passing a fermion_operator which does not explicitly reference the highest index qubit in the register.

Parameters:
  • fermion_operator (FermionOperator) – fermionic operator to transform to QubitOperator.

  • n_spinorbitals (int) – The number of active spin-orbitals being considered for the system.

  • n_electrons (int) – The number of active fermions being considered for the system (note, this is less than the number of electrons in a molecule if some orbitals have been frozen).

  • up_then_down (bool) – specify if the spin-orbital basis is already ordered putting all spin up before all spin down states.

Returns:

QubitOperator – The qubit operator corresponding to the supplied fermionic operator, with two qubits removed using spin symmetries.

Warning

Reorders orbitals from the default even-odd ordering to all spin-up orbitals, then all spin-down orbitals.

Raises:
  • ValueError if fermion_hamiltonian isn"t of the type FermionOperator, or

  • active_orbitals isn"t an integer, or active_fermions isn"t an integer.

Notes: This function reorders the spin orbitals as all spin-up, then all

spin-down. It uses the OpenFermion bravyi_kitaev_tree mapping, rather than the bravyi-kitaev mapping. Caution advised when using with a Fermi-Hubbard Hamiltonian; this technique correctly reduces the Hamiltonian only for the lowest energy even and odd fermion number states, not states with an arbitrary number of fermions.

Module contents