Quantum Many Body Model Class
High-level workflow class for building symmetry sectors, assembling Hamiltonians, diagonalizing/evolving them, and measuring observables.
- class edlgt.models.quantum_model.QuantumModel(lvals, has_obc, ham_format='sparse', basis_projector=None)[source]
Bases:
objectHigh-level container orchestrating model building and measurements.
Initialize a lattice quantum model container.
- Parameters:
lvals (
list) – Lattice dimensions.has_obc (
list) – Boundary-condition flags per axis (Truefor open boundaries).ham_format (
str, optional) – Preferred Hamiltonian representation (for example"sparse").basis_projector (
numpy.ndarray, optional) – Optional site-local projector used to reduce the effective local Hilbert space uniformly on all sites.
- default_params()[source]
Initialize default keyword arguments and the Hamiltonian container.
- Returns:
Updates
self.def_paramsand (when possible) createsself.H.- Return type:
- set_momentum_sector(k_unit_cell_size, k_vals, TC_symmetry=False)[source]
Build and store a momentum-sector projector.
- Parameters:
- Return type:
- Raises:
ValueError – If symmetry-sector configurations are missing, OBC are present, or the momentum shape is inconsistent with the lattice dimension.
- set_momentum_pair(k_left, k_right, k_unit_cell_size, TC_symmetry)[source]
Build two momentum projectors for rectangular
k_L-k_Rblocks.- Parameters:
- Return type:
Notes
This prepares rectangular projections of the form
P_kL^dagger O P_kRand stores them inself.momentum_basisin pair mode.
- check_momentum_pair()[source]
Validate orthonormality/orthogonality of the stored momentum pair basis.
- Return type:
- Raises:
ValueError – If either projector is not orthonormal or two distinct momentum sectors are not orthogonal.
- project_operators(ops_dict, bg_sector_list=None)[source]
Project local operators into the effective per-site basis.
- Parameters:
- Returns:
Stores projected operators in
self.opsand local dimensions inself.loc_dims.- Return type:
- get_abelian_symmetry_sector(global_ops, global_sectors=None, global_sym_type='U', link_ops=None, link_sectors=None, nbody_ops=None, nbody_sectors=None, nbody_sites_list=None, nbody_sym_type=None)[source]
Build symmetry-sector configurations from abelian constraints.
- Parameters:
global_ops (
listorNone) – Generators for global abelian symmetries.global_sectors (
listorNone, optional) – Target sectors for global symmetries.global_sym_type (
str, optional) – Global symmetry type flag passed to symmetry-sector routines.link_sectors (
listorNone, optional) – Target sectors for link symmetries.nbody_ops (
listorNone) – Optional n-body symmetry generators.nbody_sectors (
listorNone, optional) – Target sectors for n-body symmetries.nbody_sites_list (
object, optional) – Site patterns for n-body symmetries.nbody_sym_type (
strorNone, optional) – Symmetry type flag for n-body constraints.
Notes
The method supports pure global sectors, pure link sectors, mixed link-plus-nbody sectors, and pure n-body sectors.
- Returns:
Stores the resulting sector configurations in
self.sector_configs.- Return type:
- diagonalize_Hamiltonian(n_eigs, ham_format=None, print_results=False, **kwargs)[source]
Diagonalize the model Hamiltonian and cache energies/eigenstates.
Accepts the legacy
format=...keyword for backward compatibility.
- time_evolution_Hamiltonian(initial_state, time_line)[source]
Evolve an initial state with the current Hamiltonian.
- momentum_basis_projection(operator)[source]
Project an operator into the currently stored momentum basis.
- Parameters:
operator (
strornumpy.ndarrayorscipy.sparse.spmatrix) – Operator to project. If"H", projectsself.H.Hamin place.- Returns:
Projected operator. Returns
Nonewhen projecting"H"in place.- Return type:
- Raises:
ValueError – If no momentum basis has been set.
- build_subsystem_sector_embedding(indices)[source]
Embed a subsystem’s sector-RDM basis into its product basis.
The RDM of the sites
indiceslives in a sector-reduced basis: theDdistinct sub-configurations of those sites that occur inself.sector_configs(the rows ofunique_subsys_configs). This returns the(prod_dim, D)isometryVthat embeds that basis into the subsystem’s full computational product basis, withprod_dim = prod(loc_dims[indices]).Column
jofVis the product-basis unit vector at the mixed-radix index of thej-th reduced sub-config. HenceV.conj().T @ V == I_D(orthonormal columns) andV @ V.conj().Tprojects onto the sector-reachable subspace. Use it to pull an operator from the product basis into the reduced basis:V.conj().T @ op @ V.- Parameters:
indices (
list) – Subsystem site indices, assumed sorted ascending (to match the column order ofunique_subsys_configs).- Returns:
The
(prod_dim, D)embedding isometry.- Return type:
- build_projector_from_sector_to_fullspace(indices)
Embed a subsystem’s sector-RDM basis into its product basis.
The RDM of the sites
indiceslives in a sector-reduced basis: theDdistinct sub-configurations of those sites that occur inself.sector_configs(the rows ofunique_subsys_configs). This returns the(prod_dim, D)isometryVthat embeds that basis into the subsystem’s full computational product basis, withprod_dim = prod(loc_dims[indices]).Column
jofVis the product-basis unit vector at the mixed-radix index of thej-th reduced sub-config. HenceV.conj().T @ V == I_D(orthonormal columns) andV @ V.conj().Tprojects onto the sector-reachable subspace. Use it to pull an operator from the product basis into the reduced basis:V.conj().T @ op @ V.- Parameters:
indices (
list) – Subsystem site indices, assumed sorted ascending (to match the column order ofunique_subsys_configs).- Returns:
The
(prod_dim, D)embedding isometry.- Return type:
- get_qmb_state_from_configs(configs)[source]
Build an equal-weight state from explicit sector configurations.
- Parameters:
configs (
typing.Sequenceorlist) – Collection of basis configurations compatible withself.sector_configs.- Returns:
Normalized state vector in the symmetry-sector basis.
- Return type:
- Raises:
NotImplementedError – If a momentum sector is active.
ValueError – If one configuration is not compatible with the current symmetry sector.
- measure_fidelity(state, index, dynamics=False, print_value=False)[source]
Compute fidelity with an eigenstate or a time-evolved state.
- Parameters:
state (
numpy.ndarray) – Reference state vector.index (
int) – Index of the comparison state.dynamics (
bool, optional) – IfTrue, compare againstself.H.psi_time[index]instead ofself.H.Npsi[index].print_value (
bool, optional) – IfTrue, log the fidelity value.
- Returns:
Fidelity
|<ref|state>|^2.- Return type:
- static fermionic_antiflatness_from_eigvals(eigvals, k=2)[source]
Compute the fermionic antiflatness (FAF) from correlation-matrix eigenvalues.
- Parameters:
eigvals (
numpy.ndarray) – Eigenvaluesn_iof the Hermitian single-particle correlation matrixC(the occupations,n_iin[0, 1]). Values are clipped to[0, 1]to absorb small numerical leakage.k (
int, optional) – Antiflatness index, i.e. the power ofM^T M(k >= 1). Defaults to2, matching the Renyi-2 index used for the participation entropy (PE) and stabilizer Renyi entropy (SRE).
- Returns:
The fermionic antiflatness
F_k.- Return type:
- Raises:
ValueError – If
kis not a positive integer.
Notes
Implements Eq. (4) of arXiv:2506.00116,
F_k = N - tr[(M^T M)^k],with covariance matrix
M = 1 - 2 CandNthe number of fermionic modes (= n_sitesin the dressed-site construction, i.e. the dimension ofC). The eigenvalues ofMare1 - 2 n_iin[-1, 1](the signed Williamson eigenvalues), so in spectral formF_k = N - sum_i (1 - 2 n_i)^(2k),which is the quantity returned here.
F_k = 0for fermionic Gaussian states (n_iin{0, 1}, soM^T M = 1) and is maximal,F_k = N, for a fully depolarized correlator (n_i = 1/2,M = 0).The genuine covariance matrix is
M = 1 - 2 Cand notCitself: tracing(C^T C)^kwould not vanish on Gaussian states and would thus be inconsistent with the non-Gaussianity, which vanishes exactly whenn_iin{0, 1}. The eigenvaluesn_iare the same as those used bymeasure_fermionic_nongaussianity(), see alsoget_fermionic_string_correlator().
- measure_fermionic_antiflatness(state=None, state_index=None, dynamics=False, k=2, eigvals=None, print_value=True, eig_tol=1e-10)[source]
Measure the fermionic antiflatness (FAF) from the string correlator.
- Parameters:
state (
numpy.ndarray, optional) – Explicit state vector to measure. Forwarded toget_fermionic_string_correlator()and ignored wheneigvalsis supplied.state_index (
int, optional) – Index of an eigenstate or time-evolved state to measure. Forwarded toget_fermionic_string_correlator()and ignored wheneigvalsis supplied.dynamics (
bool, optional) – IfTrue, select the state from the time-evolved set rather than the eigenstates. Ignored wheneigvalsis supplied.k (
int, optional) – Antiflatness index, i.e. the power ofM^T M(k >= 1). Defaults to2, matching the Renyi-2 index used for PE and SRE.eigvals (
numpy.ndarray, optional) – Pre-computed eigenvalues of the Hermitian correlation matrix (occupationsn_i). When supplied, the string correlator is not recomputed, which allows reusing the eigenvalues returned bymeasure_fermionic_nongaussianity().print_value (
bool, optional) – IfTrue, log the FAF value.eig_tol (
float, optional) – Tolerance used to flag eigenvalues leaking outside[0, 1].
- Returns:
faf_value (
float) – The fermionic antiflatnessF_k.eigvals (
numpy.ndarray) – The real, unclipped eigenvalues of the correlation matrix.
Notes
FAF is a measure of fermionic magic resources (non-Gaussianity) built from the same gauge-invariant single-particle correlation matrix
Cas the non-Gaussianity. It implements Eq. (4) of arXiv:2506.00116,F_k = N - tr[(M^T M)^k], with covariance matrixM = 1 - 2 CandNthe number of fermionic modes (= n_sites). The pure formula is evaluated byfermionic_antiflatness_from_eigvals(). Results are stored inself.res["fermionic_antiflatness"]andself.res["fermionic_string_correlator_eigvals"]. See alsomeasure_fermionic_nongaussianity()andget_fermionic_string_correlator().
- get_thermal_beta(state, threshold)[source]
Estimate an effective thermal
betafor a reference state.
- canonical_avg(local_obs, beta)[source]
Compute the canonical-ensemble average of a local observable.
- microcanonical_avg(local_obs_list, state, special_norms=None, staggered_avgs=None)[source]
Compute microcanonical averages for multiple local observables.
The energy shell is defined using the energy density of the reference state and its uncertainty:
e_q = <H> / Ldelta_e = sqrt(<H^2> - <H>^2) / L
All eigenstates satisfying
abs(e_i - e_q) < delta_eare included. For each observable inlocal_obs_list, the expectation value is measured on every state in the shell and then averaged.- Parameters:
local_obs_list (
list) – Keys of local observables. Each key must be present inself.ops.state (
numpy.ndarray) – Reference state vector used to define the energy shell.special_norms (
dict, optional) – Optional mapping from observable key to a custom normalization array.staggered_avgs (
dict, optional) – Optional mapping from observable key to a staggered-averaging label or rule used by the local observable measurement.
- Returns:
(psi_thermal, ME_avg)wherepsi_thermalis the normalized coherent superposition of shell eigenstates andME_avgis a dictionary mapping observable names to microcanonical averages.- Return type:
- diagonal_avg(local_obs_list, state, special_norms=None, staggered_avgs=None, tol_deg=1e-10)[source]
Compute diagonal-ensemble averages for several local observables.
- Parameters:
local_obs_list (
list) – Observable keys inself.ops.state (
numpy.ndarray) – Reference state used to compute diagonal weights.special_norms (
dict, optional) – Optional observable-specific normalization arrays.staggered_avgs (
dict, optional) – Optional observable-specific staggered averaging labels.tol_deg (
float, optional) – Tolerance used to group degenerate eigenvalues into blocks.
- Returns:
Dictionary of diagonal-ensemble averages keyed as
DE_<obs>.- Return type:
- get_observables(local_obs=[], twobody_obs=[], plaquette_obs=[], nbody_obs=[], nbody_dist=[], twobody_axes=None)[source]
Instantiate observable objects and cache them in
self.obs_list.- Parameters:
local_obs (
list, optional) – Names of local observables.twobody_obs (
list, optional) – List of two-body operator-name pairs.plaquette_obs (
list, optional) – List of plaquette operator-name lists.nbody_obs (
list, optional) – List of n-body operator-name lists.nbody_dist (
list, optional) – Relative distances for each n-body observable.twobody_axes (
list, optional) – Axis labels for each two-body observable.
- Return type:
- measure_observables(index, dynamics=False)[source]
Measure all observables stored in
self.obs_liston one state.
- directed_link_observable(obs_name)[source]
Return positive-link observable arrays for each lattice direction.
obs_nameis the base name, for example"E","E2", or"T2". The method reads measured dressed-site observables namedf"{obs_name}_p<axis>"fromself.resand returns a list[O_x, O_y, O_z]truncated only on open boundaries along the corresponding positive-link direction.
- stag_avg(obs_name, staggered_avg=None)[source]
Average a measured local observable on all, even, or odd sites.
- Parameters:
- Returns:
Requested average value.
- Return type:
- Raises:
KeyError – If
obs_nameis not present inself.res.