ofex.transforms

This module provides functions and utilities for transforming and working with fermions and qubits.

It includes:

  • Conversions between fermion and qubit states/operators.

  • Majorana to fermion conversion.

  • Fermion rotation operations.

  • Factorization-related tools for fermions.

Modules:

  • fermion_qubit: Functions for fermion ↔ qubit state/operator conversions.

  • fermion_rotation: Functions for handling fermion rotations.

  • majorana_fermion: Tools for converting Majorana fermions to regular fermions.

  • fermion_factorization: Additional utilities related to fermion factorization.

ofex.transforms.fermion_to_qubit_state(fermion_state: ndarray | Dict[BinaryFockVector, Number] | lil_matrix, transform: str, **kwargs) ndarray | Dict[BinaryFockVector, Number] | lil_matrix[source]

Convert a fermionic state to a qubit state using a specified transformation.

Parameters:
  • fermion_state (State) – The input state in the fermionic basis to be transformed.

  • transform (str) – The transformation method to be applied. Supported options: “jordan_wigner”, “bravyi_kitaev”, “bravyi_kitaev_tree”, “symmetry_conserving_bravyi_kitaev”.

  • kwargs – Additional arguments required for specific transformations, such as: - “active_orbitals” (int): For symmetry-conserving transformations. If not provided, the number of full orbitals is used.

Returns:

The transformed state in the qubit representation.

Return type:

State

ofex.transforms.fermion_to_qubit_operator(fermion_op: FermionOperator, transform: str, **kwargs) QubitOperator[source]

Convert a FermionOperator to a QubitOperator using a specified transformation.

Parameters:
  • fermion_op (FermionOperator) – The input operator in the fermionic basis to be transformed.

  • transform (str) – The transformation method to be applied. Supported options: “jordan_wigner”, “bravyi_kitaev”, “bravyi_kitaev_tree”, “binary_code_transform”, “symmetry_conserving_bravyi_kitaev”.

  • kwargs

    Additional arguments required for some transformations, such as:

    • ”n_qubits” (int): Number of qubits for transformations “bravyi_kitaev” and “bravyi_kitaev_tree”.

    • ”code” (BinaryCode): The binary code for “binary_code_transform”.

    • ”active_fermions” (int) and “active_orbitals” (int): For “symmetry_conserving_bravyi_kitaev”.

Returns:

The transformed operator in the qubit representation.

Return type:

QubitOperator

Raises:

ValueError – If the provided transform method is not supported. If required arguments in kwargs are missing for certain transformations.

ofex.transforms.fermion_to_qubit_state_general(state: Dict[BinaryFockVector, Number], transform: str, **kwargs) Dict[BinaryFockVector, Number][source]

Convert a general fermionic state to a qubit state using the specified transformation. Because this function transforms the creation operator to qubit form and multiplies it by the state, it is computationally expensive. This function is not recommended for large systems; and used for debugging and other transform not specified in the fermion_to_qubit_state function.

Parameters:
  • state (SparseStateDict) – The input state in the fermionic basis to be transformed.

  • transform (str) – The transformation to apply. Supported options include “jordan_wigner”, “bravyi_kitaev”, “bravyi_kitaev_tree”, and others. The “symmetry_conserving_bravyi_kitaev” transformation is not implemented.

  • kwargs – Additional arguments required for some transformations, such as: - “n_qubits” (int): Number of qubits for transformations “bravyi_kitaev” and “bravyi_kitaev_tree”. - “code” (BinaryCode): The binary code for “binary_code_transform”. - “active_fermions” (int) and “active_orbitals” (int): For “symmetry_conserving_bravyi_kitaev”.

Returns:

The transformed state in the qubit basis.

Return type:

SparseStateDict

Raises:

NotImplementedError – If the “symmetry_conserving_bravyi_kitaev” transformation is requested.

ofex.transforms.qubit_to_fermion_state(qubit_state: ndarray | Dict[BinaryFockVector, Number] | lil_matrix, transform: str, **kwargs) ndarray | Dict[BinaryFockVector, Number][source]

Convert a qubit state to a fermionic state using a specified transformation.

Parameters:
  • qubit_state (State) – Input state in the qubit basis to be transformed.

  • transform (str) – The transformation method to apply. Supported options: “jordan_wigner”, “bravyi_kitaev”, “bravyi_kitaev_tree”, “symmetry_conserving_bravyi_kitaev”.

  • kwargs

    Additional arguments required for some transformations, such as:

    • ”active_fermions” (int): Number of active fermions for the symmetry-conserving transformation.

    • ”active_orbitals” (int): For symmetry-conserving transformations. If not provided, the number

      of full orbitals is used.

Returns:

Transformed fermionic state in sparse or dense form.

Return type:

Union[DenseState, SparseStateDict]

Raises:
  • ValueError – If required arguments for specific transformations are missing.

  • NotImplementedError – For unspecified transformation methods.

ofex.transforms.fermion_rotation_state(state: ndarray | Dict[BinaryFockVector, Number] | lil_matrix, v_mat: ndarray, spatial_v: bool) ndarray | Dict[BinaryFockVector, Number] | lil_matrix[source]

Transforms a Fermionic state represented in the Fock basis using an orbital mixing matrix.

This function applies a rotation on the input state according to the orbital mixing matrix v_mat. If spatial_v is set to True, the mixing matrix is expanded to include spin-orbital interactions.

The function maintains type consistency by converting the final state back to its original representation.

Parameters:
  • state (State) – The input quantum state in Fock representation.

  • v_mat (np.ndarray) – The orbital mixing matrix. Each element represents the transformation coefficients between orbitals.

  • spatial_v (bool) – Whether v_mat is in spatial orbital. If True, considers spin-orbital mixing by applying the Kronecker product of v_mat with the identity matrix for spin states. Defaults to False.

Returns:

The rotated quantum state in its original representation.

Return type:

State

ofex.transforms.fermion_rotation_operator(fop: FermionOperator, v_mat: ndarray, spatial_v: bool = False) FermionOperator[source]

Transforms the FermionOperator using an orbital mixing matrix.

This function takes a FermionOperator and applies a transformation based on the provided orbital mixing matrix (v_mat). The matrix may optionally account for spin-orbital mixing when spatial_v is set to True.

Parameters:
  • fop (FermionOperator) – The original FermionOperator.

  • v_mat (np.ndarray) – The orbital mixing matrix. Each element represents the transformation coefficients between orbitals.

  • spatial_v (bool) – Whether v_mat is in spatial orbital. If True, considers spin-orbital mixing by applying the Kronecker product of v_mat with the identity matrix for spin states. Defaults to False.

Returns:

A new FermionOperator representing the transformed Hamiltonian after applying the orbital mixing defined by v_mat.

Return type:

FermionOperator

ofex.transforms.find_pauli_symmetry(pauli_list: List[QubitOperator] | QubitOperator, num_qubits: int, debug: bool = False) Tuple[FieldArray, List[str], List[int], QubitOperator][source]

Identifies Pauli symmetry operators within a given (list of) QubitOperators. Pauli symmetry operators(\hat{S}_k) commute with all input pauli operators(\hat{H}):

\hat{H}= \sum_j \alpha_j \hat{P}_j

[\hat{S}_k, \hat{P}_j] = 0 \quad \forall k, j \quad\mathrm{thus, }\quad [\hat{S}_k, \hat{H}] = 0 \quad\forall k.

Symmetry operators are selected with maximal mutual commutativity:

\mathcal{S}_M=arg\,max_{\mathcal{S}}|\mathcal{S}|\quad \mathrm{s.t. }\quad
\mathcal{S}\subseteq \{\hat{S}_k: \forall k\}, \quad [\hat{S}_k,
\hat{S}_l] = 0 \quad \forall \hat{S}_k, \hat{S}_l \in \mathcal{S}.

Symmetry operators are diagonalized as X-type by applying the following Clifford transformation:

\hat{S}^{(X)}_k = \hat{C} \hat{S}_k \hat{C}^{\dagger} \quad \forall \hat{S}_k \in \mathcal{S}_M.

For each symmetry operator \hat{S}^{(X)}_k, a qubit q(k) is selected such that:

\{\hat{S}^{(X)}_k, \hat{Z}_{q(k)}\} = 0 \quad [\hat{S}^{(X)}_k, \hat{Z}_{q(l)}] = 0 \quad \forall k \neq l.

Then the following unitary operator is constructed:

\hat{U} = \prod_{k=1}^M \frac{1}{\sqrt{2}}(\hat{S}^{(X)}_k + \hat{Z}_{q(k)}).

Which block diagonalizes the input Pauli operators:

\hat{H}_{\mathrm{sym}} = \hat{U} \hat{C} \hat{H} \hat{C}^{\dagger} \hat{U}^{\dagger}

[\hat{H}_{\mathrm{sym}}, \hat{Z}_{q(k)}] = 0 \quad \forall k.

Refer to arXiv:1701.08213 for more details.

Parameters:
  • pauli_list (Union[List[QubitOperator], QubitOperator]) – Input list of QubitOperators or a single QubitOperator from which the symmetry is to be found.

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

  • debug (bool) – If True, validate the symmetry operators found.

Returns:

A tuple containing:
  • The final symmetry operators in tableau form (FieldArray).

  • The Clifford transformations \hat{C} as a list of string representations.

  • The indices of qubits q(k) involved in symmetry operations.

  • A unitary operator \hat{U} block diagonalizing the input Pauli operators.

Return type:

Tuple[FieldArray, List[str], List[int], QubitOperator]

ofex.transforms.qubit_reduction_operator(operator: QubitOperator | List[QubitOperator], num_qubits: int, symm_clifford_list: List[str], symm_qubits: List[int], symm_unitary: QubitOperator) Dict[Tuple[Tuple[int, int], ...], QubitOperator | List[QubitOperator]][source]

Reduces a Pauli operator or a list of Pauli operators based on identified symmetry properties.

The reduction involves applying Clifford transformations, symmetry unitaries, and qubit removal on the input operators. The reduced operators are decomposed into symmetry sectors.

Parameters:
  • operator (Union[QubitOperator, List[QubitOperator]]) – The input Pauli operator(s) to be reduced using symmetry.

  • num_qubits (int) – The total number of qubits in the system.

  • symm_clifford_list (List[str]) – A list of Clifford transformations corresponding to symmetry diagonalization.

  • symm_qubits (List[int]) – The indices of qubits involved in symmetry.

  • symm_unitary (QubitOperator) – The unitary operator \hat{U} constructed from the symmetry operators.

Returns:

Union[QubitOperator, List[QubitOperator]]]:

A dictionary mapping symmetry sectors (defined as tuples of qubit states and parities) to the reduced operator(s).

Return type:

Dict[Tuple[Tuple[int, int], …]

ofex.transforms.qubit_reduction_state(state: ndarray | Dict[BinaryFockVector, Number] | lil_matrix, symm_clifford_list: List[str], symm_qubits: List[int], symm_unitary: QubitOperator) Tuple[Dict[Tuple[Tuple[int, int], ...], Dict[BinaryFockVector, Number]], Dict[Tuple[Tuple[int, int], ...], float]][source]

Reduces a quantum state by decomposing it with respect to symmetry sectors.

Parameters:
  • state (State) – The quantum state to reduce.

  • symm_clifford_list (List[str]) – A list of Clifford transformations corresponding to symmetry diagonalization.

  • symm_qubits (List[int]) – The indices of qubits involved in symmetry.

  • symm_unitary (QubitOperator) – The unitary operator \hat{U} constructed from the symmetry operators.

Returns:

SparseStateDict], Dict[Tuple[Tuple[int, int], …]: float]]:

A tuple containing: - The reduced states in sparse dictionary format. - The normalization factors for each reduced state.

Return type:

Tuple[Dict[Tuple[Tuple[int, int], …]

ofex.transforms.fermion_factorization

This module provides functions and tools for manipulating and factorizing fermionic Hamiltonians.

The module contains utilities to convert fermion Hamiltonians into various representations, perform double factorization of electron integrals, and handle reflection or number operator transformations. It also includes helper functions for one-body and two-body terms, eigenvalue decomposition of tensors, and verification of results.

Core functionalities include: 1. Hamiltonian conversion to/from electron integral tensors in spatial and spin orbital formats. 2. Double factorization of electron integrals with optional reflection operators. 3. Construction of Hamiltonians from factorized forms. 4. Calculation of norms for reflection-based factorizations.

Common operations performed by the module involve manipulating electron integrals, normal-ordering fermion operators, and expressing Hamiltonians in highly factorized forms.

Available functions: - ham_to_ei_spatial, ei_to_ham_spatial - ham_to_ei_spin, ei_to_ham_spin - double_factorization - number_factorization_to_reflection - double_factorization_to_hamiltonian - calculate_reflect_norm

ofex.transforms.fermion_factorization.ham_to_ei_spatial(fham: FermionOperator, n_spinorb: int) Tuple[ndarray, ndarray, float][source]

Converts a Fermion Hamiltonian into spatial one-body and two-body electron integral tensors.

This function processes the input Fermion Hamiltonian into spatial orbital tensors, separating the one-body and two-body electronic integrals as well as the constant energy contribution. It ensures normal ordering of the Hamiltonian terms and constructs the corresponding tensors for spatial orbitals.

Notation:

E_{pq} = a†_{p↑}a_{q↑} + a†_{p↓}a_{q↓}

H = ∑_{pq} oei[p,q] E_{pq}
  • (1/2) ∑_{pqrs} tei[p,q,r,s] E_{pq} * E_{rs}

  • const

Parameters:
  • fham (FermionOperator) – The input Fermion Hamiltonian.

  • n_spinorb (int) – The total number of spin orbitals (must be an even number).

Returns:

  • spatial_oei (ndarray): A 2D tensor with one-body electron integrals for spatial orbitals.

  • spatial_tei (ndarray): A 4D tensor with two-body electron integrals for spatial orbitals.

  • const (float): The constant term in the Hamiltonian.

Return type:

Tuple[np.ndarray, np.ndarray, float]

ofex.transforms.fermion_factorization.ei_to_ham_spatial(spatial_oei: ndarray, spatial_tei: ndarray, const: float) FermionOperator[source]

Constructs a Fermion Hamiltonian from the spatial one-body and two-body electron integral tensors. (Inverse function of ham_to_ei_spatial)

This method uses the provided one-body and two-body integral tensors, as well as a constant term, to construct a normalized Fermion Hamiltonian.

Notation:

E_{pq} = a†_{p↑}a_{q↑} + a†_{p↓}a_{q↓}

H = ∑_{p,q} oei[p, q] E_{pq}
  • 1/2 ∑_{pqrs} tei[p, q, r, s] E_{pq} * E_{rs}

  • const

Parameters:
  • spatial_oei (np.ndarray) – A 2D array containing the spatial one-body electron integrals.

  • spatial_tei (np.ndarray) – A 4D array containing the spatial two-body electron integrals.

  • const (float) – A constant energy term to include in the Hamiltonian.

Returns:

The resulting Fermion Hamiltonian.

Return type:

FermionOperator

ofex.transforms.fermion_factorization.ham_to_ei_spin(fham: FermionOperator, n_spinorb: int) Tuple[ndarray, ndarray, float][source]

Converts a Fermion Hamiltonian into spin one-body and two-body electron integral tensors.

This function separates the provided Fermion Hamiltonian into spin orbital tensors, which include one-body and two-body electron integrals as well as a constant energy term. The method ensures normal ordering of the Hamiltonian terms and calculates the appropriate tensors for spin orbitals.

Mathematical Notation:

E_{pq} = a†_{p}a_{q}

H = ∑_{p,q} oei[p, q] * E_{pq}
  • (1/2) ∑_{p,q,r,s} tei[p, q, r, s] * E_{pq} * E_{rs}

  • const

Parameters:
  • fham (FermionOperator) – The input Fermion Hamiltonian in normal order.

  • n_spinorb (int) – The total number of spin orbitals.

Returns:

A tuple containing:
  • spin_oei (np.ndarray): A 2D array (n_spinorb x n_spinorb) representing spin one-body electron integrals.

  • spin_tei (np.ndarray): A 4D array (n_spinorb x n_spinorb x n_spinorb x n_spinorb)

    representing spin two-body electron integrals.

  • const (float): The constant energy term in the Hamiltonian.

Return type:

Tuple[np.ndarray, np.ndarray, float]

ofex.transforms.fermion_factorization.ei_to_ham_spin(spin_oei: ndarray, spin_tei: ndarray, const: float) FermionOperator[source]

Constructs a Fermion Hamiltonian from the spin one-body and two-body electron integral tensors. (Inverse function of ham_to_ei_spin)

This function takes one-body and two-body spin integral tensors, along with a constant term, and converts them back into a FermionOperator representation of the Hamiltonian. The result includes creation and annihilation operators for spin orbitals.

Notation:

E_{pq} = a†_{p}a_{q}

H = ∑_{p,q} oei[p, q] E_{pq}
  • (1/2) ∑_{p,q,r,s} tei[p, q, r, s] * E_{pq} * E_{rs}

  • const

Parameters:
  • spin_oei (np.ndarray) – A 2D array (n_spinorb x n_spinorb) representing spin one-body electron integrals.

  • spin_tei (np.ndarray) – A 4D array (n_spinorb x n_spinorb x n_spinorb x n_spinorb) representing spin two-body electron integrals.

  • const (float) – The constant energy term in the Hamiltonian.

Returns:

The resulting Fermion Hamiltonian.

Return type:

FermionOperator

ofex.transforms.fermion_factorization.double_factorization(oei: ndarray, tei: ndarray, reflection: bool = False) Tuple[List[ndarray], List[ndarray], float][source]

Perform double factorization of a Fermionic Hamiltonian using one-body and two-body spatial/spin electron integral tensors.

This method factorizes a Fermionic Hamiltonian, represented by the one-body (oei) and two-body (tei) electron integrals, into a sequence of matrices (h_list) and unitary operators (u_list). The factorization can be performed with either number operators or reflection operators, based on the optional argument reflection.

Notation:
  • n_p = n_{p↑} + n_{p↓} (number operator)

  • r_{p↑} = 2n_{p↑} - 1, r_{p↓} = 2n_{p↓} - 1 (reflection operators)

  • r_p = r_{p↑} + r_{p↓}

Double-Factorized Hamiltonian (H):
  1. If reflection=False:
    H = u0 (∑_{p} h[0][p] n_p) u0†
    • 1/2 ∑_{m >= 1} um (∑_{pq} h[m][p,q] n_p n_q) um†

  2. If reflection=True:
    H = u0 (∑_{p} h[0][p] r_p) u0†
    • 1/2 ∑_{m >= 1} um (∑_{pq} h[m][p,q] r_p r_q) um† + const

Here, um represents a unitary rotation operator corresponding to spatial/spin orbital transformations.

Parameters:
  • oei (np.ndarray) – 2D tensor of one-body electron integrals (dimension: n_orb x n_orb) in spin or spatial orbitals.

  • tei (np.ndarray) – 4D tensor of two-body electron integrals (dimension: n_orb x n_orb x n_orb x n_orb) in spin or spatial orbitals.

  • reflection (bool) – If True, factorizes in terms of reflection operators; defaults to False.

Returns:

  • h_list: List of coefficient matrices; h_list[0] is a 1D array (one-body coefficients), while h_list[m > 0] are 2D arrays (two-body coefficients).

  • u_list: List of unitary rotation matrices corresponding to orbital rotations.

  • const: Scalar constant representing the remaining contribution, which is zero if reflection=False.

Return type:

Tuple[List[np.ndarray], List[np.ndarray], float]

ofex.transforms.fermion_factorization.number_factorization_to_reflection(h_list: List[ndarray], u_list: List[ndarray], is_spin: bool) Tuple[List[ndarray], List[ndarray], float][source]

Transforms the factorization with number operators into that of reflection operators.

Notation:
  • n_p = n_{p↑} + n_{p↓} (number operator for spatial orbitals)

  • r_{p↑} = 2n_{p↑} - 1, r_{p↓} = 2n_{p↓} - 1 (reflection operators for spin orbitals)

  • r_p = r_{p↑} + r_{p↓} (reflection operator for spatial orbitals)

Transformation:

Given a factorization with number operators: H = u0 (∑_{p} h[0][p] n_p) u0† + ∑_{m≥1} um (∑_{pq} h[m][p,q] n_p n_q) um†,

this function transforms h and u such that the resulting Hamiltonian uses reflection operators: H = u0 (∑_{p} h’[0][p] r_p) u0† + ∑_{m≥1} u’m (∑_{pq} h’[m][p,q] r_p r_q) u’m† + const.

Similar transformations apply when the inputs are specified in terms of spin orbital operators.

Parameters:
  • h_list (List[np.ndarray]) – A list of coefficient matrices for the input Hamiltonian in the number operator form. The first element is a 1D array representing the one-body coefficients, and subsequent elements are 2D arrays representing two-body coefficients.

  • u_list (List[np.ndarray]) – A list of unitary rotation matrices corresponding to orbital transformations, where each matrix has dimensions n_orb x n_orb.

  • is_spin (bool) – Indicates if the inputs (h_list, u_list) correspond to spin orbital operators. - True: Spin orbital operators. - False: Spatial orbital operators.

Returns:

  • ref_h_list (List[np.ndarray]): The transformed coefficient matrices for the Hamiltonian

    in the reflection operator form.

  • ref_u_list (List[np.ndarray]): The list of rotation unitary matrices corresponding to

    the reflection operator representation.

  • const (float): The constant energy term arising during the transformation, equivalent

    to the trace of the original one-body coefficient matrix. This term ensures energy conservation.

Return type:

Tuple[List[np.ndarray], List[np.ndarray], float]

Raises:

ValueError – If the resulting constant term is not a real number.

ofex.transforms.fermion_factorization.double_factorization_to_hamiltonian(h_list: List[ndarray], u_list: List[ndarray], is_spin: bool, is_reflection: bool = False) FermionOperator[source]

Transform lists of coefficient matrices (h_list) and unitary operators (u_list) into a single FermionOperator Hamiltonian.

This method reconstructs a Hamiltonian from its factorized representation, using the provided coefficient matrices and orbital rotation matrices. Depending on the input parameters, it supports both spin and spatial orbital representations, as well as reflection-based operators.

Parameters:
  • h_list (List[np.ndarray]) – A list of coefficient matrices for the factorized Hamiltonian. - h_list[0] is a 1D array for one-body coefficients. - h_list[m > 0] are 2D arrays for two-body coefficients.

  • u_list (List[np.ndarray]) – A list of unitary matrices corresponding to orbital rotations. Each matrix should have dimensions n_orb x n_orb.

  • is_spin (bool) – Indicates whether the coefficient matrices and unitaries are in terms of spin orbitals. - True: Spin orbital representation. - False: Spatial orbital representation.

  • is_reflection (bool) – Specifies whether the coefficient matrices correspond to reflection operators. - True: Use reflection operators. - False: Use number operators.

Returns:

A FermionOperator representing the reconstructed Hamiltonian.

Return type:

FermionOperator

ofex.transforms.fermion_factorization.calculate_reflect_norm(ref_h_list: List[ndarray], frag_type: str) float[source]

Calculate the norm of a factorized Hamiltonian represented in the reflection operator form.

This method computes the norm for a Hamiltonian decomposed into reflection operators, based on the specified fragment type (“LCU” or “FH”). The norm is calculated based on either the L1 or L2 norm, depending on the fragment type because the terms are individually counted in LCU while they are grouped in FH type.

Parameters:
  • ref_h_list (List[np.ndarray]) – A list of coefficient matrices for the factorized Hamiltonian in reflection operator form. The first element corresponds to the one-body coefficients, while subsequent elements are two-body coefficient matrices.

  • frag_type (str) – The type of fragment used in the factorization. - “LCU”: Use the L1 norm for the norm calculation. - “FH”: Use the L2 norm for the norm calculation.

Returns:

The computed norm of the Hamiltonian based on the given fragment type.

Return type:

float

Raises:

ValueError – If the provided frag_type is not “LCU” or “FH”.