open-standards/wai/wai-quantum/examples/dmrg_chain.rs
Transaction Science aa64bcf112
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m53s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m28s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m14s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m13s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m37s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 4m28s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 12s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 2m9s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 23s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 44s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m26s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 58s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m0s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m54s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m50s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 12m4s
standards workspaces build + test / aac-rs (pull_request) Successful in 3m44s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 2m50s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 2m9s
standards workspaces build + test / map-rs (pull_request) Successful in 1m47s
standards workspaces build + test / mesh-rs (pull_request) Successful in 1m13s
standards workspaces build + test / openpay (pull_request) Successful in 5m39s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 9m48s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 59s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 3m34s
standards workspaces build + test / arl-rs (pull_request) Successful in 2m18s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 4m44s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m40s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 5m50s
standards workspaces build + test / sense-rs (pull_request) Successful in 2m39s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 4m32s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 7m32s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 33s
WAI energy receipts / energy receipts · macos (pull_request) Failing after 11m34s
wai-quantum 0.3.34: ground states of spin chains by DMRG, held to exact answers
Claims that classical computers cannot simulate a material are claims about
entanglement; in one dimension the density-matrix renormalization group
usually can, with an error it reports. quantum_dmrg:

- Chain: nearest-neighbour spin-1/2 chains with real terms (XXZ Heisenberg in
  a field, transverse-field Ising), written as matrix-product operators (the
  finite-state machine of their terms).
- Two-site DMRG: Lanczos with full re-orthogonalisation for the lowest state
  of the effective Hamiltonian; truncation by the reduced density matrix's
  eigenvectors (max bond, weight cutoff); discarded weight and the
  entanglement entropy at every bond.
- symmetric_eigen: Householder tridiagonalisation and implicit QL
  (tred2/tql2), hypotenuses in-crate.
- Exact referees: Lanczos on the full 2^n space (to 22 sites), and the open
  transverse-field Ising chain as free fermions at any length
  (E0 = -1/2 sum Lambda_k, Lambda_k^2 the eigenvalues of (A-B)(A+B)).
- The effective Hamiltonian runs in blocks of rows across threads, each row in
  the same order: bit-identical at any thread count (a direct test fails on a
  1e-15 change to one block). The Lanczos tolerance is a setting (1e-8 by
  default; the energy error goes as its square).

Checked:
- the eigensolver reconstructs random symmetric matrices to 1e-12;
- the free-fermion energy equals exact diagonalisation (n = 4, 7, 10);
- DMRG equals exact diagonalisation to 1e-8 on Heisenberg and Ising chains;
- critical Ising: 1.1e-11 per site at 100 sites, 1.4e-11 at 200 against the
  exact energy; Heisenberg 100 sites: -44.127739250 at bond 64 and
  -44.127739889 at bond 128, converging from above;
- variational, monotone in sweeps, repeatable.

The cross-platform pin caught a pointer-width bug: the exact-diagonalisation
start vector multiplied in usize, which wraps differently on wasm32; it now
uses u64, and all 19 pins hold natively and under wasm32-wasip2.

CLI: wai-quantum dmrg [--chain ising|heisenberg] [-n] [--j --jz --h] [--bond]
[--sweeps] [--exact] [--json]. Example: dmrg_chain. CLI output byte-identical
natively and under WASI.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 09:50:20 -04:00

34 lines
1.5 KiB
Rust

//! Ground-state DMRG on a spin chain, against the exact answer where one
//! exists.
//!
//! ```text
//! cargo run --release --example dmrg_chain --features quantum_dmrg -- ising|heisenberg N BOND SWEEPS [h]
//! ```
use wai_quantum::quantum_dmrg::{dmrg, exact_ground_energy, ising_exact_energy, Chain, DmrgConfig};
fn main() {
let a: Vec<String> = std::env::args().collect();
let n: usize = a[2].parse().unwrap();
let bond: usize = a[3].parse().unwrap();
let sweeps: usize = a[4].parse().unwrap();
let field: f64 = a.get(5).map_or(1.0, |x| x.parse().unwrap());
let (chain, exact) = match a[1].as_str() {
"ising" => (Chain::ising(n, 1.0, field), Some(ising_exact_energy(n, 1.0, field))),
"heisenberg" => {
let c = Chain::heisenberg(n, 1.0, 1.0, 0.0);
let e = if n <= 20 { exact_ground_energy(&c) } else { None };
(c, e)
}
other => panic!("{other}"),
};
let t0 = std::time::Instant::now();
let r = dmrg(&chain, &DmrgConfig { max_bond: bond, sweeps, ..DmrgConfig::default() });
let dt = t0.elapsed().as_secs_f64();
let mid = r.entropies[n / 2 - 1];
print!("{} n={n} bond={bond} sweeps={sweeps} E={:.12} per site {:.12} discarded {:.1e} S(mid) {:.4}", a[1], r.energy, r.energy / n as f64, r.discarded, mid);
if let Some(e) = exact {
print!(" exact {e:.12} error/site {:.1e}", (r.energy - e) / n as f64);
}
println!(" {dt:.1}s");
println!("sweeps: {:?}", r.sweep_energies.iter().map(|e| format!("{e:.10}")).collect::<Vec<_>>());
}