qlass.utils package
The utils module provides utility functions for executing quantum algorithms, processing measurement results, and computing loss functions for VQE optimization.
Key Features
Loss Functions
loss_function: Standard loss function for sampling-based VQEloss_function_matrix: Loss function for qubit unitary-based VQEloss_function_photonic_unitary: Loss function for photonic unitaries with post-selectione_vqe_loss_function: Ensemble-VQE loss function supporting multiple states
Utilities
linear_circuit_to_unitary: Converts Perceval linear circuits to unitary matricesDataCollector: Collects and stores energy data during ensemble-VQE optimizationloss_data: List of cost function valuesenergy_data: List of energy values for each state
Submodules
- qlass.utils.compute_energy(pauli_bin: tuple[int, ...], res: dict[tuple[int, ...], float]) float[source]
Compute the expectation value for a given Pauli string and measurement results.
- Parameters:
pauli_bin (Tuple[int, ...]) – A tuple of 0’s and 1’s (0’s are identities, 1’s are non-identities (X or Z))
res (Dict[Tuple[int, ...], float]) – Frequencies of measured qubit bitstrings
- Returns:
The corresponding expectation value
- Return type:
float
- qlass.utils.compute_expectation_value_from_unitary(unitary: ndarray, pauli_matrix: ndarray, initial_state: ndarray | None = None) float[source]
Compute expectation value <ψ|H|ψ> where |ψ> = U|0>.
- Parameters:
unitary (np.ndarray) – Unitary matrix representing the circuit
pauli_matrix (np.ndarray) – Matrix representation of Pauli operator
initial_state (np.ndarray) – Initial state vector (default: |0…0>)
- Returns:
Expectation value
- Return type:
float
- qlass.utils.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.utils.get_probabilities(samples: list[FockState | tuple[int, ...] | str]) dict[FockState | tuple[int, ...], float][source]
Get the probabilities of sampled states.
This function now handles: - Fock states: List[exqalibur.FockState] -> Dict[exqalibur.FockState, float] - Bitstring tuples: List[Tuple[int, …]] -> Dict[Tuple[int, …], float] - Bitstring strings (from Qiskit): List[str] -> Dict[Tuple[int, …], float]
- Parameters:
samples (List[Union[exqalibur.FockState, Tuple[int, ...], str]]) – Sampled states (Fock states, bitstring tuples, or bitstring strings)
- Returns:
Probabilities of sampled states
- Return type:
Dict[Union[exqalibur.FockState, Tuple[int, …]], float]
- qlass.utils.is_qubit_state(state: FockState) tuple[int, ...] | bool[source]
Check if a given Fock state is a valid qubit state.
- Parameters:
state (exqalibur.FockState) – The Fock state to check
- Returns:
The corresponding qubit state if valid, False otherwise
- Return type:
Union[Tuple[int, …], bool]
- qlass.utils.linear_circuit_to_unitary(circuit: Circuit) ndarray[source]
Convert a linear optical circuit to a unitary matrix.
- Parameters:
circuit (pcvl.Circuit) – Linear optical circuit
- Returns:
Unitary matrix representation of the circuit
- Return type:
np.ndarray
- qlass.utils.logical_state_to_modes(logical_state: int, m: int) list[int][source]
Convert a logical qubit state to the set of occupied photon modes.
Parameters:
- logical_stateint
Integer representing the logical state (0 to 2^m - 1)
- mint
Number of qubits
Returns:
- List[int]
List of occupied mode indices (0-indexed)
- qlass.utils.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.utils.loss_function_matrix(params: ndarray, H: dict[str, float], unitary_executor: Callable) float[source]
Compute loss function using unitary matrices directly.
- Parameters:
params (np.ndarray) – Variational parameters
H (Dict[str, float]) – Hamiltonian dictionary
unitary_executor – Function that returns unitary matrix given params
- Returns:
Energy expectation value
- Return type:
float
- qlass.utils.loss_function_photonic_unitary(params: ndarray, H: dict[str, float], photonic_unitary_executor: Callable, initial_state: ndarray | None = None, ancillary_modes: list[int] | None = None) float[source]
Computes the loss function for a photonic VQE using the efficient, matrix-free state vector approach for post-selection.
This version accepts a full state vector for the initial state, allowing for superposition states, and allows for post-selection on ancillary modes.
- Parameters:
params – Variational parameters for the ansatz.
H – Hamiltonian dictionary.
photonic_unitary_executor – A function that takes params and returns the M x M photonic unitary U, where M is the total number of modes (logical + ancillary).
initial_state – The initial qubit state as a 2^m dimensional numpy vector. If None, defaults to the |00…0> state.
ancillary_modes – A list of mode indices to be treated as ancillary. Post-selection is performed by assuming these modes are 0 (vacuum) for both input and output.
- Returns:
The computed energy expectation value.
- qlass.utils.normalize_samples(samples: Any) list[FockState | tuple[int, ...]][source]
Normalize samples from different executor formats to a consistent format.
Handles: - Qiskit bitstring format: [‘00’, ‘01’, ‘11’] -> [(0,0), (0,1), (1,1)] - Already normalized tuples: [(0,0), (0,1)] -> [(0,0), (0,1)] - ExQalibur FockStates: [FockState, …] -> [FockState, …]
- Parameters:
samples – Raw samples in various formats
- Returns:
Normalized samples
- Return type:
List[Union[exqalibur.FockState, Tuple[int, …]]]
- qlass.utils.permanent(matrix: ndarray) complex[source]
Calculate the permanent of a matrix.
The permanent is like a determinant but without alternating signs: Perm(A) = Σ_{σ∈Sₘ} Π_{i=1 to m} A_{i,σ(i)}
Parameters:
- matrixnp.ndarray
Square matrix to calculate permanent of
Returns:
- complex
The permanent of the matrix
- qlass.utils.photon_to_qubit_unitary(U_photon: ndarray) ndarray[source]
Convert a photon unitary to the effective qubit unitary via post-selection.
Parameters:
- U_photonnp.ndarray
The 2m × 2m unitary matrix acting on photon modes
Returns:
- np.ndarray
The 2^m × 2^m effective qubit unitary matrix
- qlass.utils.qubit_state_marginal(prob_dist: dict[FockState | tuple[int, ...], float]) dict[tuple[int, ...], float][source]
Calculate the frequencies of measured qubit states from a probability distribution.
This function now handles both Fock states and bitstring inputs: - If input contains Fock states, converts them to qubit states using is_qubit_state - If input already contains bitstrings (tuples), passes them through directly
- Parameters:
prob_dist (Dict[Union[exqalibur.FockState, Tuple[int, ...]], float]) – Probability distribution of either Fock states or bitstrings
- Returns:
Frequencies of measured qubit states
- Return type:
Dict[Tuple[int, …], float]
- qlass.utils.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