qlass package

Module contents

class qlass.HardwareConfig(brightness: float = 1.0, indistinguishability: float = 1.0, g2: float = 0.0, g2_distinguishable: bool = False, transmittance: float = 0.9, phase_imprecision: float = 0.0, phase_error: float = 0.0, photon_loss_component_db: float = 0.05, photon_loss_waveguide_db_per_cm: float = 0.3, source_efficiency: float = 0.9, detector_efficiency: float = 0.95, fusion_success_prob: float = 0.11, hom_visibility: float = 0.97, avg_path_length_per_component_cm: float = 0.1)[source]

Bases: object

A data structure to hold the physical properties of a photonic hardware backend.

avg_path_length_per_component_cm: float = 0.1
brightness: float = 1.0
detector_efficiency: float = 0.95
fusion_success_prob: float = 0.11
g2: float = 0.0
g2_distinguishable: bool = False
hom_visibility: float = 0.97
indistinguishability: float = 1.0
phase_error: float = 0.0
phase_imprecision: float = 0.0
photon_loss_component_db: float = 0.05
photon_loss_waveguide_db_per_cm: float = 0.3
source_efficiency: float = 0.9
transmittance: float = 0.9
qlass.Hchain_KS_hamiltonian(n_hydrogens: int = 2, R: float = 1.2) tuple[dict[str, float], ndarray, int][source]

Generate the one-body Hamiltonian for a linear chain of hydrogen atoms at a given bond length.

This function constructs a non-interacting one-body Hamiltonian for a chain of hydrogen atoms using Density Functional Theory (DFT) with a closed-shell Hartree-Fock (RHF) method. The hydrogen atoms are placed linearly along the z-axis with a uniform bond length R. The resulting molecular orbitals are transformed into a qubit Hamiltonian representation.

Parameters:
  • n_hydrogens (int, optional) – Number of hydrogen atoms in the linear chain. Must be an even integer. Default is 2.

  • R (float, optional) – Bond length between adjacent hydrogen atoms in angstroms. Default is 1.2.

Returns:

  • H_qubit_dic (dict) – Dictionary representation of the qubit Hamiltonian in terms of Pauli operators. The keys correspond to Pauli strings and the values are their coefficients.

  • mo_energy (list of float) – Molecular orbital energies computed from PySCF.

  • n_molecular_orbital (int) – Number of molecular orbitals.

Notes

  • The electronic structure is calculated using the minimal sto-3g basis set.

  • The function internally performs the following steps:
    1. Builds the molecular geometry.

    2. Runs RHF self-consistent field (SCF) calculation via PySCF.

    3. Constructs the Fock and overlap matrices in the atomic orbital (AO) basis.

    4. Transforms to an orthogonalized atomic orbital (OAO) basis.

    5. Maps the resulting Hamiltonian to a qubit representation.

  • The transformation to the qubit Hamiltonian uses a helper function transformation_Hmatrix_Hqubit and a dictionary builder sparsepauliop_dictionary.

qlass.LiH_hamiltonian(R: float = 1.5, charge: int = 0, spin: int = 0, num_electrons: int = 2, num_orbitals: int = 2) dict[str, float][source]

Generate the qubit Hamiltonian for the LiH molecule at a given bond length.

This function uses OpenFermion and PySCF to compute molecular integrals, applies active space transformation, and maps to qubits via Jordan-Wigner.

Note: Nuclear repulsion energy is excluded to maintain compatibility with qiskit_nature behavior.

Parameters:
  • R (float) – Bond length in Angstroms

  • charge (int) – Charge of the molecule

  • spin (int) – Spin of the molecule

  • num_electrons (int) – Number of electrons in active space

  • num_orbitals (int) – Number of molecular orbitals in active space

Returns:

Hamiltonian dictionary with Pauli string keys

Return type:

Dict[str, float]

class qlass.ResourceAwareCompiler(config: HardwareConfig)[source]

Bases: object

A compiler that analyzes a quantum circuit against a hardware configuration to estimate its real-world performance and resource requirements.

compile(circuit: QuantumCircuit) Processor[source]

Compiles a Qiskit circuit and runs a resource analysis.

qlass.brute_force_minimize(H: dict[str, float]) float[source]

Compute the minimum eigenvalue of a Hamiltonian using brute force.

Parameters:

H (Dict[str, float]) – Hamiltonian dictionary

Returns:

Minimum eigenvalue of the Hamiltonian

Return type:

float

qlass.compile(circuit: QuantumCircuit, backend_name: str = 'Naive', use_postselection: bool = True, input_state: StateVector | FockState | None = None, noise_model: NoiseModel = None) Processor[source]

Convert a Qiskit quantum circuit to a Perceval processor.

Parameters:
  • circuit (QuantumCircuit) – The Qiskit quantum circuit to convert

  • backend_name (str) – The backend to use for the Perceval processor Options are: “Naive”, “SLOS”

  • use_postselection (bool) – Whether to use postselection for the processor

  • input_state (Optional[Union[pcvl.StateVector, pcvl.BasicState]]) – The input state for the processor. If None, the |0…0> state is used.

  • noise_model (NoiseModel) – A perceval NoiseModel object representing the noise model for the processor.

Returns:

The quantum circuit as a Perceval processor

Return type:

pcvl.Processor

qlass.custom_unitary_ansatz(lp: ndarray, pauli_string: str, U: ndarray, noise_model: NoiseModel | None = None) Processor[source]

Creates Perceval quantum processor that directly implements a given unitary matrix. This function serves as a custom ansatz that bypasses circuit construction and instead loads a full unitary matrix representing the quantum operation.

The unitary is embedded in a Qiskit QuantumCircuit, converted to Perceval format, and returned as a Processor object with post-selection enabled.

Parameters:
  • lp (np.ndarray) – Placeholder array of parameter values (unused, for compatibility).

  • pauli_string (str) – Pauli string used to determine the number of qubits.

  • U (np.ndarray) – A unitary matrix of shape (2^n, 2^n) where n = len(pauli_string).

  • noise_model (NoiseModel) – A perceval NoiseModel object representing the noise model.

Returns:

The quantum circuit as a Perceval processor implementing unitary U.

Return type:

Processor

qlass.e_vqe_loss_function(lp: ndarray, H: dict[str, float], executor: Any, energy_collector: Any, weight_option: str = 'weighted') float[source]

Compute the loss function for the ensemble Variational Quantum Eigensolver (VQE) with automatic Pauli grouping for measurement optimization.

This function automatically groups commuting Pauli terms to reduce the number of measurements required. The grouping is applied transparently without changing the function interface, providing automatic optimization for ensemble VQE algorithms.

The function works with executors that return either: 1. Fock states (from linear optical circuits) - exqalibur.FockState objects 2. Bitstring tuples (from regular qubit-based circuits) 3. Bitstring strings (from Qiskit Sampler)

The executor should return samples in one of these formats: - Dict with ‘results’ key: {‘results’: [samples]} - Direct list of samples: [samples] - Qiskit-style format with bitstrings or counts

Parameters:
  • lp (np.ndarray) – Array of variational circuit parameters. Typically optimized to minimize the expectation value of the Hamiltonian.

  • H (dict of {str: float}) – Hamiltonian represented as a dictionary mapping Pauli strings (e.g., 'X0 Z1') to their coefficients.

  • executor (callable) – Function or callable object that executes the quantum circuit and returns measurement samples. Must accept arguments (lp, pauli_string) and return samples in one of the accepted formats.

  • energy_collector (object) – Object responsible for tracking or logging the energy convergence history. Must implement a method energies_convergence(energies, n_ensembles, total_loss).

  • weight_option ({'weighted', 'equi', 'ground_state_only'}) – Scheme for assigning ensemble weights: - 'weighted' (default): Linearly decreasing weights with index, i.e., w_i < w_j for i > j. - 'equi' : Equal weights for all occupied orbitals, w_i = w_j. - 'ground_state_only' : Only the ground state contributes, w_0 = 1, others 0.

Returns:

loss – The computed ensemble VQE loss value, equal to the weighted sum of ensemble energies.

Return type:

float

qlass.generate_report(analysis_report: dict[str, Any]) None[source]

Prints the analysis report in a human-readable format.

qlass.group_commuting_pauli_terms(hamiltonian: dict[str, float]) list[dict[str, float]][source]

Group commuting Pauli terms in a Hamiltonian.

This function takes a Hamiltonian represented as a dictionary of Pauli strings and their coefficients, and returns a list of Hamiltonians where each group contains only mutually commuting Pauli terms. This grouping can be used to reduce the number of measurements needed in quantum algorithms like VQE.

This function provides a more general approach than OpenFermion’s group_into_tensor_product_basis_sets, which only groups terms that are diagonal in the same tensor product basis. Our function groups all mutually commuting terms regardless of the measurement basis required.

Parameters:

hamiltonian (Dict[str, float]) – Hamiltonian dictionary with Pauli string keys and coefficient values

Returns:

List of grouped Hamiltonians, where each group

contains mutually commuting Pauli terms

Return type:

List[Dict[str, float]]

qlass.hamiltonian_matrix(H: dict[str, float]) ndarray[source]

Convert a Hamiltonian dictionary to a matrix representation.

Parameters:

H (Dict[str, float]) – Hamiltonian dictionary

Returns:

Matrix representation of the Hamiltonian

Return type:

np.ndarray

qlass.le_ansatz(lp: ndarray, pauli_string: str, noise_model: NoiseModel | None = None) Processor[source]

Creates Perceval quantum processor for the Linear Entangled Ansatz. This ansatz consists of a layer of parametrized rotations, followed by a layer of CNOT gates, and finally another layer of parametrized rotations.

Parameters:
  • lp (np.ndarray) – Array of parameter values

  • pauli_string (str) – Pauli string

  • noise_model (NoiseModel) – A perceval NoiseModel object representing the noise model

Returns:

The quantum circuit as a Perceval processor

Return type:

Processor

qlass.loss_function(lp: ndarray, H: dict[str, float], executor: Any, mitigator: Any | None = None) float[source]

Compute the loss function for the VQE algorithm with automatic Pauli grouping.

This function automatically groups commuting Pauli terms to reduce the number of measurements required. The grouping is applied transparently without changing the function interface, providing automatic optimization for VQE algorithms.

The function works with executors that return either: 1. Fock states (from linear optical circuits) - exqalibur.FockState objects 2. Bitstring tuples (from regular qubit-based circuits) 3. Bitstring strings (from Qiskit Sampler)

The executor should return samples in one of these formats: - Dict with ‘results’ key: {‘results’: [samples]} - Direct list of samples: [samples] - Qiskit-style format with bitstrings or counts

Parameters:
  • lp (np.ndarray) – Array of parameter values

  • H (Dict[str, float]) – Hamiltonian dictionary

  • executor – A callable function that executes the quantum circuit.

  • mitigator – Optional mitigator object (e.g., M3Mitigator) to correct measurement errors.

Returns:

The computed loss value

Return type:

float

qlass.pauli_commute(p1: str, p2: str) bool[source]

Check if two Pauli strings commute.

Two Pauli strings commute if and only if the number of positions where both have non-identity operators that are different is even.

Parameters:
  • p1 (str) – First Pauli string

  • p2 (str) – Second Pauli string

Returns:

True if the Pauli strings commute, False otherwise

Return type:

bool

Raises:

ValueError – If Pauli strings have different lengths

qlass.rotate_qubits(pauli_string: str, vqe_circuit: Circuit | QuantumCircuit) Circuit[source]

Apply the correct rotations on corresponding qubits for expectation value computation.

Parameters:
  • pauli_string (str) – A string representation of Pauli operators

  • vqe_circuit (pcvl.Circuit) – The VQE circuit to modify

Returns:

The modified VQE circuit with applied rotations

Return type:

pcvl.Circuit

qlass.sparsepauliop_dictionary(H: QubitOperator) dict[str, float][source]

Converts an OpenFermion QubitOperator into a dictionary representation.

This function translates the structure of an OpenFermion QubitOperator, which represents a sum of Pauli strings, into a Python dictionary. The keys of the dictionary are string representations of Pauli operators (e.g., “IXYZ”), and the values are their corresponding real coefficients.

Parameters:

H – The OpenFermion QubitOperator to be converted. Each term in this operator is a product of Pauli operators acting on specific qubits.

Returns:

A dictionary where each key is a Pauli string (e.g., “IZX”) representing a term in the Hamiltonian, and its value is the real part of the coefficient for that term.

qlass.transformation_Hmatrix_Hqubit(Hmatrix: ndarray, nqubits: int) QubitOperator[source]

Transform a Hamiltonian matrix into an OpenFermion QubitOperator representation.

This function converts a Hermitian matrix, expressed in the computational basis, into an equivalent Hamiltonian written as a sum of tensor products of Pauli operators (I, X, Y, Z). The result is an OpenFermion QubitOperator that can be used in quantum simulation frameworks.

Parameters:
  • Hmatrix (np.ndarray) – A complex Hermitian matrix of shape (2**nqubits, 2**nqubits) representing the Hamiltonian in the computational basis.

  • nqubits (int) – Number of qubits in the system. Determines the dimension of Hmatrix.

Returns:

H_qubit – The Hamiltonian expressed as a sum of Pauli operators with complex coefficients.

Return type:

openfermion.QubitOperator

Notes

  • Each matrix element Hmatrix[i, j] is decomposed into a sum of tensor products of single-qubit projectors expressed in the Pauli basis.

  • The transformation uses the following single-qubit projector identities:

    \[\]

    |0⟩⟨0| = (I + Z) / 2, |1⟩⟨1| = (I - Z) / 2, |0⟩⟨1| = (X + iY) / 2, |1⟩⟨0| = (X - iY) / 2

  • Terms with negligible coefficients (magnitude < 1e-12) are ignored to improve numerical stability.