iDMRG¶
Infinite DMRG (iDMRG) finds the ground-state energy per site of a translationally invariant Hamiltonian directly in the thermodynamic limit.
Background¶
iDMRG works by repeatedly inserting two new sites into the centre of a growing chain and optimising them with a Lanczos eigensolver. After each growth step the centre bond is truncated via SVD to a maximum bond dimension \(\chi\). The energy-per-site estimate converges as the effective environment builds up around the unit cell.
Key properties of the Tenax implementation:
2-site growth algorithm: two sites are added per iteration.
The bulk Hamiltonian is specified as a single repeated MPO tensor \(W[w_l, \text{ket}, \text{bra}, w_r]\).
Outer growth loop is a Python for-loop; the Lanczos matvec is
@jax.jitcompiled.Built-in MPO constructors for the Heisenberg chain and cylinder.
Configuration¶
from tenax import iDMRGConfig
config = iDMRGConfig(
max_bond_dim=100, # maximum MPS bond dimension (chi)
max_iterations=200, # maximum number of growth steps
convergence_tol=1e-8, # stop when |dE/site| < tol
lanczos_max_iter=50, # Lanczos iteration cap
lanczos_tol=1e-12, # Lanczos convergence tolerance
svd_trunc_err=None, # SVD truncation error (None = use max_bond_dim)
verbose=True,
)
Parameter |
Default |
Description |
|---|---|---|
|
100 |
Maximum MPS bond dimension \(\chi\) |
|
200 |
Maximum 2-site growth steps |
|
1e-8 |
Energy-per-site convergence threshold |
|
50 |
Maximum Lanczos iterations |
|
1e-12 |
Lanczos convergence tolerance |
|
None |
Max SVD truncation error (overrides |
|
False |
Print per-step diagnostics |
Example – Heisenberg chain¶
from tenax import iDMRGConfig, idmrg, build_bulk_mpo_heisenberg
# Build the bulk W-tensor for the spin-1/2 XXZ Heisenberg model
bulk_mpo = build_bulk_mpo_heisenberg(Jz=1.0, Jxy=1.0, hz=0.0)
config = iDMRGConfig(max_bond_dim=64, max_iterations=200, verbose=True)
result = idmrg(bulk_mpo, config)
print(f"Energy/site: {result.energy_per_site:.10f}")
print(f"Converged: {result.converged}")
print(f"Steps: {len(result.energies_per_step)}")
# Reference: E/site ≈ 0.25 - ln(2) ≈ −0.4431471805
build_bulk_mpo_heisenberg returns a DenseTensor with legs
("w_l", "mpo_top", "mpo_bot", "w_r") and shape (5, 2, 2, 5).
Example – Infinite cylinder¶
build_bulk_mpo_heisenberg_cylinder constructs a bulk MPO for a
Heisenberg model on an infinite cylinder of circumference \(L_y\). Each
“super-site” encodes an entire ring of \(L_y\) spins (physical dimension
\(d = 2^{L_y}\)).
from tenax import iDMRGConfig, idmrg, build_bulk_mpo_heisenberg_cylinder
Ly = 4
bulk_mpo = build_bulk_mpo_heisenberg_cylinder(Ly=Ly, J=1.0)
config = iDMRGConfig(max_bond_dim=200, max_iterations=300)
result = idmrg(bulk_mpo, config)
print(f"E/site (Ly={Ly}): {result.energy_per_site / Ly:.8f}")
Note
build_bulk_mpo_heisenberg_cylinder only accepts even \(L_y\).
Odd circumference frustrates antiferromagnetic order on the square
lattice.
Result object¶
idmrg() returns an iDMRGResult named tuple:
Field |
Type |
Description |
|---|---|---|
|
|
Converged energy per site |
|
|
Energy-per-site estimate at each iteration |
|
|
2-site unit cell |
|
|
Singular values on the centre bond |
|
|
Whether the run converged within tolerance |
MPO construction¶
build_bulk_mpo_heisenberg builds a single bulk \(W\)-matrix (shape
\(5 \times d \times d \times 5\)) for the spin-1/2 XXZ Heisenberg model:
For finite chains, use build_mpo_heisenberg() instead (see
DMRG). For custom Hamiltonians, see AutoMPO.