Skip to content

Add two-site BUG time integrator#1

Open
madhavmen wants to merge 15 commits into
Ideogenesis-AI:developfrom
madhavmen:feature/two-site-bug
Open

Add two-site BUG time integrator#1
madhavmen wants to merge 15 commits into
Ideogenesis-AI:developfrom
madhavmen:feature/two-site-bug

Conversation

@madhavmen

@madhavmen madhavmen commented Jun 19, 2026

Copy link
Copy Markdown

Summary

Adds alice.algorithm.two_site_bug, a gate-based two-site BUG (Basis-Update &
Galerkin)
integrator for real- and imaginary-time evolution of an MPS under a
nearest-neighbour Hamiltonian. It is an independent algorithm unit built entirely
on the existing Alice/Nicole stack — symmetry-aware MPS, the AutoMPO interaction
list, Nicole decomp/contract/merge_axes, and the PyTorch backend — and adds
no new tensor infrastructure.

How it works

  • Even/odd Trotter sweeps. The nearest-neighbour Hamiltonian splits into two
    commuting bond groups (even and odd left-site index). Each step applies two-site
    bond gates group by group; within a group the gates act on disjoint site pairs,
    so the group is exact. 'strang' (symmetric, second-order) and 'lie'
    (first-order) compositions are provided, plus imaginary-time cooling.
  • Rank-adaptive bond update. Each bond update does the Basis Update Galerkin scheme.
    .
  • Bond gates from AutoMPO. The bare two-site bond Hamiltonian is reused
    directly from each nearest-neighbour Interaction2Site: the leading and terminal
    MPO tensors are contracted over their operator channel (exactly as
    build_hamiltonian does) and exponentiated block-wise on the PyTorch backend,
    preserving the symmetry block structure. No bespoke operator algebra.
  • Diagnostics. Summary records, per step, both the kept bond dimension and
    the proposed (pre-truncation) augmented dimension, so the basis augmentation
    and the discarded rank growth are both visible.

Reused Alice/Nicole features

Symmetry-aware MPS (any group Nicole supports) · AutoMPO interaction list and
geometries (any nearest-neighbour model build_interaction produces) · Nicole
decomp for the SVD rank adaptation · PyTorch backend for the block matrix
exponential (GPU/dtype/autograd inherited) · logging for sweep-by-sweep
diagnostics · the AlgorithmOptions/AlgorithmSummary interface (TOML I/O,
serialize/deserialize) shared with DMRG.

Validation

New tests under tests/algorithm/two_site_bug/ check the integrator against exact
diagonalization on a Heisenberg domain wall:

  • state fidelity vs. exp(-iHt) (1 - F < 1e-6),
  • exact norm conservation (unitary gates),
  • exact U(1) total-S_z conservation,
  • second-order Strang convergence (infidelity ~dt^4), and Strang beating Lie,
  • imaginary-time evolution lowering the energy toward the ground state.

Scope

Nearest-neighbour Hamiltonians (the BUG target);Full suite: 835 passed;
ruff check src/ tests/ clean; docs build verified.

Related issues: none.

Phy-David-Zhang and others added 9 commits May 4, 2026 10:31
Feature release delivering the first stable version of Alice, an open-source
project for 1D tensor network algorithms built on Nicole. The release covers
the full MPS/MPO infrastructure, a TOML-driven AutoMPO Hamiltonian builder,
three-scheme DMRG with environment caching, and comprehensive physics model
support for spin, fermionic, and Hubbard systems. No breaking changes; this
is the initial public API.

Version: 0.1.0
Release Date: May 4, 2026

New Features:

Tensor Network Infrastructure (network.py, observe.py):
- MPS, MPO, and Network classes providing block-sparse matrix product states
  and operators with full support for Abelian and non-Abelian (SU(2))
  symmetry groups inherited from Nicole
- Left- and right-canonicalization routines with norm computation and
  bond-consistency validation
- observe function for MPS-MPO-MPS expectation-value computation, accepting
  both pure MPS and mixed MPS/MPO states

AutoMPO Construction (autompo.py, interaction.py):
- build_interaction: TOML-configured interaction map builder with built-in
  model presets and support for user-defined model functions
- build_hamiltonian: term-by-term MPO assembler accumulating interactions via
  Nicole's oplus, then compressing with two canonical sweeps; handles
  arbitrary symmetry groups including non-Abelian SU(2)
- compact_every parameter for incremental compaction during large Hamiltonian
  builds to limit intermediate bond dimension growth
- Interaction, Interaction1Site, Interaction2Site data types for unambiguous
  representation of on-site and two-site coupling terms

Lattice Geometries (geometry.py):
- 1D chain: straight nearest-neighbor traversal for standard spin and fermion
  chains
- 2D snake traversal: boustrophedon MPS ordering for rectangular lattices,
  supporting quasi-1D cylinders and ladders
- 2D square lattice: full nearest-neighbor interaction map with both
  horizontal and vertical bonds
- Custom geometry support via the build_geometry dispatch mechanism

Physical Spaces (system.py):
- build_bosonic: spin-s site with spherical spin operator templates and
  Jordan-Wigner-free intermediate tensors; supports U(1) and SU(2)
- build_fermionic: spinless-fermion site with Jordan-Wigner-dressed hopping
  templates and number operator; supports U(1) and Z(2)
- build_conductor: spinful-fermion site with JW-dressed hopping templates,
  spin operators, and double-occupancy operator; supports U(1)xU(1),
  Z(2)xU(1), U(1)xSU(2), and Z(2)xSU(2)

Physics Models (models.py):
- Heisenberg: spin-s Heisenberg chain with NN coupling J and optional NNN
  coupling J'; built on build_bosonic; supports U(1) and SU(2)
- Free fermion: spinless tight-binding chain with NN hopping t, optional NNN
  hopping t', and optional chemical potential mu; built on build_fermionic;
  supports U(1) and Z(2)
- Hubbard: spinful Hubbard chain with NN hopping t, on-site interaction U,
  optional NNN hopping t', and chemical potential mu referenced to
  half-filling; built on build_conductor; supports all four Band symmetry
  sectors

DMRG Algorithm (dmrg.py, sweep.py, scheme_1s.py, scheme_2s.py,
complement.py, davidson.py):
- Three update schemes: 1-site (bond-dimension preserving, for convergence
  refinement), 2-site (SVD truncation for diagnostic checks), and 1-site-plus
  (primary scheme for bond dimension growth via a complement isometry
  projected from the 2-site residual)
- Davidson eigensolver operating directly in the symmetry-block-sparse space
  with thick restart; uses the plain residual as the correction vector (no
  preconditioning)
- Energy-based convergence criterion with configurable threshold per sweep
- dmrg.Options.from_toml for TOML-driven configuration; dmrg.run entry point
  returning a dmrg.Summary with sweep history and discarded weights

Environment Caching (environ.py):
- Environment class with optional disk-spilling of environment blocks via
  torch.save for long chains that exceed available RAM
- Sliding in-memory window with configurable size limiting peak memory usage
- Asynchronous I/O on a background thread to overlap disk transfers with
  sweep computation

Systematic Logging (logging.py):
- configure_logging: one-call setup of Alice's logging hierarchy with
  configurable level and format, backed by Python's standard logging module
- Sweep-by-sweep diagnostics logging site index, energy, bond dimensions,
  and discarded weight per half-sweep
- Geometry and interaction-map summaries logged as ASCII diagrams at
  construction time

Test Suite (538 tests):
- 538 tests pass, 0 skipped.
- New test modules: tests/algorithm/dmrg/test_davidson.py (10 tests),
  test_dmrg.py (36), test_environ.py (39), test_scheme_1s.py (5),
  test_scheme_1sp.py (31), test_scheme_2s.py (11), test_sweep.py (14);
  tests/algorithm/test_interface.py (11);
  tests/diagonaliztn/test_autompo.py (38), test_conductor.py (8),
  test_freefermion.py (4), test_heisenberg.py (8);
  tests/network/test_network.py (113), test_observe.py (12);
  tests/physics/test_chain.py (19), test_geometry.py (11),
  test_models.py (43), test_square.py (39), test_system.py (86)

Statistics and Scope:
- 196 commits in the initial release.
- 63 files changed: 15908 insertions, 26 deletions.
- Source modules: src/alice/network/network.py, autompo.py, interaction.py,
  observe.py; src/alice/physics/geometry.py, models.py, system.py;
  src/alice/algorithm/dmrg/dmrg.py, environ.py, sweep.py, scheme_1s.py,
  scheme_2s.py, complement.py, davidson.py; src/alice/algorithm/interface.py;
  src/alice/logging.py
- Test modules: tests/algorithm/dmrg/, tests/algorithm/,
  tests/diagonaliztn/, tests/network/, tests/physics/
- Docs pages touched: README.md

Rationale: Alice is structured around a shared core — the MPS, MPO, and
network infrastructure — on top of which algorithms and models are developed
as independent units. The two-level physics layer (space builders in
system.py, Hamiltonian models in models.py) separates operator construction
from coupling assignment, allowing either layer to be replaced without
modifying the other. The AutoMPO pipeline delegates all sector arithmetic to
Nicole's oplus, which makes the Hamiltonian builder agnostic to the symmetry
group and correct for SU(2) without any special-casing. The three DMRG
schemes are designed to be used in sequence: 1-site-plus sweeps drive bond
dimension growth via controlled expansion, and 1-site sweeps refine
convergence once the target bond dimension is reached. The 2-site scheme is
provided primarily for diagnostic purposes and would rarely be the scheme of
choice in a production calculation. Environment caching with asynchronous I/O
ensures that chain lengths are limited by disk space rather than RAM,
enabling production runs on modest hardware. The TOML-driven configuration
keeps the user-facing API concise and reproducible across workstations and
HPC clusters without code changes.

Breaking Changes: None. This is the initial public release; there is no
prior API to break.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.6,
Yuzuha >= 0.1.5.

All 538 tests pass.
Documentation update release introducing the complete Alice documentation site.
A Material-themed MkDocs site with 45 pages across getting-started guides, a
full API reference, and worked DMRG examples is added. The PyPI distribution is
concurrently renamed from alice to alice-net; the import namespace and all
public APIs are unchanged. No breaking changes.

Version: 0.1.1
Release Date: May 6, 2026

Documentation:

Infrastructure (mkdocs.yml, docs/overrides/, docs/stylesheets/, docs/hooks.py):
- mkdocs.yml: full site configuration with Material theme, custom alice color
  scheme, three-tab navigation, dark/light/system theme switching, content and
  search features
- docs/overrides/home.html: custom landing page with hero image and feature cards
- docs/stylesheets/extra.css: alice color palette, hero-section layout,
  light/dark overrides
- docs/hooks.py: post-processing hook converting inline bullet text in table
  cells to proper HTML list elements
- Plugins: mkdocstrings (NumPy-style docstrings), markdown-exec (configured for
  future live execution), git-revision-date-localized, git-committers
- Extensions: arithmatex (MathJax), superfences (Mermaid), tabbed, emoji
  (Material + FontAwesome)

Getting Started (docs/getting-started/, 7 pages):
- what-is-alice.md: philosophy, relationship with Nicole, supported symmetry
  groups and algorithms
- installation.md: pip/uv install, development setup, optional dependency groups
- core-concepts.md: MPS/MPO block-sparse structure, symmetry sectors, DMRG
  sweep logic
- quick-start.md: end-to-end Heisenberg DMRG example from site definition
  through energy output
- contributing.md: branch model, coding conventions, test requirements
- git-control.md: tagging, branching, and release workflow for the Alice project
- changelog.md: version history beginning with v0.1.0

API Reference (docs/api/, 30 pages):
- Network: Network, MPS, MPO (construction, canonicalization, norm,
  serialization, SVD compression, norm redistribution); observe
  (expectation-value sweep with SU(2) Bridge weight support)
- Interaction: Interaction, Interaction1Site, Interaction2Site dataclass
  references; build_interaction with plugin section documentation
- Geometry: generate_snake_order, intrcmap_1dchain, intrcmap_square,
  build_geometry with parameter tables and usage notes
- Local Space: build_bosonic, build_fermionic, build_conductor with
  symmetry-mode tables
- Hamiltonian: build_hamiltonian; build_heisenberg, build_free_fermion,
  build_hubbard
- DMRG: dmrg.Options (full parameter reference with TOML key mapping),
  dmrg.Summary (output fields and serialization), dmrg.run (update schemes
  1s/2s/1sp, convergence criteria)
- Logging: configure_logging (handler configuration, log levels, output file
  naming)

Examples (docs/examples/, 8 pages):
- dmrg/heisenberg.md: ground-state energy of a spin-1/2 chain, U(1) and SU(2)
  symmetry comparison
- dmrg/free-fermion.md: tight-binding chain benchmark against exact
  diagonalization
- dmrg/hubbard.md: charge and spin sector targeting in a single-band Hubbard
  model; disk-caching walkthrough for large chains
- autompo-toml.md: [[interaction]] tables, [plugin] sections for user-defined
  models, built-in presets
- extensions/custom-geometry.md, custom-space.md, custom-model.md: guides for
  extending Alice outside the built-in presets

Packaging:

Distribution Renamed to alice-net (pyproject.toml, src/alice/):
- Distribution name changed from alice to alice-net; wheel target added pointing
  to src/alice; project URLs (homepage, documentation, repository, issues)
  expanded
- Copyright notices updated from "Alice library" to "Alice project" across all
  source, test, and example files
- README badge links and logging startup banner updated to reflect alice-net
- Install: pip install alice-net or uv add alice-net; import namespace alice is
  unchanged

Test Suite (538 tests):
- 538 tests pass, 0 skipped.
- No new test files added; this release is documentation and packaging only.
  The existing test suite is unchanged.

Statistics and Scope:
- 42 commits since v0.1.0.
- 112 files changed: 3228 insertions, 64 deletions.
- Source modules touched: src/alice/__init__.py, src/alice/logging.py,
  src/alice/network/__init__.py, src/alice/physics/__init__.py,
  src/alice/algorithm/__init__.py (copyright notices);
  pyproject.toml (version, distribution name)
- Test modules touched: all test files (copyright notice update)
- Docs pages touched: 45 new pages across docs/api/, docs/examples/,
  docs/getting-started/; docs/index.md, docs/hooks.py,
  docs/overrides/home.html, docs/stylesheets/extra.css; mkdocs.yml

Rationale:

Building the documentation alongside the v0.1.1 release makes the site
immediately accurate and prevents the documentation debt that accumulates when
docs are written separately from implementation. The Material theme and
mkdocstrings stack mirrors the Nicole documentation site, which keeps the user
experience consistent across both projects and reduces the maintenance overhead
of running two divergent documentation systems. Renaming the PyPI distribution
to alice-net removes a potential package conflict without touching any import
paths or API surfaces, making the change invisible to users who already have
Alice code written.

Breaking Changes: None. All previously valid calls continue to work unchanged.
The only user-visible change outside the documentation is the PyPI distribution
name.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.6,
Yuzuha >= 0.1.5.

All 538 tests pass.
Feature release introducing the Geometry dataclass, Kagome lattice support, a full
traversal order naming overhaul, and MPS/MPO text diagram rendering. The geometry
module is restructured into independent per-lattice modules (chain.py, square.py,
kagome.py), and the build_interaction pipeline is extended with an intrcmap_fn hook.
Several breaking changes to the geometry and build_interaction APIs are introduced.

Version: 0.1.2
Release Date: May 11, 2026

New Features:

Geometry Dataclass (geometry.py, chain.py, square.py, kagome.py):
- Geometry dataclass introduced to carry the fully-resolved lattice as a single
  object: cfg (configuration dict), ord_map (tuple-keyed coordinate-to-index map),
  and latt (list of all lattice coordinates).
- build_geometry returns a Geometry instance; build_intrcmap generates the bare
  interaction map from a Geometry, enabling independent reuse without rebuilding
  the lattice.
- Geometry exposes convenience properties: L (chain length), lx, ly, lattice,
  traverse, to_1d, to_2d.

Lattice Modules Refactored (chain.py, square.py):
- 1D chain geometry separated into chain.py with build_traversal and
  intrcmap_1dchain.
- 2D square lattice separated into square.py with build_traversal,
  build_traversal_sequential, build_traversal_serpentine, and intrcmap_square.
- All lattice modules expose build_traversal as a public entry point.

Kagome Lattice (kagome.py):
- intrcmap_kagome generates nearest-neighbor bonds for the 3-sublattice Kagome
  geometry: N2U (upward-triangle) and N2D (downward-triangle) bond families.
- build_traversal supports sequential and serpentine traversal orders.
- ord_map keys are (row, col, u) tuples, where u indexes the sublattice within
  each unit cell.

Traversal Order Naming (square.py, kagome.py, geometry.py):
- 'snake' renamed to 'serpentine'; 'snake' is no longer recognized.
- 'zigzag' renamed to 'sequential'; sequential is now the default traversal for
  all 2D lattices.
- generate_snake_order removed; its logic is now internal to build_geometry's
  serpentine traversal path.

MPS/MPO Text Display (network/display.py, network/network.py):
- network_summary renders a text diagram of an MPS or MPO chain, showing node
  symbols, bond dimensions, and an information block.
- MPS.__repr__ and MPO.__repr__ delegate to network_summary for interactive
  session display.

Operator Templates (system.py):
- Sp4, Sp4dag, Sm4, Sm4dag operator templates added to build_bosonic and
  build_conductor for U(1) symmetry mode, enabling separate raising and lowering
  channels for anisotropic single-channel couplings.

build_interaction Pipeline (interaction.py):
- intrcmap_fn parameter added as an optional second-stage plugin hook; if
  provided, it replaces the built-in intrcmap_* dispatch and receives a Geometry
  instance as its argument.
- geometry_fn signature updated: callers must now return a Geometry instance
  instead of a dict.

Documentation:

API Reference (docs/api/):
- geometry.md: new page documenting the Geometry dataclass.
- build-intrcmap.md: new page documenting the build_intrcmap function.
- intrcmap-kagome.md: new page with traversal tables and bond diagrams for
  the Kagome lattice.
- generate-snake-order.md removed; replaced by updated build-geometry.md.
- build-interaction.md: updated with four-stage pipeline description, intrcmap_fn
  hook section, and updated return-value types.
- mps.md, mpo.md: new string-representation sections with text diagram examples.
- mkdocs.yml: geometry section updated; custom-intrcmap.md added to extensions.

Getting Started and Examples (docs/):
- core-concepts.md: two-stage geometry construction documented in the AutoMPO
  pipeline section.
- custom-geometry.md: updated with Geometry dataclass and separation of geometry
  and interaction map stages.
- custom-intrcmap.md: new extension guide showing how to replace the intrcmap
  stage with a custom bond filter.
- free-fermion.md: NNN hopping section removed; NNN bonds are not supported for
  1D chains.
- All documentation headings standardized to title case.
- changelog.md: version history updated through v0.1.2.

Test Suite (659 tests):
- 659 tests pass, 0 skipped.
- New test files: tests/network/test_display.py (network_summary and
  _select_sites), tests/physics/test_kagome.py (intrcmap_kagome and
  build_traversal for Kagome).

Statistics and Scope:
- 120 commits since v0.1.1.
- 66 files changed: 3478 insertions, 826 deletions.
- Source modules touched: src/alice/__init__.py, src/alice/network/display.py,
  src/alice/network/interaction.py, src/alice/network/network.py,
  src/alice/network/autompo.py, src/alice/network/observe.py,
  src/alice/physics/__init__.py, src/alice/physics/chain.py,
  src/alice/physics/geometry.py, src/alice/physics/kagome.py,
  src/alice/physics/square.py, src/alice/physics/system.py,
  src/alice/algorithm/dmrg/dmrg.py, src/alice/algorithm/dmrg/scheme_2s.py.
- Test modules touched: tests/algorithm/dmrg/conftest.py,
  tests/algorithm/dmrg/test_scheme_1sp.py, tests/diagonaliztn/test_autompo.py,
  tests/network/test_display.py, tests/network/test_network.py,
  tests/physics/test_chain.py, tests/physics/test_geometry.py,
  tests/physics/test_kagome.py, tests/physics/test_models.py,
  tests/physics/test_square.py, tests/physics/test_system.py.
- Docs pages touched: docs/api/geometry/ (7 files), docs/api/interaction/ (2),
  docs/api/network/ (4), docs/api/hamiltonian/ (4), docs/api/ (2),
  docs/examples/extensions/ (4), docs/getting-started/ (5); mkdocs.yml.

Rationale:

The geometry module was originally a single file mixing traversal-order generation,
interaction-map construction, and dispatch logic. Separating these responsibilities
into per-lattice modules makes each module small enough to read in isolation and
allows new lattice types to be added without touching existing code. The Geometry
dataclass formalizes the previously implicit contract between build_geometry and the
intrcmap_* functions: instead of passing raw dicts between stages, callers receive a
typed object with stable properties. Splitting construction into two explicit
stages — build_geometry, which resolves the traversal and coordinate map, and
build_intrcmap, which generates bonds — lets users build multiple interaction maps
for the same lattice without repeating the traversal computation. This is
particularly useful for Kagome, where the 3-sublattice unit cell requires a
three-element tuple key (row, col, u); the old 2D-list ord_map did not generalize
to this structure. The traversal naming overhaul (snake → serpentine, zigzag →
sequential) aligns the public API with the language used in the documentation, and
making sequential the default reflects that column-major ordering is the more
natural starting point for 2D lattices. The intrcmap_fn plugin hook extends the same
compositional philosophy to the bond-generation stage: users can replace only the
part of the pipeline they need to customize without touching the geometry
construction.

Breaking Changes:
- build_geometry return type: now returns a Geometry instance instead of a dict.
  Callers must update references to use Geometry properties (geo.cfg, geo.ord_map,
  geo.latt, geo.L).
- intrcmap_* functions now accept a Geometry instance as their first argument
  instead of a dict. Direct calls to intrcmap_1dchain, intrcmap_square, or
  intrcmap_kagome must pass a Geometry object.
- build_interaction return type: the third element of the returned tuple is now a
  Geometry instance (was int). Callers that used the integer chain length must
  replace it with geo.L.
- geometry_fn signature: custom geometry functions passed to build_interaction must
  now return a Geometry instance, not a dict.
- generate_snake_order has been removed. Use build_geometry with
  traverse='serpentine' to obtain serpentine ordering.
- traverse='snake' is no longer recognized. Replace with traverse='serpentine'.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.6, Yuzuha >= 0.1.5.

All 659 tests pass.
Feature release introducing init_mps, a universal particle-type–agnostic MPS
initializer for DMRG, and atomic per-sweep checkpointing via a new
checkpoint_dir option in dmrg.Options. Network.bond_states is added to expose
physical state counts per bond for non-Abelian simulations. No breaking changes.

Version: 0.1.3
Release Date: May 13, 2026

New Features:

Universal MPS Initializer (automps.py):
- init_mps constructs an initial MPS for DMRG from any (Spc, Op) pair returned
  by load_space. Works for bosonic, fermionic, and conductor sites without a
  particle_type= argument; the (Spc, Op) pair encodes all symmetry information.
- bond_dim=1: deterministic product state with exact charge targeting. Every
  bond carries a single sector; best used with CBE (scheme='1sp') or 2-site
  (scheme='2s') DMRG, which expand bond dimension during the first sweep.
- bond_dim>1: random MPS with group-derived bond sectors. Reachable charges are
  found by breadth-first search from the center-bond charge to depth 2, keeping
  the sector count independent of chain length.
- Auto-balanced config=None heuristic covers all standard even-L half-filled
  cases: alternating high/low sectors for 2-sector spaces, single neutral-charge
  sector for 3-sector spaces, alternating neutral-pair for 4-sector spaces, and
  the SU(2) dimer path for pure-SU(2) spaces. Explicit config lists override the
  auto-selection for unusual fillings or odd L.
- Exported from alice and alice.network public namespaces.

DMRG Checkpointing (dmrg.py):
- New checkpoint_dir option in dmrg.Options: after every completed sweep, the
  current state is serialized atomically to dmrg.ckpt in the specified directory.
  The write first goes to dmrg_lock.ckpt, then is renamed to dmrg.ckpt; on POSIX
  systems the rename is atomic, so a crash during serialization cannot corrupt
  the previous checkpoint.
- Checkpoint file is in PyTorch format and loadable via dmrg.Summary.load.
- checkpoint_dir defaults to None, resolving to the current working directory at
  run() call time (matching the behavior of Options.logging). Stored as str for
  TOML round-trip compatibility.

Network.bond_states (network.py):
- New bond_states property on Network (and hence MPS and MPO): returns the
  number of physical states at each internal bond (list of length L - 1).
  Entry i is index.num_states for the right bond of site i.
- Equal to bond_dims for Abelian groups (U(1), Z(2)). For SU(2) it is larger:
  each multiplet of spin j contributes 2j+1 states, making bond_states the
  physically meaningful truncation measure in non-Abelian simulations.

DMRG Examples (examples_dmrg/):
- dmrg_heisenberg.py, dmrg_freefermion.py, dmrg_conductor.py updated to accept
  an init parameter ('iter_diag' or 'random'), using init_mps for the random
  path. Per-example _random_mps helpers removed.

Documentation:

API Reference (docs/api/network/):
- init-mps.md: new page with parameter table, charge-convention notes, mode
  descriptions, and runnable examples for Heisenberg and free-fermion cases.
- network.md: bond_states property added to Network class reference.
- index.md: init_mps entry added to the Network module index.

Getting Started (docs/getting-started/):
- quick-start.md: updated to use init_mps for MPS construction and the
  Summary.save / dmrg.Summary.load checkpoint interface.
- changelog.md: version history updated through v0.1.3.

Navigation (mkdocs.yml):
- init-mps.md added under the Network section.

Packaging (pyproject.toml):
- Version bumped to 0.1.3.

Test Suite (742 tests):
- 742 tests pass, 0 skipped.
- New test file: tests/network/test_automps.py (77 tests covering TestAutoConfig,
  TestBondCharges, TestReachableCharges, TestProductStateMPS, TestRandomMPS).
- New tests in tests/algorithm/dmrg/test_dmrg.py: TestCheckpoint (6 tests
  covering file creation, lock-file cleanup, load round-trip, default-cwd
  behavior, per-sweep frequency, and TOML round-trip).

Statistics and Scope:
- 18 commits since v0.1.2.
- 18 files changed: 1384 insertions, 188 deletions.
- Source modules touched: src/alice/__init__.py, src/alice/network/__init__.py,
  src/alice/network/automps.py, src/alice/network/network.py,
  src/alice/algorithm/dmrg/dmrg.py.
- Test modules touched: tests/algorithm/dmrg/conftest.py,
  tests/algorithm/dmrg/test_dmrg.py, tests/network/test_automps.py.
- Docs pages touched: docs/api/network/index.md, docs/api/network/init-mps.md,
  docs/api/network/network.md, docs/getting-started/quick-start.md,
  docs/getting-started/changelog.md; mkdocs.yml.

Rationale:

init_mps was introduced because every DMRG example script was reimplementing its
own _random_mps helper with hardcoded charge heuristics that only worked for one
particle type. These helpers were redundant and accumulated subtle differences over
time. init_mps centralizes that logic once: the (Spc, Op) pair from load_space
already carries the group structure, so no particle_type= argument is required, and
the auto-balanced _auto_config heuristic covers all standard even-L half-filled
cases without user input. The BFS-based sector selection for random MPS replaces
the previous per-type hardcoded sector lists with a uniform algorithm that works for
any symmetry group supported by Nicole.

Checkpointing was the last missing piece of the DMRG restart workflow. Summary.load
and Summary.save already existed for post-run storage; checkpoint_dir extends them to
in-run checkpointing so that a simulation interrupted by a wall-time limit or
hardware fault can be resumed from the last completed sweep without losing work. The
atomic write strategy — serialize to a lock file, then rename — ensures the on-disk
checkpoint is always either absent or a complete, valid state; there is no window
during which a partial write can leave a corrupt file.

Breaking Changes: None. All previously valid calls continue to work unchanged.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.6, Yuzuha >= 0.1.5.

All 742 tests pass.
Feature release introducing NormalMPO, an MPO subclass that separates the
physical scale factor from unit-normed internal tensors, and thermal_mpo, which
approximates ρ(β) = exp(−βH) via a truncated Taylor series in MPO arithmetic.
The observe function is extended to compute normalized thermal expectation values
Tr[ρO] / Tr[ρ] when passed a NormalMPO state. No breaking changes.

Version: 0.1.4
Release Date: May 31, 2026

New Features:

NormalMPO (thermal.py):
- New MPO subclass representing scale × mpo, where mpo.norm() ≈ 1 after
  compact() or from_mpo(). Keeps the physical magnitude in _scale, decoupled
  from the internal tensors, so SVD truncation thresholds are always applied on
  a consistent unit scale.
- from_mpo(mpo): clones the input MPO, canonicalizes to site 0, extracts the
  Frobenius norm into _scale, and returns a unit-normed NormalMPO.
- scale property: read-only access to _scale.
- compact(trunc): two-sweep canonicalization that folds the extracted norm into
  _scale instead of redistributing it; restores the standard IN/OUT bond arrow
  convention via capcup after each sweep, required by subsequent oplus and trace
  operations.
- __matmul__ (@ operator): per-site einsum('abrs,cdsu->acbdru') followed by two
  merge_axes calls (right bonds first, then left) maintaining the
  (L, R, phys_in, phys_out) axis order; _scale is the product of the two input
  scales.
- __add__ (+ operator): per-site oplus with relative weight |alpha|^(1/L) per
  site, where alpha = other._scale / self._scale; the sign of alpha is absorbed
  into site 0 to avoid complex fractional powers when Taylor coefficients are
  negative.
- __mul__ / __rmul__ (* operator): updates _scale only; site tensors are
  unchanged.
- Exported from alice.network and the alice top-level namespace.

thermal_mpo (thermal.py):
- Approximates ρ(β) = exp(−βH) via the truncated Taylor series
  ρ(β) ≈ Σ_{n=0}^{N} (−β)^n/n! H^n, where H^0 = I is an L-site identity MPO
  built from the physical space index spc following the same itag convention as
  build_hamiltonian.
- compact() is called after every addition and every power step to control bond
  growth.
- trunc parameter: truncation options forwarded to each compact() call; defaults
  to {'thresh': 1e-14}.
- coeff_thresh parameter: early-stopping threshold on |β^n / n!|; loop exits
  when the coefficient falls below this value. Defaults to 1e-15 (safe for
  double precision).
- The returned NormalMPO carries _scale ≈ Tr[ρ] (the partition function up to
  the MPO norm), so a single trace call suffices to recover Z.
- Exported from alice.network and the alice top-level namespace.

observe Extended for Thermal States (observe.py):
- observe() now dispatches on isinstance(state, NormalMPO) before the generic
  MPO check; passing a plain MPO still raises NotImplementedError with a
  migration note.
- New _observe_thermal helper: forms rho @ NormalMPO.from_mpo(observable),
  calls compact(), and returns Tr[ρO] / Tr[ρ]; raises ZeroDivisionError if
  Tr[ρ] is numerically zero.

Documentation:

API Reference (docs/api/network/):
- normal-mpo.md: new page with mkdocstrings block and Notes covering the
  representation invariant (scale × unit-norm MPO), arithmetic contract, and
  dtype-preservation design of __add__.
- thermal-mpo.md: new page with algorithm, convergence, partition function, and
  thermal expectation value notes.
- index.md: NormalMPO added to the Classes table; thermal_mpo and updated
  observe description added to the Functions table.

Navigation and Changelog (mkdocs.yml, docs/getting-started/changelog.md):
- mkdocs.yml: NormalMPO and thermal_mpo added under the Network nav section.
- changelog.md: version history updated through v0.1.4.

Packaging (pyproject.toml):
- Version bumped to 0.1.4.
- nicole dependency floor raised from >=0.3.6 to >=0.3.7.

Test Suite (740 tests):
- 740 tests pass, 0 skipped.
- New test file: tests/network/test_thermal.py (48 tests across
  TestNormalMPOConstruction, TestNormalMPOTrace, TestNormalMPOMatmul,
  TestNormalMPOAdd, TestThermalMPO, TestFreeFermionThermal).
- tests/network/test_observe.py: error-message assertions updated to match
  revised NotImplementedError and TypeError text in observe().

Statistics and Scope:
- 15 commits since v0.1.3.
- 11 files changed: 1254 insertions, 12 deletions.
- Source modules touched: src/alice/network/thermal.py,
  src/alice/network/observe.py, src/alice/network/__init__.py.
- Test modules touched: tests/network/test_thermal.py,
  tests/network/test_observe.py.
- Docs pages touched: docs/api/network/normal-mpo.md,
  docs/api/network/thermal-mpo.md, docs/api/network/index.md,
  docs/getting-started/changelog.md; mkdocs.yml, pyproject.toml.

Rationale:

Accumulating the Taylor series on unnormalized MPO tensors causes rapid overflow
or underflow as H^n grows or decays with n. NormalMPO decouples the physical
magnitude from the truncation logic: keeping site tensors at unit norm means the
SVD threshold in compact() is always relative to the largest singular value of
the normalized operator, independent of the overall scale. The dtype-preservation
decision in __add__ — computing |alpha|^(1/L) and absorbing the sign of alpha
into site 0 — is necessary because a negative base with a fractional exponent
would silently promote float64 tensors to complex128, causing dtype mismatches in
subsequent __matmul__ calls. The capcup loop at the end of compact() is also
non-obvious: Nicole's QR/SVD sweeps may reorient bond arrows, and both oplus
(used in __add__) and the transfer-matrix einsum (used in trace) assume the
standard IN/OUT convention.

The thermal_mpo implementation calls compact() after every addition and every
power step rather than only at the end. This keeps bond dimensions bounded
throughout the accumulation loop rather than allowing them to grow unboundedly
until a final compression pass. The early-stopping condition on the Taylor
coefficient magnitude provides an automatic, quantitative convergence check that
is independent of both chain length and the value of the order argument.

Breaking Changes: None. All previously valid calls continue to work unchanged.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.7, Yuzuha >= 0.1.5.

All 740 tests pass.
Patch release with two targeted improvements: DMRG environment-block caching is
made safe for concurrent runs by isolating each invocation in a unique
subdirectory, and the early-stopping criterion in thermal_mpo is corrected to
test the actual contribution magnitude rather than the bare Taylor coefficient.
No breaking changes.

Version: 0.1.5
Release Date: June 8, 2026

Bug Fixes:

DMRG Environment Cache Isolation (dmrg.py):
- run() previously wrote all cached environment blocks to a fixed left/ and
  right/ path directly inside env_cache_dir. Two concurrent DMRG jobs sharing
  the same Options (and hence the same env_cache_dir) would read and overwrite
  each other's blocks, silently corrupting both runs.
- run() now generates a unique subdirectory (first 8 hex characters of a UUID4,
  e.g. env_cache_dir/a1b2c3d4/) on entry and removes it in a finally block on
  return or exception. The left/ and right/ subdirectories are created inside
  this unique path. shutil.rmtree with ignore_errors=True is used for cleanup
  so that a partially-written or already-deleted directory does not mask the
  exception from the sweep loop.
- Options.env_cache_dir docstring updated to document the subdirectory scheme
  and the automatic cleanup guarantee.

thermal_mpo Early-Stopping Correction (thermal.py):
- The early-stopping guard previously tested abs(coeff) < coeff_thresh, where
  coeff = (-beta)^n / n!. For Hamiltonians with large operator norm, H_pow.scale
  (the Frobenius norm of H^n tracked by NormalMPO) can be many orders of
  magnitude larger than 1, so the actual n-th term contribution
  abs(coeff) * H_pow.scale remained significant long after the bare coefficient
  fell below coeff_thresh. The loop exited too early, silently underestimating
  exp(-beta * H) for any Hamiltonian whose operator norm exceeds 1.
- The guard is now abs(coeff) * H_pow.scale < coeff_thresh, using the scale
  already maintained by the NormalMPO representation at zero extra cost.
- A conditional that skipped the H_pow update step when the next coefficient was
  small has been removed. H_pow is now always advanced when n < order; the
  decision to exit is made at the top of the following iteration with the
  corrected criterion.
- order and coeff_thresh parameter docstrings updated to describe the corrected
  stopping condition.

Test Suite (795 tests):
- 795 tests pass, 0 skipped.
- New test class TestEnvCache in tests/algorithm/dmrg/test_dmrg.py (4 tests:
  test_unique_subdir_removed_on_success, test_unique_subdir_created_inside_cache_dir,
  test_two_runs_use_distinct_subdirs, test_no_leftover_files_after_two_runs).
- New test test_env_cache_dir_toml_round_trip added to TestOptions in
  tests/algorithm/dmrg/test_dmrg.py.

Statistics and Scope:
- 5 commits since v0.1.4.
- 5 files changed: 185 insertions, 18 deletions.
- Source modules touched: src/alice/algorithm/dmrg/dmrg.py,
  src/alice/network/thermal.py.
- Test modules touched: tests/algorithm/dmrg/test_dmrg.py.
- Docs pages touched: docs/getting-started/changelog.md.
- Packaging: pyproject.toml (version bumped to 0.1.5).

Rationale:

The cache-isolation bug was latent because most DMRG workflows run a single job
at a time. The collision surface only appears when multiple jobs share a config
file or a shared scratch directory — a common pattern in batch-job environments.
Using a UUID subdirectory is the minimal fix: it requires no coordination between
processes, works across NFS and local filesystems, and is invisible to callers
because the subdirectory is created and removed entirely inside run().

The thermal_mpo stopping condition was wrong by construction. The early-stopping
literature for Taylor-series MPO expansions checks the actual term magnitude, not
the scalar coefficient, precisely because MPO norms grow with chain length and
expansion order. The NormalMPO representation already carries the running Frobenius
norm in H_pow.scale, making the corrected check a one-character change. The
redundant conditional on the power-update step was defensive code that became
incorrect once the stopping condition was changed: it could skip updating H_pow on
an iteration where the corrected criterion would not exit, leading to a stale power
on the next iteration.

Breaking Changes: None. All previously valid calls continue to work unchanged.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.7, Yuzuha >= 0.1.5.

All 795 tests pass.
Enhancement release extending init_mps with a target_qn parameter for explicit
quantum-number targeting, fixing a silent zero-MPS bug in random MPS
initialization for odd-L chains, and upgrading the warning pathway in automps
from warnings.warn to structured logging. No breaking changes.

Version: 0.1.6
Release Date: June 10, 2026

Enhancements:

init_mps target_qn Parameter (automps.py):
- New keyword argument target_qn on init_mps: specifies the desired
  right-boundary charge Q[L] (total quantum number of the chain). Defaults to
  None, which resolves to Q_vac (half-filling), preserving existing behavior
  for even-L half-filled cases.
- Both modes honor target_qn. Product-state mode (bond_dim=1): _auto_config
  targets target_qn; the right boundary is always Q[L] from the resulting
  charge path (rigid). Random-MPS mode (bond_dim>1): _auto_config targets
  target_qn to obtain a physically appropriate center-bond charge, and the
  right boundary index is explicitly pinned to target_qn, decoupling the
  boundary from the path.
- When an explicit target_qn is given and the auto-config cannot reach it
  (e.g. target_qn=0 for odd-L spin-1/2), init_mps raises ValueError in both
  modes rather than silently constructing an MPS in the wrong sector.

Odd-L Random MPS Fix (automps.py):
- Bug fixed: _random_mps previously pinned both boundary indices to Op['vac']
  (charge Q_vac). For odd L, no config can return the bond charge to Q_vac in
  an odd number of fusion steps, so every charge block of the last tensor was
  forbidden. The MPS canonicalized to zero without raising any error.
- The right boundary index is now constructed with effective_right = Q[L]
  (the actual end charge of the auto-config path) when target_qn was not given
  explicitly. For even L this is still Q_vac; for odd L it is the correct
  non-vacuum charge, producing a non-zero MPS in the expected sector.
- The Op parameter of _random_mps has been removed (no longer needed); the
  left boundary is built from Q[0] and the right boundary from target_qn or
  effective_right.

_auto_config Generalization (automps.py):
- _auto_config now accepts target_qn; all three internal strategies
  (single-sector fill, period-2 alternation, greedy fallback) target target_qn
  instead of Q_vac. The period-2 strategy no longer applies a per-period
  shortcut — the full length-L path is checked against target_qn, making it
  correct for any target.
- The function is now a pure helper with no side effects; the sole warning
  site is init_mps.

Warning System Upgrade (automps.py):
- init_mps no longer calls warnings.warn(UserWarning) when the auto-config
  cannot close to Q_vac (e.g. odd L). The message is now emitted via
  logging.getLogger(__name__), consistent with Alice's structured logging
  infrastructure. Module-level import warnings replaced by import logging and
  a logger = logging.getLogger(__name__) instance.

Documentation:

API Reference (docs/api/network/init-mps.md):
- New Logic Overview section: ASCII decision diagram showing how target_qn,
  config, Q[L], and bond_dim interact inside init_mps, including the
  effective_right asymmetry between product-state and random-MPS modes.
- New Odd-chain lengths section: explains the default WARNING behavior, the
  target_qn fix path, and the ValueError guard; includes a runnable spin-1/2
  U(1) example for L=7.
- Bond Sectors in Random Mode section updated: clarifies that the BFS is
  seeded from Q_c = Q[L//2] of the targeted auto-config, not from Q_vac.
- Charge Conventions note updated: center-bond charge is zero only for even L
  with a balanced auto-config.

Changelog (docs/getting-started/changelog.md):
- Version history updated through v0.1.6.

Test Suite (814 tests):
- 814 tests pass, 0 skipped.
- New TestAutoConfigTargetQn (4 tests): verifies that _auto_config reaches an
  explicit target_qn exactly, covering odd and even L across Spin U1 and
  Ferm U1 spaces.
- New TestInitMpsOddL (3 tests): regression tests for the zero-MPS bug —
  checks non-zero norm, correct right-boundary charge, and WARNING emission
  across all standard physical spaces for odd L.
- New TestTargetQn (7 tests): end-to-end tests for the target_qn keyword on
  init_mps, covering both modes, even/odd L, negative targets, and ValueError
  on unreachable sectors.

Statistics and Scope:
- 7 commits since v0.1.5.
- 5 files changed: 484 insertions, 89 deletions.
- Source modules touched: src/alice/network/automps.py.
- Test modules touched: tests/network/test_automps.py.
- Docs pages touched: docs/api/network/init-mps.md,
  docs/getting-started/changelog.md.
- Packaging: pyproject.toml (version bumped to 0.1.6).

Rationale:

The zero-MPS bug for odd-L random initialization was silent by construction: no
exception was raised during init_mps itself. The MPS canonicalized to zero, and
the error only surfaced inside the Davidson eigensolver when the initial trial
vector had zero norm, producing a zero-division rather than an informative
initialization error. The root cause was that _random_mps always used Op['vac']
for the right boundary index, which carries Q_vac. For even L the auto-config
closes exactly at Q_vac, so every charge block of the last tensor has a valid
assignment. For odd L the charge path ends at Q[L] != Q_vac, so the right
boundary and the accumulated path are in different sectors and Nicole's
block-sparse engine produces an all-zero tensor. Using Q[L] as the effective
right boundary is the minimal correct fix: it requires no additional user input
and is provably correct for all L, because Q[L] is always the charge the path
actually reaches.

The target_qn parameter addresses a separate limitation: before this release,
init_mps had no way to request a specific quantum number sector for doped or
odd-L systems — the only alternative was passing an explicit config list, which
requires the caller to know the charge arithmetic. target_qn delegates that
arithmetic to _auto_config, which already understands group fusion rules. The
ValueError path for unreachable targets gives immediate, actionable feedback
instead of raising an opaque Nicole index-mismatch error inside the
canonicalization sweep.

Breaking Changes: None. All previously valid calls continue to work unchanged.
Existing calls to init_mps without target_qn behave identically to v0.1.5 for
even-L chains. Odd-L chains no longer silently produce a zero random MPS.

Requirements: Python >= 3.11, PyTorch >= 2.5, Nicole >= 0.3.7, Yuzuha >= 0.1.5.

All 814 tests pass.
Add `alice.algorithm.two_site_bug`, a gate-based two-site BUG
(Basis-Update & Galerkin) integrator for real- and imaginary-time
evolution of an MPS under a nearest-neighbour Hamiltonian. It is built
entirely on the existing Alice/Nicole stack (MPS, the AutoMPO interaction
list, decomp, the PyTorch backend) and adds no new tensor infrastructure.

- run(mps, interactions, opts): even/odd Trotter sweeps of two-site bond
  gates with a truncated-SVD split that adapts the bond dimension; Lie
  (first-order) and Strang (second-order) steps, plus imaginary-time cooling.
- Bond gates reuse the AutoMPO interaction list: each nearest-neighbour
  Interaction2Site's leading/terminal tensors are contracted over their
  operator channel and exponentiated block-wise on the PyTorch backend,
  preserving the symmetry block structure exactly.
- Options (TOML-loadable) and Summary mirror the DMRG interface; Summary
  records per-step kept and proposed (augmented) bond dimensions.
- Tests validate against exact diagonalization: state fidelity, exact norm
  conservation, U(1) charge conservation, and second-order Trotter scaling.
- Docs: API reference pages, nav entry, and changelog.

ruff check passes; full suite: 835 passed.
Replace the gate-based two-site update with the faithful rank-adaptive
Basis-Update & Galerkin (Ceruti–Kusch–Lubich) K/L/S local bond update.

- Vendor the Nicole-native, symmetry-aware faithful-KLS kernel under
  `_kernel/` (K-augment, L-augment, Galerkin S-step with Krylov expv).
- Alice bridge: bond Hamiltonians from the AutoMPO interaction list (bond.py),
  canonical MPS snapshot + odd/even Strang sweep (scheme.py) driving the kernel.
- Remove the gate-based propagator path (gate.py and its tests).
- `trunc_thresh` (S-step SVD threshold) controls how far each bond grows; the
  per-step discarded weight is tracked in `Summary.disc_weights`.
- Tests: full-phys domain wall vs exact diagonalization (1 - F ~ 1.9e-8 at
  dt = 0.05, clean 2nd-order Strang), U(1) Sz and norm conservation, and
  imaginary-time cooling.
@madhavmen
madhavmen force-pushed the feature/two-site-bug branch from 0d5c1a5 to 686cd0e Compare June 19, 2026 22:52
madhavmen and others added 6 commits June 20, 2026 10:00
A rank-adaptive BUG variant derived from the faithful Ceruti-Kusch-Lubich
scheme, differing only in the local bond update: the discarded
(orthogonal-complement) projector is applied to the K/L generator before the
exponential (project-before), and the basis is grown by a plain direct sum
[U0 | Qk] / [V0 ; Ql] with no augmented overlap matrices. The project-before
generator is non-Hermitian, so the K/L substep uses a symmetry-preserving
tensor Arnoldi exponential; the Hermitian S-step reuses the faithful kernel's
tensor Lanczos. The odd/even Trotter sweep, AutoMPO bond Hamiltonians, and
Options/Summary are reused unchanged from two_site_bug, so only the per-bond
candidate is new.

Validated on the symmetric Heisenberg chain against exact diagonalization
(state fidelity, O(dt^2) Strang convergence, norm and total-Sz conservation,
rank growth, imaginary-time cooling) — 22 tests.

Adds the discarded_bug package and tests, docs/api/discarded-bug pages with
mkdocs nav and api/index entries (and the previously missing two-site-bug
overview section), a changelog entry, and the module exports.
Reimplement the discarded-projector BUG as the MPS specialisation of the Lubich
tree-tensor-network BUG. Like two-site TDVP and DMRG it takes a Hamiltonian MPO and
exponentiates the two-site effective Hamiltonian with the left/right MPO environments
(no Trotter splitting), reusing the DMRG environment machinery; it is inverse-free.

A step recursively bisects the chain — the MPS realisation of the reference's
balanced-binary-tree Step (the tree is built by recursive bisection of the 1D modes).
At each bisection bond the two-site block is evolved once, the K-step and L-step grow
the left/right frames with the discarded projector (qr([Theta1_left|U0]) /
qr([Theta1_right;V0]), no augmented overlap matrices), and the Galerkin core is the
projection of the evolved block, SVD-truncated. Frames are read off the evolved block
so a product-state interface grows its genuine rank-2 entanglement. Because every bond
is a tree node, the bond dimension grows along the whole chain (the full ballistic
light cone) as a domain wall melts.

The step is first order in dt with no backward substep; the validated property is the
rank growth / light-cone spread. Everything stays in the U(1) block-sparse Nicole
representation so the kept rank respects the charge sectors.

- Replace the per-bond Trotter/KLS scheme.py with the recursive-bisection sweep.py and
  the symmetry-aware block_local_update in candidate.py; vendor the Krylov expv.
- run(mps, mpo, opts) on a Hamiltonian MPO; Options/Summary mirror the DMRG interface.
- Tests cover the full light-cone growth (peaked profile to 2**(L/2)), first-order
  single-step convergence, that the forward-only error does not shrink with dt, and
  norm / U(1) / imaginary-time conservation, all vs exact diagonalization.
- Update the API docs and changelog to the MPO recursive-bisection scheme.
Replace the recursive-bisection / block-evolution scheme with a single global
Basis-Update & Galerkin sweep (mirror of the Julia port): form phi = H*psi via
mpo_times_mps, build augmented left/right isometries that keep psi exact and admit
only the discarded part (I - U0 U0^dagger) phi per basis matrix (symmetry-blocked),
then integrate one Galerkin centre tensor under the two-site effective Hamiltonian.
No M/N overlap matrices, no backward substep. Exact at full bond dimension, 2nd
order and convergent under truncation.

- sweep.py: mpo_times_mps + k_sweep + l_sweep + global_step; the two-site effective
  apply and centre truncation/assembly helpers folded in.
- candidate.py: deleted (block_local_update / bond_snapshot / augmenters removed).
- discarded_bug.py, __init__.py: docstrings updated to the global sweep.
- tests: validate vs exact diagonalisation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants