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: object

High-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 (True for 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_params and (when possible) creates self.H.

Return type:

None

set_momentum_sector(k_unit_cell_size, k_vals, TC_symmetry=False)[source]

Build and store a momentum-sector projector.

Parameters:
  • k_unit_cell_size (list) – Translation unit-cell size used to define momentum sectors.

  • k_vals (list) – Target momentum quantum numbers (one per lattice dimension).

  • TC_symmetry (bool, optional) – Whether to include translation-charge symmetry reduction in the momentum basis construction.

Return type:

None

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_R blocks.

Parameters:
  • k_left (list) – Left and right momentum quantum numbers.

  • k_right (list) – Left and right momentum quantum numbers.

  • k_unit_cell_size (list) – Translation unit-cell size.

  • TC_symmetry (bool) – Whether to include translation-charge symmetry reduction.

Return type:

None

Notes

This prepares rectangular projections of the form P_kL^dagger O P_kR and stores them in self.momentum_basis in pair mode.

check_momentum_pair()[source]

Validate orthonormality/orthogonality of the stored momentum pair basis.

Return type:

None

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:
  • ops_dict (dict) – Dictionary of bare local operators.

  • bg_sector_list (list, optional) – Optional per-site background-sector labels used to restrict the gauge-invariant basis on each site.

Returns:

Stores projected operators in self.ops and local dimensions in self.loc_dims.

Return type:

None

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 (list or None) – Generators for global abelian symmetries.

  • global_sectors (list or None, optional) – Target sectors for global symmetries.

  • global_sym_type (str, optional) – Global symmetry type flag passed to symmetry-sector routines.

  • link_ops (list or None) – Link-symmetry generators.

  • link_sectors (list or None, optional) – Target sectors for link symmetries.

  • nbody_ops (list or None) – Optional n-body symmetry generators.

  • nbody_sectors (list or None, optional) – Target sectors for n-body symmetries.

  • nbody_sites_list (object, optional) – Site patterns for n-body symmetries.

  • nbody_sym_type (str or None, 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:

None

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 (str or numpy.ndarray or scipy.sparse.spmatrix) – Operator to project. If "H", projects self.H.Ham in place.

Returns:

Projected operator. Returns None when projecting "H" in place.

Return type:

scipy.sparse.csr_matrix or None

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 indices lives in a sector-reduced basis: the D distinct sub-configurations of those sites that occur in self.sector_configs (the rows of unique_subsys_configs). This returns the (prod_dim, D) isometry V that embeds that basis into the subsystem’s full computational product basis, with prod_dim = prod(loc_dims[indices]).

Column j of V is the product-basis unit vector at the mixed-radix index of the j-th reduced sub-config. Hence V.conj().T @ V == I_D (orthonormal columns) and V @ V.conj().T projects 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 of unique_subsys_configs).

Returns:

The (prod_dim, D) embedding isometry.

Return type:

scipy.sparse.csc_matrix

build_projector_from_sector_to_fullspace(indices)

Embed a subsystem’s sector-RDM basis into its product basis.

The RDM of the sites indices lives in a sector-reduced basis: the D distinct sub-configurations of those sites that occur in self.sector_configs (the rows of unique_subsys_configs). This returns the (prod_dim, D) isometry V that embeds that basis into the subsystem’s full computational product basis, with prod_dim = prod(loc_dims[indices]).

Column j of V is the product-basis unit vector at the mixed-radix index of the j-th reduced sub-config. Hence V.conj().T @ V == I_D (orthonormal columns) and V @ V.conj().T projects 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 of unique_subsys_configs).

Returns:

The (prod_dim, D) embedding isometry.

Return type:

scipy.sparse.csc_matrix

get_qmb_state_from_configs(configs)[source]

Build an equal-weight state from explicit sector configurations.

Parameters:

configs (typing.Sequence or list) – Collection of basis configurations compatible with self.sector_configs.

Returns:

Normalized state vector in the symmetry-sector basis.

Return type:

numpy.ndarray

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) – If True, compare against self.H.psi_time[index] instead of self.H.Npsi[index].

  • print_value (bool, optional) – If True, log the fidelity value.

Returns:

Fidelity |<ref|state>|^2.

Return type:

float

static fermionic_antiflatness_from_eigvals(eigvals, k=2)[source]

Compute the fermionic antiflatness (FAF) from correlation-matrix eigenvalues.

Parameters:
  • eigvals (numpy.ndarray) – Eigenvalues n_i of the Hermitian single-particle correlation matrix C (the occupations, n_i in [0, 1]). Values are clipped to [0, 1] to absorb small numerical leakage.

  • k (int, optional) – Antiflatness index, i.e. the power of M^T M (k >= 1). Defaults to 2, matching the Renyi-2 index used for the participation entropy (PE) and stabilizer Renyi entropy (SRE).

Returns:

The fermionic antiflatness F_k.

Return type:

float

Raises:

ValueError – If k is 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 C and N the number of fermionic modes (= n_sites in the dressed-site construction, i.e. the dimension of C). The eigenvalues of M are 1 - 2 n_i in [-1, 1] (the signed Williamson eigenvalues), so in spectral form

F_k = N - sum_i (1 - 2 n_i)^(2k),

which is the quantity returned here. F_k = 0 for fermionic Gaussian states (n_i in {0, 1}, so M^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 C and not C itself: tracing (C^T C)^k would not vanish on Gaussian states and would thus be inconsistent with the non-Gaussianity, which vanishes exactly when n_i in {0, 1}. The eigenvalues n_i are the same as those used by measure_fermionic_nongaussianity(), see also get_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 to get_fermionic_string_correlator() and ignored when eigvals is supplied.

  • state_index (int, optional) – Index of an eigenstate or time-evolved state to measure. Forwarded to get_fermionic_string_correlator() and ignored when eigvals is supplied.

  • dynamics (bool, optional) – If True, select the state from the time-evolved set rather than the eigenstates. Ignored when eigvals is supplied.

  • k (int, optional) – Antiflatness index, i.e. the power of M^T M (k >= 1). Defaults to 2, matching the Renyi-2 index used for PE and SRE.

  • eigvals (numpy.ndarray, optional) – Pre-computed eigenvalues of the Hermitian correlation matrix (occupations n_i). When supplied, the string correlator is not recomputed, which allows reusing the eigenvalues returned by measure_fermionic_nongaussianity().

  • print_value (bool, optional) – If True, log the FAF value.

  • eig_tol (float, optional) – Tolerance used to flag eigenvalues leaking outside [0, 1].

Returns:

  • faf_value (float) – The fermionic antiflatness F_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 C as the non-Gaussianity. It implements Eq. (4) of arXiv:2506.00116, F_k = N - tr[(M^T M)^k], with covariance matrix M = 1 - 2 C and N the number of fermionic modes (= n_sites). The pure formula is evaluated by fermionic_antiflatness_from_eigvals(). Results are stored in self.res["fermionic_antiflatness"] and self.res["fermionic_string_correlator_eigvals"]. See also measure_fermionic_nongaussianity() and get_fermionic_string_correlator().

compute_expH(beta)[source]

Return exp(-beta H) as a sparse CSC matrix.

get_thermal_beta(state, threshold)[source]

Estimate an effective thermal beta for a reference state.

canonical_avg(local_obs, beta)[source]

Compute the canonical-ensemble average of a local observable.

Parameters:
  • local_obs (str) – Observable key in self.ops.

  • beta (float) – Inverse temperature.

Returns:

Canonical average per lattice site.

Return type:

float

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> / L

  • delta_e = sqrt(<H^2> - <H>^2) / L

All eigenstates satisfying abs(e_i - e_q) < delta_e are included. For each observable in local_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 in self.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) where psi_thermal is the normalized coherent superposition of shell eigenstates and ME_avg is a dictionary mapping observable names to microcanonical averages.

Return type:

tuple

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 in self.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:

dict

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:

None

measure_observables(index, dynamics=False)[source]

Measure all observables stored in self.obs_list on one state.

Parameters:
  • index (int) – Eigenstate or time-step index.

  • dynamics (bool, optional) – If True, measure on self.H.psi_time[index].

Returns:

Results are stored in self.res.

Return type:

None

Average a directional link observable over all valid lattice links.

Parameters:

obs_name (str) – Base observable name. Directional components are expected in self.res as f"{obs_name}_p<dir>".

Returns:

Average over all valid directed links.

Return type:

float

Return the positive-link array shape along one lattice axis.

Return positive-link array shapes in x, y, z order.

Return positive-link observable arrays for each lattice direction.

obs_name is the base name, for example "E", "E2", or "T2". The method reads measured dressed-site observables named f"{obs_name}_p<axis>" from self.res and 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:
  • obs_name (str) – Observable key already stored in self.res as a site-resolved array.

  • staggered_avg (str or None, optional) – None for the full average, or "even" / "odd" for a staggered sublattice average.

Returns:

Requested average value.

Return type:

float

Raises:

KeyError – If obs_name is not present in self.res.

configure_dtype_mode(dtype_mode='auto', auto_mode='complex')[source]

Apply the global numeric dtype mode for Hamiltonian/operator assembly.

Parameters:
  • dtype_mode (str or bool, optional) – Explicit mode ("real"/"complex" or bool) or "auto".

  • auto_mode (str or bool, optional) – Fallback mode used when dtype_mode == "auto".

Returns:

Applied normalized mode ("real" or "complex").

Return type:

str