This release is a pre-release and may not be stable for production use.
Tenax
A JAX-based tensor network library with symmetry-aware block-sparse tensors and label-based contraction.
The name Tenax combines Tensor network + Jax, and is also Latin for "holding fast" — reflecting how tensor networks bind indices together through contraction.
Experimental project — This library is under active development and largely written with the assistance of Claude Code (AI). While we test extensively, AI-generated code can contain subtle bugs. Please verify results against known benchmarks before using them in research. Bug reports and contributions are welcome.
Features
Each entry links to its guide page; the full documentation is at tenax.readthedocs.io.
Tensors and contraction
- Block-sparse symmetric tensors — only allowed charge sectors stored: U(1), Z_n, products, fermion parity (symmetry)
- Label-based contraction — shared labels contract automatically (Cytnx-style), with opt_einsum path finding (contraction)
- Block-sparse SVD, QR and eigh — native symmetry-aware decompositions in
tenax.linalg(contraction) - Polymorphic arithmetic — the same algorithm code runs on
DenseTensorandSymmetricTensor(core concepts) - Tensor networks and
.netfiles — cached graph container and declarative topologies (tensor networks)
1D algorithms
- DMRG — finite DMRG with a Cython BLAS CPU path and JIT / multi-GPU sharded sweeps (DMRG)
- iDMRG — infinite chains and infinite cylinders (iDMRG)
- TDVP and iTEBD — time evolution; iTEBD with the inversion-free Hastings update (TDVP, capabilities)
- AutoMPO — Hamiltonian MPOs from symbolic operator terms, dense or U(1) block-sparse (AutoMPO)
2D quantum algorithms
- iPEPS simple update — 1-site and 2-site unit cells, with a belief-propagation gauge for the bond weights (iPEPS)
- AD ground-state optimization — implicit, explicit, C4v and root-implicit AD through CTM; on the fused-CTM implicit-AD 1x1 and 2-site paths an unconverged CTM forward raises
CTMNotConvergedError(or warns withCTMNotConvergedWarning) (AD paths) - CTM environments — SVD/eigh/QR projectors, in-CTM χ growth, convergence and saddle checks, optional mixing for two-state cycles, split-CTMRG (CTM)
- Fermionic iPEPS (fPEPS) — graded tensors for spinless fermions / the t-V model (fPEPS)
- Honeycomb and kagome — native honeycomb CTM and kagome iPESS with AD (guide)
- Quasiparticle excitations — iPEPS excitation spectra at arbitrary momenta (AD excitations)
Classical statistical mechanics
- TRG and Gilt-TNR — coarse-graining of 2D partition functions (TRG)
- HOTRG and Gilt-HOTRG — with multi-GPU sharding and the q-state Potts model (HOTRG)
Tooling
- Hardware backends and benchmarks — CPU, CUDA, TPU and Metal via JAX; CLI benchmark suite (benchmarks)
See capabilities for a map of what each path is (and is not) the right tool for.
Installation
Note: The PyPI package (
tenax-tn) is not yet available. Install from source using the instructions below.
git clone https://github.com/tenax-lab/tenax.git
cd tenax
# With uv (recommended)
uv sync --all-extras --dev
# Or with pip
pip install -e .
Hardware acceleration
Tenax uses JAX as its backend. To enable GPU or TPU acceleration, install the appropriate JAX variant before installing Tenax:
# NVIDIA GPU (CUDA 13, recommended)
pip install -U "jax[cuda13]"
# NVIDIA GPU (CUDA 12)
pip install -U "jax[cuda12]"
# Google Cloud TPU
pip install -U "jax[tpu]"
# Apple Silicon GPU (macOS only, experimental)
pip install jax-metal
See the installation guide and the
JAX installation guide for
more accelerator options. Importing tenax enables float64; see
gotchas if you import JAX first.
Quick Start
import jax
import jax.numpy as jnp
import numpy as np
from tenax import (
U1Symmetry,
TensorIndex,
FlowDirection,
SymmetricTensor,
TensorNetwork,
contract,
)
# Define U(1) symmetric tensor indices with named legs
u1 = U1Symmetry()
phys_charges = np.array([-1, 1], dtype=np.int32)
bond_charges = np.array([-1, 0, 1], dtype=np.int32)
key = jax.random.PRNGKey(0)
A = SymmetricTensor.random_normal(
indices=(
TensorIndex.from_charges(u1, phys_charges, FlowDirection.IN, label="p0"),
TensorIndex.from_charges(u1, bond_charges, FlowDirection.IN, label="left"),
TensorIndex.from_charges(u1, bond_charges, FlowDirection.OUT, label="bond"),
),
key=key,
)
B = SymmetricTensor.random_normal(
indices=(
TensorIndex.from_charges(u1, phys_charges, FlowDirection.IN, label="p1"),
TensorIndex.from_charges(u1, bond_charges, FlowDirection.IN, label="bond"), # shared label
TensorIndex.from_charges(u1, bond_charges, FlowDirection.OUT, label="right"),
),
key=jax.random.PRNGKey(1),
)
# Contract by matching shared labels — "bond" is summed over automatically
result = contract(A, B)
print(result.labels()) # ('p0', 'left', 'p1', 'right')
# Build a tensor network and contract
tn = TensorNetwork()
tn.add_node("A", A)
tn.add_node("B", B)
tn.connect_by_shared_label("A", "B")
result = tn.contract()
Examples
One short example per algorithm family. Each guide page has the full version, the options, and the caveats.
DMRG
from tenax import DMRGConfig, build_mpo_heisenberg, build_random_symmetric_mps, dmrg
L = 10 # chain length
mpo = build_mpo_heisenberg(L, Jz=1.0, Jxy=1.0) # U(1) block-sparse MPO
mps = build_random_symmetric_mps(L, bond_dim=8) # matching block-sparse MPS
config = DMRGConfig(max_bond_dim=50, num_sweeps=10)
result = dmrg(mpo, mps, config)
print(f"Ground state energy: {result.energy:.8f}")
2D cylinders map onto a chain through AutoMPO; see the DMRG guide.
iDMRG
from tenax import idmrg, build_bulk_mpo_heisenberg, iDMRGConfig
W = build_bulk_mpo_heisenberg(Jz=1.0, Jxy=1.0)
config = iDMRGConfig(max_bond_dim=32, max_iterations=100, convergence_tol=1e-8)
result = idmrg(W, config)
print(f"Energy per site: {result.energy_per_site:.6f}") # ~ -0.4431
print(f"Converged: {result.converged}")
Infinite cylinders: see the iDMRG guide.
TRG
from tenax import TRGConfig, trg, compute_ising_tensor, ising_free_energy_exact
beta = 0.44 # near critical temperature
T = compute_ising_tensor(beta)
config = TRGConfig(max_bond_dim=16, num_steps=20)
log_z_per_n = trg(T, config)
f_trg = float(-log_z_per_n / beta)
f_exact = ising_free_energy_exact(beta)
print(f"TRG: {f_trg:.8f}")
print(f"Exact: {f_exact:.8f}")
HOTRG, Gilt-TNR and the Potts model follow the same pattern (TRG, HOTRG).
AutoMPO
from tenax import AutoMPO
L = 10
auto = AutoMPO(L)
for i in range(L - 1):
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()
mpo_sym = auto.to_mpo(symmetric=True) # U(1) block-sparse MPO
Custom operators and the functional interface: see the AutoMPO guide.
iPEPS simple update
from tenax import iPEPSConfig, CTMConfig, heisenberg_gate, ipeps
# 2-site checkerboard iPEPS — captures Neel order
config = iPEPSConfig(
max_bond_dim=2,
num_imaginary_steps=200,
dt=0.05,
ctm=CTMConfig(chi=10, max_iter=40),
unit_cell="2site",
)
energy, peps, (env_A, env_B) = ipeps(heisenberg_gate(), None, config)
print(f"Energy per site: {energy:.6f}") # ~ -0.63
The energy ipeps() reports is a quick estimate; for an accurate number, and
for the bond-weight options, see the iPEPS guide.
iPEPS AD optimization
from tenax import (
iPEPSConfig, CTMConfig, heisenberg_gate, optimize_gs_ad, sublattice_rotate_gate,
)
# 1-site unit cell: rotate one sublattice so the Neel state is translation invariant
H = sublattice_rotate_gate(heisenberg_gate())
config = iPEPSConfig(
max_bond_dim=2,
num_imaginary_steps=200,
dt=0.05,
ctm=CTMConfig(chi=8, max_iter=40),
gs_num_steps=10, # implicit AD + L-BFGS (Hager-Zhang) by default
su_init=True, # warm-start from simple update
)
A_opt, env, E_gs = optimize_gs_ad(H, None, config)
print(f"Ground-state energy: {E_gs:.6f}") # ~ -0.660
The AD paths guide compares the implicit, explicit, C4v and root-implicit paths and gives a recommended configuration; excitation spectra are in the excitations guide.
Fermionic iPEPS (fPEPS)
import jax
from tenax import FPEPSConfig, fpeps, spinless_fermion_gate, sublattice_gap
# mu = 2V is the half-filling point of the t-V model
config = FPEPSConfig(D=2, t=1.0, V=4.0, mu=8.0, dt=0.05, num_imaginary_steps=200,
ctm_chi=8, ctm_max_iter=60, ctm_conv_tol=1e-8)
H = spinless_fermion_gate(config)
energy, (A, B), (env_A, env_B) = fpeps(H, config, key=jax.random.PRNGKey(0))
print(energy, sublattice_gap(A, B, env_A, env_B)) # -4.0 1.0: CDW, E = -V per site
Read the fPEPS guide before trusting the energy: it covers the sign convention, the chemical potential, and the standing caveats.
Example scripts
Runnable example scripts are in the examples/ directory:
| Script | Algorithm | Model |
|---|---|---|
heisenberg_cylinder.py |
DMRG | Heisenberg on 4x2, 6x3, 8x4 cylinders |
heisenberg_infinite_cylinder.py |
iDMRG | Heisenberg on infinite Ly=2, Ly=4 cylinders |
heisenberg_ipeps_su.py |
iPEPS simple update | Heisenberg (1x1 and 2-site unit cells) |
heisenberg_ipeps_ad.py |
iPEPS AD optimization | Heisenberg (random vs SU init) |
heisenberg_ipeps_excitations.py |
iPEPS excitations | Heisenberg dispersion along Γ-X-M-Γ |
spinless_fermion_fpeps.py |
fPEPS simple update | Spinless fermions (free and interacting) |
ising_trg.py |
TRG | 2D Ising vs Onsager exact |
ising_hotrg.py |
HOTRG | 2D Ising vs Onsager exact |
gilt_hotrg_ising.py |
Gilt-HOTRG | 2D Ising critical point |
kagome_spin12_pess_ad_benchmark.py |
iPESS AD | Spin-½ kagome AFM Heisenberg sweep |
kagome_spin1_pess_ad_benchmark.py |
iPESS AD | Spin-1 kagome Heisenberg sweep |
kagome_spin1_xxz_anisotropy_sweep.py |
iPESS AD | Spin-1 kagome XXZ Δ ∈ {0, 0.5, 1, 1.5, 2} |
Run any example with:
uv run python examples/<script>.py
Documentation
The full documentation — user guide, algorithm tutorials and API reference —
is at tenax.readthedocs.io. The sources are in
docs/; build them locally with Sphinx:
uv sync --extra docs
cd docs && uv run make html
The generated HTML is in docs/_build/html/.
Benchmarks
A CLI-driven benchmark suite measures wall-clock performance of every algorithm across hardware backends:
# Quick smoke test (TRG, small size, 1 trial)
python -m benchmarks.run --backend cpu --algorithm trg --size small --trials 1
# Show available backends
python -m benchmarks.run --list-backends
See the benchmarks guide for every option and output format.
Development
# Clone and install with dev dependencies
git clone https://github.com/tenax-lab/tenax.git
cd tenax
uv sync --all-extras --dev
# Install pre-commit hooks (ruff lint + format on every commit)
uv run pre-commit install
# Run tests
uv run pytest -m core # fast core tests only
uv run pytest -m algorithm # algorithm tests (DMRG, TRG, iPEPS, integration)
uv run pytest -m "not slow" # skip expensive tests
uv run pytest # full suite
# Lint
uv run ruff check src/ tests/
See the contributing guide for the workflow and
how to document new API. Work-in-progress design documents live in design/.
References
- H.-J. Liao, J.-G. Liu, L. Wang, T. Xiang, Phys. Rev. X 9, 031041 (2019) — AD-based iPEPS ground-state optimization
- A. Francuz, N. Schuch, B. Vanhecke, PRR 7, 013237 (2025) — Stable AD through CTM (SVD regularization, truncation correction, implicit differentiation)
- M. Rader, L. Gresista, C. Hubig, S. Montangero, A. Weichselbaum, J. von Delft, arXiv:2511.09546 (2025) — Metric preconditioning and Hager-Zhang line search for iPEPS optimization
- L. Ponsioen, F. F. Assaad, P. Corboz, SciPost Phys. 12, 006 (2022) — Quasiparticle excitations for iPEPS
- J. Naumann, E. L. Weerda, J. Eisert, M. Rizzi, P. Schmoll, arXiv:2502.10298 (2025) — Split-CTMRG with factored projectors for efficient iPEPS environments
Algorithm-specific references are listed on each guide page.
License
Apache 2.0
Metadata
Release files for tenax-tn 0.8.4.dev20261016
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tenax_tn-0.8.4.dev20261016.tar.gz | 4.1 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| tenax_tn-0.8.4.dev20261016-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| tenax_tn-0.8.4.dev20261016-cp312-cp312-macosx_11_0_arm64.whl | CPython 3.12 | CPython 3.12 | macOS 11.0+ ARM64 | Details |
| tenax_tn-0.8.4.dev20261016-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| tenax_tn-0.8.4.dev20261016-cp311-cp311-macosx_11_0_arm64.whl | CPython 3.11 | CPython 3.11 | macOS 11.0+ ARM64 | Details |
Total release size: 13.9 MB
Release files / tenax_tn-0.8.4.dev20261016.tar.gz
| Download URL | tenax_tn-0.8.4.dev20261016.tar.gz |
|---|---|
| Size | 4.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
bddfd38a2ad2ce6ffe705b6bf1710a3178e37bf5063cb0dc6198ae01badde609
|
|
BLAKE2b-256 checksum How to use checksums |
ea0357df6111ea6121ccaeb10b6d58627125ed822b820ee5b7e57315e06fa4de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / tenax_tn-0.8.4.dev20261016-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | tenax_tn-0.8.4.dev20261016-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 4.3 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
f31ad5962916c010d65ed7284f5739a0f6a53a657761c72089f652378b113650
|
|
BLAKE2b-256 checksum How to use checksums |
10f744cc4d62a1642ce7a8ca4af2ecb414da7b1fe23543ab0995a760c5293ff4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / tenax_tn-0.8.4.dev20261016-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | tenax_tn-0.8.4.dev20261016-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
98c4f21cad442bc099b8c6c7f9866f7cdf1628d21ac36fda0fae31d215f4f55b
|
|
BLAKE2b-256 checksum How to use checksums |
e72187df138f7b153e4aba2347b6500ee5a91b6971ff1ab6e14fe35f54c3beb8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / tenax_tn-0.8.4.dev20261016-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | tenax_tn-0.8.4.dev20261016-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
2992546510e581c539d8fd1abc3bae7ff837421cd00242a5e8e8721c1ae2974f
|
|
BLAKE2b-256 checksum How to use checksums |
80aae1650f1c6509be2eef0f6c4879afac370321b031fd0fc5a4a2ea423279f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / tenax_tn-0.8.4.dev20261016-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | tenax_tn-0.8.4.dev20261016-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
490ea51321f6f3415c4b37fb5eecaf2ffa925ef0f2c3e99e81473976a2b3b643
|
|
BLAKE2b-256 checksum How to use checksums |
6f53e1fe0cb2783eb92ee80d33662f6527e8b6d86a3c2d0482338fd744b81df7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log