Algorithms¶
DMRG¶
- class tenax.algorithms.dmrg.DMRGConfig(max_bond_dim=100, num_sweeps=10, convergence_tol=1e-10, num_states=1, two_site=True, lanczos_max_iter=50, lanczos_tol=1e-12, noise=0.0, svd_trunc_err=None, verbose=False)[source]
Bases:
objectConfiguration for a DMRG run.
- Parameters:
- max_bond_dim
Maximum allowed bond dimension (chi).
- num_sweeps
Number of full left-right sweep cycles.
- convergence_tol
Energy convergence threshold to stop early.
- num_states
Number of lowest eigenstates to target (1 = ground state).
- two_site
If True, use 2-site DMRG (allows bond dim growth). If False, use 1-site DMRG (conserves bond dim exactly).
- lanczos_max_iter
Maximum Lanczos iterations for eigenvalue solve.
- lanczos_tol
Convergence tolerance for Lanczos.
- noise
Perturbative noise added to density matrix (helps escape local minima in 2-site DMRG).
- svd_trunc_err
Maximum truncation error per SVD (overrides max_bond_dim when set and more restrictive).
- verbose
Print energy at each sweep.
- max_bond_dim: int = 100
- num_sweeps: int = 10
- convergence_tol: float = 1e-10
- num_states: int = 1
- two_site: bool = True
- lanczos_max_iter: int = 50
- lanczos_tol: float = 1e-12
- noise: float = 0.0
- verbose: bool = False
- class tenax.algorithms.dmrg.DMRGResult(energy, energies_per_sweep, mps, truncation_errors, converged)[source]
Bases:
NamedTupleResult of a DMRG run.
- Parameters:
- energy
Final ground state energy.
- energies_per_sweep
Energy at the end of each sweep.
- mps
TensorNetwork representing the optimized MPS.
- truncation_errors
List of truncation errors at each bond update step.
- converged
True if energy converged within convergence_tol.
- energy: float
Alias for field number 0
- mps: TensorNetwork
Alias for field number 2
- converged: bool
Alias for field number 4
- tenax.algorithms.dmrg.dmrg(hamiltonian, initial_mps, config)[source]¶
Run DMRG to find the ground state of a 1D Hamiltonian given as MPO.
The Hamiltonian must be provided as an MPO (Matrix Product Operator) TensorNetwork with L site tensors connected by virtual bonds.
- Parameters:
hamiltonian (
TensorNetwork) – MPO representation of the Hamiltonian.initial_mps (
TensorNetwork) – Starting MPS TensorNetwork (modified in-place conceptually; the result MPS is returned in DMRGResult).config (
DMRGConfig) – DMRGConfig parameters.
- Return type:
DMRGResult- Returns:
DMRGResult with energy, sweep history, optimized MPS, and diagnostics.
- tenax.algorithms.dmrg.build_mpo_heisenberg(L, Jz=1.0, Jxy=1.0, hz=0.0, dtype=<class 'jax.numpy.float64'>)[source]¶
Build the MPO for the spin-1/2 XXZ Heisenberg chain.
- H = Jz * sum_i Sz_i Sz_{i+1} + Jxy/2 * sum_i (S+_i S-_{i+1} + S-_i S+_{i+1})
hz * sum_i Sz_i
The MPO is constructed using the standard 5x5 MPO representation with bond dimension 5 (I, S+, S-, Sz, I boundaries).
- Parameters:
- Return type:
- Returns:
TensorNetwork representing the MPO with L site tensors connected by virtual bonds. Each site tensor has legs: (“w{i-1}_{i}”, “mpo_top_{i}”, “mpo_bot_{i}”, “w{i}_{i+1}”) Boundary sites have only 3 legs (one virtual bond removed).
iDMRG¶
- class tenax.algorithms.idmrg.iDMRGConfig(max_bond_dim=100, max_iterations=200, convergence_tol=1e-08, lanczos_max_iter=50, lanczos_tol=1e-12, svd_trunc_err=None, verbose=False)[source]
Bases:
objectConfiguration for an iDMRG run.
- Parameters:
- max_bond_dim
Maximum allowed bond dimension (chi).
- max_iterations
Maximum number of 2-site growth steps.
- convergence_tol
Convergence threshold on energy per site.
- lanczos_max_iter
Maximum Lanczos iterations.
- lanczos_tol
Lanczos convergence tolerance.
- svd_trunc_err
Maximum SVD truncation error (None = use max_bond_dim).
- verbose
Print per-step diagnostics.
- max_bond_dim: int = 100
- max_iterations: int = 200
- convergence_tol: float = 1e-08
- lanczos_max_iter: int = 50
- lanczos_tol: float = 1e-12
- verbose: bool = False
- class tenax.algorithms.idmrg.iDMRGResult(energy_per_site, energies_per_step, mps_tensors, singular_values, converged)[source]
Bases:
NamedTupleResult of an iDMRG run.
- Parameters:
- energy_per_site
Converged energy per site.
- energies_per_step
Energy-per-site estimate at each iteration.
- mps_tensors
2-site unit cell
[A_L, A_R]asTensor.
- singular_values
Singular values on the centre bond.
- converged
True if the run converged within tolerance.
- energy_per_site: float
Alias for field number 0
- mps_tensors: list[Tensor]
Alias for field number 2
- singular_values: Array
Alias for field number 3
- converged: bool
Alias for field number 4
- tenax.algorithms.idmrg.idmrg(bulk_mpo, config=None, d=2, dtype=<class 'jax.numpy.float64'>)[source]¶
Run infinite DMRG to find the ground-state energy per site.
- Parameters:
bulk_mpo (
DenseTensor) – Bulk MPO tensor (D_w, d, d, D_w) as aDenseTensor.config (
iDMRGConfig|None) – iDMRG configuration. Uses defaults if None.d (
int) – Physical dimension.dtype (
Any) – JAX dtype for computation.
- Return type:
iDMRGResult- Returns:
iDMRGResultwith energy per site and diagnostic information.
- tenax.algorithms.idmrg.build_bulk_mpo_heisenberg(Jz=1.0, Jxy=1.0, hz=0.0, d=2, dtype=<class 'jax.numpy.float64'>)[source]¶
Build a single bulk W-matrix for the spin-1/2 XXZ Heisenberg model.
The returned tensor is the 5×d×d×5 MPO site tensor that is repeated at every site of an infinite chain.
- Parameters:
- Return type:
- Returns:
DenseTensorwith legs("w_l", "mpo_top", "mpo_bot", "w_r").
- tenax.algorithms.idmrg.build_bulk_mpo_heisenberg_cylinder(Ly, J=1.0, dtype=<class 'jax.numpy.float64'>)[source]¶
Build a bulk W-matrix for the Heisenberg model on an infinite cylinder.
Each “super-site” represents an entire ring of
Lyspins (physical dimensiond = 2**Ly). Within-ring Heisenberg bonds (periodic in y) become an on-site term, and between-ring bonds become nearest-neighbour MPO interactions.The resulting MPO tensor can be passed directly to
idmrg().- Parameters:
- Return type:
- Returns:
DenseTensorwith legs("w_l", "mpo_top", "mpo_bot", "w_r")and shape(D_w, d, d, D_w)whereD_w = 3*Ly + 2,d = 2**Ly.
TRG¶
- class tenax.algorithms.trg.TRGConfig(max_bond_dim=16, num_steps=10, svd_trunc_err=None)[source]
Bases:
objectConfiguration for TRG coarse-graining.
- max_bond_dim
Maximum bond dimension chi after each coarse-graining step.
- num_steps
Number of coarse-graining iterations (number of times lattice size is halved).
- svd_trunc_err
Optional maximum truncation error per SVD step. If set and more restrictive than max_bond_dim, takes precedence.
- max_bond_dim: int = 16
- num_steps: int = 10
- tenax.algorithms.trg.trg(tensor, config)[source]¶
TRG coarse-graining for a 2D square lattice partition function.
The input tensor
T_{u,d,l,r}(up, down, left, right legs) represents a single site tensor placed on every site of an infinite 2D square lattice. TRG iteratively coarse-grains the lattice by SVD splitting into half-tensors, then contracting four half-tensors around a plaquette to form the new coarse tensor.The partition function estimate is tracked via log normalization:
log(Z)/N = sum_steps log(norm_step) / 2^step.- Parameters:
tensor (
Tensor) – Initial site tensor, a DenseTensor with 4 legs labeled (“up”, “down”, “left”, “right”) or shape (d, d, d, d).config (
TRGConfig) – TRGConfig parameters.
- Return type:
- Returns:
Scalar JAX array – estimated log(Z)/N (free energy per site up to sign).
- tenax.algorithms.trg.compute_ising_tensor(beta, J=1.0)[source]¶
Build the initial transfer matrix tensor for the 2D Ising model.
Constructs the local tensor T_{udlr} for the partition function Z = Tr prod T_{s_i s_j s_k s_l} where the trace is over all spin configs.
The tensor is derived from the Boltzmann weight T_{udlr} = sum_{s} sqrt(Q_{u,s}) sqrt(Q_{d,s}) sqrt(Q_{l,s}) sqrt(Q_{r,s}) where Q_{a,b} = exp(beta*J*s_a*s_b) / 2 and s ∈ {-1, +1} (or {0, 1}).
- Parameters:
- Return type:
- Returns:
DenseTensor of shape (2, 2, 2, 2) with legs (“up”, “down”, “left”, “right”).
Note
At the 2D Ising critical temperature, beta_c = ln(1 + sqrt(2)) / (2*J) ≈ 0.4407 / J, TRG should reproduce the Onsager exact free energy.
- tenax.algorithms.trg.ising_free_energy_exact(beta, J=1.0)[source]¶
Compute the exact 2D Ising free energy per site via Onsager’s formula.
The exact result for ln(Z)/N on the square lattice is:
- ln(Z)/N = ln(2) + (1/(2*pi^2)) * int_0^pi int_0^pi
ln(cosh^2(2K) - sinh(2K)*(cos t1 + cos t2)) dt1 dt2
where K = beta*J. The inner integral over t2 is evaluated analytically via int_0^pi ln(A - B*cos(t)) dt = pi*ln((A + sqrt(A^2-B^2))/2), reducing to a single integral over t1.
Reference: Onsager, Phys. Rev. 65, 117 (1944).
HOTRG¶
- class tenax.algorithms.hotrg.HOTRGConfig(max_bond_dim=16, num_steps=10, direction_order='alternating', svd_trunc_err=None)[source]
Bases:
objectConfiguration for HOTRG coarse-graining.
- max_bond_dim
Maximum bond dimension chi after each coarse-graining step.
- num_steps
Number of coarse-graining iterations.
- direction_order
Order of coarse-graining directions. “alternating”: alternate horizontal/vertical (default). “horizontal”: horizontal only. “vertical”: vertical only.
- svd_trunc_err
Optional maximum truncation error per HOSVD.
- max_bond_dim: int = 16
- num_steps: int = 10
- direction_order: str = 'alternating'
- tenax.algorithms.hotrg.hotrg(tensor, config)[source]¶
HOTRG coarse-graining for a 2D square lattice partition function.
Uses Higher-Order SVD (HOSVD) for computing truncation isometries, providing better accuracy than TRG at the same bond dimension.
- Parameters:
tensor (
Tensor) – Initial site tensor with 4 legs (up, down, left, right). Can be a DenseTensor or raw tensor-like with shape (d,d,d,d).config (
HOTRGConfig) – HOTRGConfig parameters.
- Return type:
- Returns:
Scalar JAX array – estimated log(Z)/N (free energy per site).
iPEPS¶
- class tenax.algorithms.ipeps.iPEPSConfig(max_bond_dim=2, num_imaginary_steps=100, dt=0.01, ctm=<factory>, svd_trunc_err=None, gate_order='sequential', unit_cell='1x1', gs_optimizer='adam', gs_learning_rate=0.001, gs_num_steps=200, gs_conv_tol=1e-08, su_init=False)[source]
Bases:
objectConfiguration for iPEPS simple update optimization.
- Parameters:
- max_bond_dim
PEPS virtual bond dimension D.
- num_imaginary_steps
Number of imaginary time evolution steps.
- dt
Imaginary time step size.
- ctm
CTM configuration for environment computation.
- svd_trunc_err
SVD truncation error for simple update.
- gate_order
Order of bond updates: “sequential” or “random”.
- su_init
If True,
optimize_gs_adinitializes the site tensor via simple update (ipeps()) instead of random initialization. Ignored whenA_initis provided explicitly.
- max_bond_dim: int = 2
- num_imaginary_steps: int = 100
- dt: float = 0.01
- ctm: CTMConfig
- gate_order: str = 'sequential'
- unit_cell: str = '1x1'
- gs_optimizer: str = 'adam'
- gs_learning_rate: float = 0.001
- gs_num_steps: int = 200
- gs_conv_tol: float = 1e-08
- su_init: bool = False
- class tenax.algorithms.ipeps.CTMConfig(chi=20, max_iter=100, conv_tol=1e-08, renormalize=True)[source]
Bases:
objectConfiguration for CTM environment computation.
- chi
Bond dimension of CTM environment tensors.
- max_iter
Maximum CTM iterations before declaring convergence.
- conv_tol
Convergence tolerance (based on singular value change between CTM iterations).
- renormalize
Whether to renormalize environment tensors at each step to prevent exponential growth (always recommended).
- chi: int = 20
- max_iter: int = 100
- conv_tol: float = 1e-08
- renormalize: bool = True
- class tenax.algorithms.ipeps.CTMEnvironment(C1, C2, C3, C4, T1, T2, T3, T4)[source]
Bases:
NamedTupleThe 8 CTM environment tensors (4 corners + 4 edge tensors).
- Corner convention (looking at a single site):
C1 — T1 — C2 | | T4 [A] T2 | | C4 — T3 — C3
- Corners (chi x chi tensors):
C1: top-left C2: top-right C3: bottom-right C4: bottom-left
- Edges (chi x D^2 x chi tensors, where D = PEPS bond dim):
T1: top T2: right T3: bottom T4: left
All shapes use chi for environment bonds, D^2 for the PEPS bond (physical space of the doubled layer A * A^* is D^2 = D*D).
- C1: Array
Alias for field number 0
- C2: Array
Alias for field number 1
- C3: Array
Alias for field number 2
- C4: Array
Alias for field number 3
- T1: Array
Alias for field number 4
- T2: Array
Alias for field number 5
- T3: Array
Alias for field number 6
- T4: Array
Alias for field number 7
- tenax.algorithms.ipeps.ipeps(hamiltonian_gate, initial_peps, config)[source]¶
Run iPEPS simple update + CTM for a 2D quantum lattice model.
Algorithm overview:
Simple update (imaginary time evolution) – apply
exp(-dt * H_bond)on each bond, SVD-truncate to D, update lambda matrices.CTM environment computation – initialise and iteratively absorb rows/columns until convergence.
Compute energy per site using the CTM environment.
- Parameters:
hamiltonian_gate (
Array) – The 2-site Hamiltonian as a 4-leg tensor of shape (d, d, d, d) representing H on a bond.initial_peps (
TensorNetwork|Array|KeyPath[Array,Array] |None) – TensorNetwork, raw JAX array, or tuple of two JAX arrays(A, B)for the 2-site unit cell.Nonefor random initialization.config (
iPEPSConfig) – iPEPSConfig.
- Return type:
KeyPath[float,TensorNetwork,CTMEnvironment|KeyPath[CTMEnvironment,CTMEnvironment]]- Returns:
(energy_per_site, optimized_peps, ctm_environment)
- tenax.algorithms.ipeps.ctm(A, config, initial_env=None)[source]¶
Compute CTM environment for a PEPS with 1x1 unit cell.
Runs the CTM algorithm (Corboz/Orús scheme) until convergence. The input A is the double-layer tensor A * A^* combined, or the single-layer A from which the doubled tensor is computed.
The iteration loop uses
jax.lax.while_loopso that the entire convergence procedure can be JIT-compiled without host sync.
- tenax.algorithms.ipeps.ctm_2site(A, B, config)[source]¶
Compute CTM environments for a 2-site checkerboard unit cell.
On a checkerboard, all neighbors of A are B and vice versa. Each absorption move for env_A uses B’s double-layer tensor and T’s from env_B, and vice versa.
The iteration loop uses
jax.lax.while_loopso that the entire convergence procedure can be JIT-compiled without host sync.- Parameters:
- Return type:
KeyPath[CTMEnvironment,CTMEnvironment]- Returns:
(env_A, env_B) — converged CTM environments for each sublattice.
- tenax.algorithms.ipeps.compute_energy_ctm_2site(A, B, env_A, env_B, hamiltonian_gate, d)[source]¶
Compute energy per site for a 2-site checkerboard iPEPS.
E/site = E_horizontal + E_vertical (one bond of each type per site).
- tenax.algorithms.ipeps.optimize_gs_ad(hamiltonian_gate, A_init, config)[source]¶
AD-based ground state optimization of iPEPS.
Uses automatic differentiation through the CTM fixed-point equation (Francuz et al. PRR 7, 013237) to compute exact gradients of the energy with respect to the site tensor A, then optimizes with optax.
- Parameters:
hamiltonian_gate (
Array) – 2-site Hamiltonian of shape(d, d, d, d).A_init (
Array|None) – Initial site tensor(D, D, D, D, d), or None for random initialization. WhenNoneandconfig.su_initisTrue, the tensor is initialized via simple update (ipeps()).config (
iPEPSConfig) – iPEPSConfig with AD optimization settings.
- Return type:
- Returns:
(A_opt, env, E_gs)— optimized tensor, CTM environment, and ground state energy per site.
AD Utilities¶
- tenax.algorithms.ad_utils.truncated_svd_ad(M, chi)[source]¶
Truncated SVD with correct and stable backward pass.
Forward: standard SVD truncated to chi singular values. Backward: Lorentzian-regularized F-matrix + truncation correction.
iPEPS Excitations¶
- class tenax.algorithms.ipeps_excitations.ExcitationConfig(chi=20, ctm_max_iter=100, ctm_conv_tol=1e-08, num_excitations=3, null_space_tol=0.001)[source]
Bases:
objectConfiguration for iPEPS excitation calculation.
- Parameters:
- chi
CTM bond dimension.
- ctm_max_iter
Maximum CTM iterations.
- ctm_conv_tol
CTM convergence tolerance.
- num_excitations
Number of lowest excitation energies to return.
- null_space_tol
Threshold for filtering null-space of the norm matrix (eigenvalues below this fraction of the maximum are discarded).
- chi: int = 20
- ctm_max_iter: int = 100
- ctm_conv_tol: float = 1e-08
- num_excitations: int = 3
- null_space_tol: float = 0.001
- class tenax.algorithms.ipeps_excitations.ExcitationResult(energies, momenta, ground_state_energy)[source]
Bases:
objectResult of an iPEPS excitation calculation.
- energies
Excitation energies of shape
(num_k, num_excitations).
- momenta
Momentum points
(num_k, 2).
- ground_state_energy
Ground state energy per site.
- energies: ndarray
- momenta: ndarray
- ground_state_energy: float
- tenax.algorithms.ipeps_excitations.compute_excitations(A, env, hamiltonian_gate, E_gs, momenta, config)[source]¶
Compute excitation spectrum at given momentum points.
For each momentum point, constructs the effective Hamiltonian and norm matrices using AD (Ponsioen et al. 2022), then solves the generalized eigenvalue problem for the lowest excitation energies.
- Parameters:
A (
Array) – Optimized ground state tensor(D, D, D, D, d).env (
CTMEnvironment) – Converged CTM environment for A.hamiltonian_gate (
Array) – 2-site Hamiltonian(d, d, d, d).E_gs (
float) – Ground state energy per site.momenta (
list[KeyPath[float,float]]) – List of(kx, ky)momentum points.config (
ExcitationConfig) – ExcitationConfig.
- Return type:
ExcitationResult- Returns:
ExcitationResult with energies and momenta.
- tenax.algorithms.ipeps_excitations.make_momentum_path(path_type='brillouin', num_points=20)[source]¶
Generate momentum path through the Brillouin zone.
For a square lattice with lattice constant 1:
path_type="brillouin":\(\Gamma(0,0) \to X(\pi,0) \to M(\pi,\pi) \to \Gamma(0,0)\)
path_type="diagonal":\(\Gamma(0,0) \to M(\pi,\pi)\)
AutoMPO¶
- class tenax.algorithms.auto_mpo.AutoMPO(L, d=2, site_ops=None)[source]¶
Bases:
objectSymbolic Hamiltonian builder that produces an MPO TensorNetwork.
Operator names are resolved against a
site_opsdictionary; the defaults arespin_half_ops()ford=2andspin_one_ops()ford=3.Example:
auto = AutoMPO(L=6) for i in range(5): auto += (1.0, "Sz", i, "Sz", i + 1) auto += (0.5, "Sp", i, "Sm", i + 1) auto += (0.5, "Sm", i, "Sp", i + 1) mpo = auto.to_mpo() result = dmrg(mpo, mps, config)
The resulting MPO is directly compatible with
dmrg().- add_term(coeff, *args)[source]¶
Add one term to the Hamiltonian.
- Parameters:
- Return type:
Example:
auto.add_term(0.5, "Sp", 0, "Sm", 1) auto.add_term(1.0, "Sz", 0, "Sz", 1, "Sz", 2) # 3-body term
- to_mpo(compress=False, compress_tol=1e-12, dtype=<class 'jax.numpy.float64'>, symmetric=False, phys_charges=None)[source]¶
Build and return the MPO as a TensorNetwork.
- Parameters:
compress (
bool) – Apply a left-to-right SVD compression pass to reduce bond dimension (approximate; not globally optimal but useful for long-range interactions).compress_tol (
float) – Relative singular-value threshold for compression.dtype (
Any) – JAX dtype for on-device MPO tensors.symmetric (
bool) – If True, build aSymmetricTensor-based MPO with proper U(1) charge assignments on every leg.phys_charges (
ndarray|None) – Physical-leg charge array (length d). If None, defaults to[1, -1]for d=2 and[2, 0, -2]for d=3.
- Return type:
- Returns:
TensorNetwork with L site tensors in the standard MPO format, compatible with
dmrg().- Raises:
ValueError – If no terms have been added.
- class tenax.algorithms.auto_mpo.HamiltonianTerm(coefficient, ops)[source]
Bases:
objectOne term in the Hamiltonian: coefficient * product of local operators.
- coefficient
Scalar (complex) prefactor.
- ops
Tuple of (site, operator_matrix) pairs, sorted by site.
- coefficient: complex
- tenax.algorithms.auto_mpo.build_auto_mpo(terms_spec, L, d=2, site_ops=None, compress=False, compress_tol=1e-12, dtype=<class 'jax.numpy.float64'>, symmetric=False, phys_charges=None)[source]¶
Build an MPO from a list of term specifications.
- Parameters:
terms_spec (
list[KeyPath]) – List of tuples(coeff, op1, site1, op2, site2, ...).L (
int) – Chain length (number of sites).d (
int) – Local Hilbert-space dimension (2 for spin-1/2).site_ops (
WSGIEnvironment[Text,ndarray] |None) – Operator name → matrix dict; defaults to spin_half_ops() for d=2 and spin_one_ops() for d=3.compress (
bool) – Apply left-to-right SVD compression.compress_tol (
float) – Relative singular-value threshold for compression.dtype (
Any) – JAX dtype for MPO tensors.symmetric (
bool) – If True, build aSymmetricTensor-based MPO.phys_charges (
ndarray|None) – Physical-leg charge array (length d).
- Return type:
- Returns:
TensorNetwork MPO compatible with
dmrg().
Example:
mpo = build_auto_mpo( [(1.0, "Sz", i, "Sz", i + 1) for i in range(L - 1)] + [(0.5, "Sp", i, "Sm", i + 1) for i in range(L - 1)] + [(0.5, "Sm", i, "Sp", i + 1) for i in range(L - 1)], L=L, )