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 1m58s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m30s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m16s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m11s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m40s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 4m29s
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 2m11s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 29s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 46s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m31s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m4s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 1m2s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m56s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m45s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m41s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m37s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m0s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 41s
standards workspaces build + test / map-rs (pull_request) Successful in 41s
standards workspaces build + test / mesh-rs (pull_request) Successful in 34s
standards workspaces build + test / openpay (pull_request) Successful in 2m7s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 6m5s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 34s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m9s
standards workspaces build + test / arl-rs (pull_request) Successful in 3m57s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 3m58s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 4m0s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 3m53s
standards workspaces build + test / sense-rs (pull_request) Successful in 3m57s
standards workspaces build + test / macOS energy backends (pull_request) Failing after 6m44s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 8m36s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 35s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m2s
quantum_tdvp evolves a matrix-product state by the two-site time-dependent variational principle, a symmetric second-order sweep: - each bond goes forward half a step under its effective Hamiltonian, and the new centre goes back half a step under its one-site one; - the exponentials are Lanczos with full re-orthogonalisation, and a step that does not converge is halved; - bonds are split by a Jacobi SVD, so amplitudes resolve to rounding; - every bond's basis is completed with null vectors up to max_bond, which removes the projection error a product state's small bonds would cause. The referees are exact Krylov evolution of all amplitudes (up to 20 sites) and the free-fermion Ising quench at any length, including the Loschmidt echo. Checked: - complete bases are exact to rounding at any step size; - at 100 sites and bond 64 the critical quench stays within 1e-9 of the exact answer through t = 3, and past that the error follows the reported discarded weight; - runs are bit-identical across thread counts and natively vs wasm32-wasip2 (new pin); - the CLI command tdvp prints the same bytes natively and under WASI. A fourth-order Yoshida composition was measured as less accurate and slower, and was removed; the module docs record why. Co-Authored-By: Claude Opus 5.5 <[email protected]>
54 lines
2.6 KiB
Rust
54 lines
2.6 KiB
Rust
//! A quench of the transverse-field Ising chain by TDVP, held at every
|
||
//! report to the exact free-fermion solution: the chain starts with every
|
||
//! σˣ = +1 and evolves under `−J Σ σᶻσᶻ − h Σ σˣ`.
|
||
//!
|
||
//! ```text
|
||
//! cargo run --release --example tdvp_quench --features quantum_tdvp -- N BOND DT T [h] [cutoff] [threads]
|
||
//! ```
|
||
use wai_quantum::quantum_dmrg::{Chain, Mps, Op, Scalar, C};
|
||
use wai_quantum::quantum_tdvp::{ising_quench, Evolution, TdvpConfig};
|
||
|
||
fn main() {
|
||
let a: Vec<String> = std::env::args().collect();
|
||
let n: usize = a[1].parse().unwrap();
|
||
let bond: usize = a[2].parse().unwrap();
|
||
let dt: f64 = a[3].parse().unwrap();
|
||
let t_end: f64 = a[4].parse().unwrap();
|
||
let h: f64 = a.get(5).map_or(1.0, |x| x.parse().unwrap());
|
||
let cutoff: f64 = a.get(6).map_or(1e-20, |x| x.parse().unwrap());
|
||
let threads: usize = a.get(7).map_or(TdvpConfig::default().threads, |x| x.parse().unwrap());
|
||
let chain = Chain::ising(n, 1.0, h);
|
||
let plus = Mps::product(&vec![[C { re: 1.0, im: 0.0 }, C { re: 1.0, im: 0.0 }]; n]);
|
||
let cfg = TdvpConfig { dt, max_bond: bond, cutoff, threads, ..TdvpConfig::default() };
|
||
let mut ev = Evolution::new(&chain, &plus, cfg);
|
||
let e0 = ev.energy();
|
||
let steps = (t_end / dt).round() as usize;
|
||
let every = ((0.5 / dt).round() as usize).max(1);
|
||
let t0 = std::time::Instant::now();
|
||
let mut discarded = 0.0;
|
||
println!("ising n={n} h={h} bond={bond} dt={dt} cutoff={cutoff:e}");
|
||
println!(" t max|Δσˣ| max|Δσᶻσᶻ| σˣ(mid) exact rate exact rate S(mid) bond |ΔE| discarded seconds");
|
||
for s in 1..=steps {
|
||
discarded += ev.step().discarded;
|
||
if s % every == 0 || s == steps {
|
||
let t = ev.time();
|
||
let ff = ising_quench(n, 1.0, h, t);
|
||
let x = ev.expect(Op::x());
|
||
let zz = ev.bond_expect(Op::z(), Op::z());
|
||
let dx = x.iter().zip(&ff.x).map(|(p, q)| (p - q).abs()).fold(0.0, f64::max);
|
||
let dzz = zz.iter().zip(&ff.zz).map(|(p, q)| (p - q).abs()).fold(0.0, f64::max);
|
||
let echo = ev.overlap(&plus).norm2();
|
||
let rate = -echo.ln() / n as f64;
|
||
let exact_rate = -ff.echo.ln() / n as f64;
|
||
let s_mid = ev.entropies()[n / 2 - 1];
|
||
println!(
|
||
"{t:5.2} {dx:.2e} {dzz:.2e} {:+.10} {:+.10} {rate:.8} {exact_rate:.8} {s_mid:.4} {:4} {:.1e} {discarded:.1e} {:.1}",
|
||
x[n / 2],
|
||
ff.x[n / 2],
|
||
ev.max_bond(),
|
||
(ev.energy() - e0).abs(),
|
||
t0.elapsed().as_secs_f64()
|
||
);
|
||
}
|
||
}
|
||
}
|