qlass.vqe package
The vqe module provides implementations of Variational Quantum Eigensolver algorithms tailored for photonic quantum computing. The VQE algorithm is a hybrid quantum-classical approach originally proposed for photonic processors [PMS+14].
Key Features
Executor Types
The VQE class supports three executor types to handle different abstraction levels of the photonic hardware:
sampling: Uses sampling from quantum processors (default).qubit_unitary: Uses unitary matrices directly for qubit states (ideal simulation).photonic_unitary: Uses photonic unitaries with dual-rail encoding and post-selection. This explicitly models the mapping of qubits to optical modes described in LOQC architectures [KMN+07].
Optimization Algorithms
Standard VQE: Minimizes ground state energy using
cost="VQE".Ensemble-VQE (e-VQE): Computes multiple states simultaneously using
cost="e-VQE". This implements subspace-search variational quantum eigensolvers [NMF19] to find excited states.weighted: Linearly decreasing weightsequi: Equal weights for all statesground_state_only: Only ground state contributes
Ansätze
hf_ansatz: Hartree-Fock based ansatz supporting:method="WFT": Wave function theorymethod="DFT": Density functional theory [KS65]Compatible with both VQE and e-VQE costs
VQE Class
- class qlass.vqe.VQE(hamiltonian: dict[str, float], executor: Callable, num_params: int, optimizer: str = 'COBYLA', executor_type: str = 'sampling', initial_state: ndarray | None = None, ancillary_modes: list[int] | None = None, mitigator: Any | None = None)[source]
Bases:
objectVariational Quantum Eigensolver for photonic quantum computing.
This class provides a high-level interface for running VQE experiments on photonic simulators, finding ground state energies of quantum systems.
- compare_with_exact(exact_energy: float | None = None) dict[str, float][source]
Compare the VQE result with the exact ground state energy.
- Parameters:
exact_energy (float) – Exact ground state energy
- Returns:
Comparison metrics
- Return type:
dict
- parametershift_grad(vqefunction: Callable, param: ndarray, *args: Any) ndarray[source]
Compute the gradient of a variational quantum function using the parameter-shift rule.
This method evaluates the gradient of the given variational function with respect to its parameters by shifting each parameter (theta) by ±π/2.
- Parameters:
vqefunction (Callable) – A callable that evaluates the variational quantum objective. It must accept a parameter array as its first argument and return a scalar value.
param (numpy.ndarray) – One-dimensional array of variational parameters at which the gradient is evaluated.
*args (tuple) – Additional positional arguments passed directly to vqefunction.
- Returns:
grad – Array of the same shape as intialparam containing the gradient of vqefunction with respect to each parameter.
- Return type:
numpy.ndarray
Notes
This implementation uses the standard parameter-shift rule:
\[\frac{\partial f(\theta)}{\partial \theta_i} = \frac{1}{2} [f(\theta_i + \frac{\pi}{2}) - f(\theta_i - \frac{\pi}{2})]\]
- plot_convergence(exact_energy: float | None = None) None[source]
Plot the energy convergence during the optimization.
- Parameters:
exact_energy (float) – Exact ground state energy for comparison, if available
- run(initial_params: ndarray | None = None, max_iterations: int = 100, verbose: bool = True, weight_option: str = 'weighted', cost: str = 'VQE', jacobian: str | None = None) float[source]
Run a Variational Quantum Eigensolver (VQE) or ensemble-VQE optimization to find the ground state energy of a given Hamiltonian.
This method executes the classical optimization loop using SciPy’s
minimizefunction, updating the variational parameters of a quantum circuit. It supports both standard VQE and ensemble-VQE (e-VQE) algorithms, with customizable weighting schemes for the ensemble. Progress can be logged at each step ifverbose=True.- Parameters:
initial_params (np.ndarray, optional) – Initial parameters for the variational quantum circuit. If
None, random parameters will be generated uniformly in [0,1). Default isNone.max_iterations (int, optional) – Maximum number of iterations for the optimizer. Default is 100.
verbose (bool, optional) – If
True, prints progress information including number of qubits, parameters, and final energies. Default isTrue.weight_option ({'weighted', 'equi', 'ground_state_only'}, optional) – Weighting scheme for ensemble-VQE: -
'weighted': linearly decreasing weights (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) Default is'weighted'.cost ({'VQE', 'e-VQE'}, optional) – Choice of optimization algorithm: -
'VQE': standard single-state VQE optimization. -'e-VQE': ensemble-VQE using multiple states and the specified weights. Default is'VQE'.jacobian ({'None', 'parameter_shift'}, optional) – Method for computing the gradient vector. Only for CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov, trust-exact and trust-constr. If it is a callable, it should be a function that returns the gradient vector. -
'None'the gradient will be estimated using 2-point finite difference estimation with an absolute step size. -'parameter_shift'evaluates the gradient of the given variational function±π/2. (with respect to its parameters by shifting each parameter (theta) by)
- Returns:
Minimum cost (energy) found by the optimizer.
- Return type:
float
Notes
The method resets the loss and parameter history at the start of each run.
For ensemble-VQE, the
weight_optiondetermines how individual state energies are combined into the total loss.Exact energies for the Hamiltonian are computed at the end using a brute-force diagonalization routine for reference.
Verbose mode prints information about optimizer progress, final energies, and number of function evaluations.
Ansatz Module
- qlass.vqe.ansatz.Bitstring_initial_states(layers: int, n_states: int, lp: ndarray, pauli_string: str, cost: str = 'VQE', noise_model: NoiseModel | None = None) Processor | list[Processor][source]
Build a Bitstring-based variational ansatz using Qiskit’s
n_localcircuit, combined with initial reference states and compiled into Perceval processors.- Parameters:
layers (int) – Number of circuit layers (repetitions) in the ansatz.
n_states (int) – Number of states.
lp (np.ndarray) – Array of parameter values for the ansatz circuit.
pauli_string (str) – Pauli operator string defining the measurement basis.
cost (str, optional) –
- Type of cost function to prepare. One of:
"VQE": Return only the ground-state processor (default)"e-VQE": Return a list of processors for excited states
noise_model (NoiseModel, optional) – A Perceval
NoiseModelobject representing the noise model to include in compilation.
- Returns:
If
cost="VQE", returns a single PercevalProcessorinstance. Ifcost="e-VQE", returns a list of processors.- Return type:
Processor or list of Processor
- Raises:
ValueError – If
methodorcostarguments are invalid.
Notes
The ansatz is constructed by Bitstrings with a parameterized
n_localcircuit (Ry–CX entangling pattern).See https://scipost.org/SciPostPhys.14.3.055 for details on the DFT mapping.
- qlass.vqe.ansatz.CSF_initial_states(num_spatial_orbitals: int, num_electrons: tuple[int, int], initial_parameters: ndarray, pauli_string: str, singlet_excitation: bool = False, k_index: int | None = None, l_index: int | None = None, noise_model: NoiseModel | None = None) Processor | list[Processor][source]
Generate a Hartree-Fock initial state quantum circuit and optionally apply a singlet excitation.
This function constructs a Hartree-Fock initial state for a given number of electrons and spatial orbitals, applies a parameterized ansatz, and prepares the circuit for simulation on a quantum processor. Optionally, it can include a singlet excitation between specified orbitals.
- Parameters:
num_spatial_orbitals (int) – Number of spatial orbitals in the system.
num_electrons (list of int) – Number of alpha and beta electrons, given as [num_alpha, num_beta].
initial_parameters (np.ndarray) – Initial values for the parameterized ansatz.
pauli_string (str) – Pauli string used to rotate the qubits after the ansatz.
singlet_excitation (bool, optional) – If True, apply a singlet excitation to the Hartree-Fock state using the specified orbitals i and j. Default is False.
k_index (int or None, optional) – Index of the occupied orbital for singlet excitation. Required if singlet_excitation=True.
l_index (int or None, optional) – Index of the unoccupied orbital for singlet excitation. Required if singlet_excitation=True.
noise_model (NoiseModel or None, optional) – Optional noise model for simulating the quantum processor. Default is None.
- Returns:
If singlet_excitation=False, returns a single Processor object representing the Hartree-Fock initial state with the ansatz applied.
If singlet_excitation=True, returns a list [Processor_HF, Processor_SC] containing the Hartree-Fock processor and the singlet-excited processor.
- Return type:
Processor or list of Processor
- Raises:
ValueError – If singlet_excitation=True but either k or l is not provided.
Notes
The Hartree-Fock state is created by initializing qubits corresponding to spin orbitals.
Do not use tampered Hamiltonian on this function.
The ansatz used is a n_local circuit with ‘ry’ rotations and linear ‘cx’ entanglement.
The circuit is transpiled using basis gates [‘u3’, ‘cx’] and optimized to level 3.
The rotate_qubits function is applied to align with the specified Pauli string.
This function integrates with Perceval’s LogicalState and compile functions to produce a processor-ready quantum circuit.
- qlass.vqe.ansatz.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.vqe.ansatz.kerr_ansatz(params: ndarray, num_kerr: int = 4, n_max: int = 4) ndarray[source]
Construct a 2-mode nonlinear photonic ansatz with Kerr gates and a beamsplitter.
The circuit layout is:
- Mode 0: ── Gate_0 ──┐ ┌── Gate_2 ──
BS(θ, φ)
Mode 1: ── Gate_1 ──┘ └── Gate_3 ──
where each Gate slot is either a Kerr gate or a phase shifter, depending on
num_kerr. Whennum_kerr < 4, the last slots (3, 2, 1, …) are replaced by phase shifters.This ansatz operates directly in the truncated Fock basis (no dual-rail qubit encoding). It returns a unitary matrix of dimension (n_max+1)^2 acting on the 2-mode Fock space, intended for use with a bosonic Hamiltonian in a Fock-space VQE setting.
- Parameters:
params (np.ndarray) – Array of 6 variational parameters: - params[0..3]: gate parameters (Kerr κ or phase-shift φ) - params[4]: beamsplitter angle θ - params[5]: beamsplitter phase φ
num_kerr (int) – Number of Kerr gates to use (1–4). The remaining gate slots use phase shifters. Default is 4.
n_max (int) – Maximum photon number per mode (Fock space truncation). The single-mode Hilbert space has dimension n_max + 1. Default is 4.
- Returns:
- Unitary matrix of shape ((n_max+1)^2, (n_max+1)^2)
representing the full 2-mode circuit in Fock space.
- Return type:
np.ndarray
- Raises:
ValueError – If
num_kerris not in {1, 2, 3, 4} orparamsdoes not have exactly 6 elements.
- qlass.vqe.ansatz.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.vqe.ansatz.list_of_ones(computational_basis_state: int, n_qubits: int) list[int][source]
Return the indices of ones in the binary expansion of an integer, in big-endian order.
- Parameters:
computational_basis_state (int) – Integer representing the computational basis state.
n_qubits (int) – Total number of qubits (length of the binary string).
- Returns:
List of indices where the binary representation has ones. Indices are in big-endian order. For example, for n_qubits=6 and computational_basis_state=22 (binary 010110), the result is [1, 3, 4].
- Return type:
list of int
Notes
The output index ordering corresponds to the big-endian representation of the qubits.
Walter Kohn and Lu Jeu Sham. Self-consistent equations including exchange and correlation effects. Physical review, 140(4A):A1133, 1965.
Pieter Kok, William J Munro, Kae Nemoto, Timothy C Ralph, Jonathan P Dowling, and Gerard J Milburn. Linear optical quantum computing with photonic qubits. Reviews of Modern Physics, 79(1):135, 2007.
Ken M Nakanishi, Kosuke Mitarai, and Keisuke Fujii. Subspace-search variational quantum eigensolver for excited states. Physical Review Research, 1(3):033062, 2019.
Alberto Peruzzo, Jarrod McClean, Peter Shadbolt, Man-Hong Yung, Xiao-Qi Zhou, Peter J Love, Alán Aspuru-Guzik, and Jeremy L O’brien. A variational eigenvalue solver on a photonic quantum processor. Nature communications, 5(1):4213, 2014.