feat(mps): linear-combination SRC apply and SRC-based rounding - #493
Merged
Conversation
Generalize the successive-randomized-compression sweep to a coefficient-weighted sum of MPO-MPS products, sharing each site's Gaussian block across terms (a correctness requirement: the summed panel is then exactly the sketch of the summed operand). Per-term environment stores and caps; one shared incremental QR and stopping test; coefficients enter only the panel summation and the deterministic site assembly, with a coefficient-one bypass keeping the single-pair wrapper bit-identical to the previous kernel. Zero-weighted terms are pruned up front and an all-zero coefficient list yields the bond-dimension-1 zero state. New public surface: apply_sum_successive_randomized, the SumTerm alias, Mpo::identity (dense delta sites), and the in-place Mps::round_successive_randomized, which rounds a state adaptively by running the SRC sweep against a per-call identity MPO. Block-sparse arms panic with the existing dense-only wording. The kernel module splits its environment machinery (env.rs) and term-list handling (terms.rs) into submodules, and the dispatch free functions move to dispatch/entries.rs.
The all-zero-coefficient fast path returned every site as a zero tensor
while claiming Mixed { center: 0 }; zero off-center sites are not
right-isometries, and downstream consumers (truncate among them) trust
the canonical-form metadata and skip re-canonicalization. Only the
center site is zero now; off-center sites are normalized basis tensors,
so the claimed form holds structurally while the state stays zero.
Qualify the ApplyMethod intra-doc link that broke when dispatch.rs stopped importing the enum, add round_successive_randomized to the inherent-method inventory in lib.rs, and update the bench module doc's arm count for the new sum arm.
Add the SRC sum free function and the rounding inherent method to the MpsOps trait doc's forwarding inventory, and document the reachable zero-physical-dimension panic that rounding inherits from the identity MPO construction.
There was a problem hiding this comment.
Pull request overview
This PR extends the dense successive randomized compression (SRC) MPO–MPS apply path to support coefficient-weighted sums of multiple MPO–MPS terms in a single shared-Gaussian right-to-left sweep, and adds SRC-based adaptive in-place MPS rounding implemented via applying a per-call identity MPO.
Changes:
- Generalize the SRC sweep core to a multi-term kernel with shared Gaussian sketch blocks, per-term environments/caps, and coefficient-weighted panel/site assembly.
- Introduce new public API surface:
apply_sum_successive_randomized,SumTerm,Mpo::identity, andMps::round_successive_randomized, plus sealed-trait dispatch wiring. - Add comprehensive tests for multi-term correctness (including cancellation/zero-coefficient behavior) and rounding, and extend the existing apply benchmark with a two-term “sum” arm.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ariadnetor-mps/tests/mps/helpers.rs | Adds dense relative-error helper and a generic site-scaling helper; updates identity MPO test helper to call Mpo::identity. |
| crates/ariadnetor-mps/tests/mps/apply_successive_randomized.rs | Refactors existing SRC tests to reuse new helpers (relative_frobenius, with_site_scaled). |
| crates/ariadnetor-mps/tests/mps/apply_src_sum.rs | New test suite covering SRC sum apply + SRC-based rounding + validation panics. |
| crates/ariadnetor-mps/tests/mps.rs | Registers the new apply_src_sum test module. |
| crates/ariadnetor-mps/src/types.rs | Adds SumTerm alias, implements Mpo::identity, and updates ApplyError/SRC param docs for new SRC entry points. |
| crates/ariadnetor-mps/src/lib.rs | Re-exports the new public entry apply_sum_successive_randomized and SumTerm; documents round_successive_randomized as inherent. |
| crates/ariadnetor-mps/src/dispatch/entries.rs | New module holding multi-arg public free functions, including apply_sum_successive_randomized. |
| crates/ariadnetor-mps/src/dispatch.rs | Adds sealed-trait entrypoints for sum apply + rounding; wires new entries module; implements dense and block-sparse (panic) arms. |
| crates/ariadnetor-mps/src/apply/successive_randomized/env.rs | New module for per-term environment storage and sketch-panel contraction, supporting shared-Gaussian multi-term recursion. |
| crates/ariadnetor-mps/src/apply/successive_randomized/terms.rs | New module for term validation, zero-coefficient pruning, and coefficient-weighted tensor summation with single-term bypass. |
| crates/ariadnetor-mps/src/apply/successive_randomized.rs | Refactors SRC sweep into multi-term kernel and restores single-term behavior via coefficient-one wrapper/bypass. |
| crates/ariadnetor-mps/src/apply/mod.rs | Re-exports the new dense sum-SRC kernel from the apply module. |
| crates/ariadnetor-algorithms/benches/mpo_mps_apply.rs | Adds a “sum” benchmark arm to exercise the new sum entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The multi-term rank caps (default max_dim and the per-site left-rank sum) now use saturating arithmetic: a wrapped sum would masquerade as a small cap and silently truncate ranks, while saturation pins at effectively unbounded. The test-side relative-error helper asserts a nonzero reference norm instead of returning inf/NaN.
This was referenced Jul 20, 2026
This was referenced Jul 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends successive randomized compression (SRC, arXiv:2504.06475) with the two extensions tracked as phase 3 of #469: a linear-combination apply computing$\eta \approx \sum_t c_t\, H_t \psi_t$ in one right-to-left sweep with each site's Gaussian block shared across the terms, and adaptive MPS rounding that runs the SRC sweep against a per-call identity MPO. Sharing the Gaussians is a correctness requirement, not an optimization: the coefficient-weighted sum of the terms' sketches is then exactly the sketch of the summed operand, so the paper's single-pair guarantees (exactness with probability one at the representable rank, validity of the leave-one-out error estimate) transfer verbatim — with independent per-term draws a cancelling sum would sketch as nonzero. Closes #492.
Changes
crates/ariadnetor-mps/src/apply/successive_randomized.rs— the sweep core generalizes to a multi-term kernel: one sketch-environment store and one cap (the running right environment closing a term's remaining network against the assembled output basis) per term, one shared incremental QR and stopping test over the summed sketch panels (the per-round blocks of sketch columns), coefficients entering only the panel summation and the deterministic site assembly — never the caps, which the shared basis projects at every later site. The single-pair kernel behindApplyMethod::SuccessiveRandomizedbecomes a coefficient-one wrapper whose output is bit-identical to the previous implementation at equal seeds. Environment machinery and term-list handling split into theenv.rs/terms.rssubmodules.crates/ariadnetor-mps/src/types.rs—Mpo::identity(denseSumTermterm alias.crates/ariadnetor-mps/src/dispatch.rs+dispatch/entries.rs— new sealed-trait methods with panicking block-sparse arms, the public free functionapply_sum_successive_randomized, and the inherent in-placeMps::round_successive_randomized; the multi-arg free functions move todispatch/entries.rs.crates/ariadnetor-algorithms/benches/mpo_mps_apply.rs— a two-term Heisenbergsumarm in the existing case grid (reachability of the new entry; no performance claim).Impact
New public surface in
ariadnetor-mps:apply_sum_successive_randomized,SumTerm,Mpo::identity, andMps::round_successive_randomized, plus the two sealed-trait methods backing them. Existing entry points keep their signatures and numerical output.ApplyErrordocs now enumerate the new SRC-based reporters ofNonFinitealongsideApplyMethod::SuccessiveRandomized.Test plan
apply_with_methodentry withApplyMethod::SuccessiveRandomizedat the same seed, pinning both the RNG-stream preservation of the shared-Gaussian refactor and the coefficient-one arithmetic bypass.sketch_increment) of the rank bound set by the state-space dimensions on each side of the cut, preserves the state, and returnsMixed { center: 0 }with right-canonical sites.Mpo::identityinvariance under a lossless apply and its zero-dimension panic.cargo make gategreen (fmt-check, clippy-D warningsover all targets, workspace tests and doctests); rustdoc with-D warningsclean.Notes
Plan-vs-actual delta
Everything in #492's Scope landed; the deltas are additions.
Scope additions:
0 * inf; the pruning matches the paper authors' companion implementation (TNrandNLA).Mixed { center: 0 }structurally true — zero tensors are not isometries, andMps::truncatetrusts the stamped form and skips re-canonicalization (the all-zero test now asserts right-isometry).SumTermpublic alias, replacing the raw term-slice tuple type that clippy'stype_complexitylint rejects in signatures.terms.rs(term validation / pruning / combiner) anddispatch/entries.rs(the pre-existing free functions), keeping every source file within the committed line-count hook's limit (scripts/check-file-lines.sh; 600 lines for non-test sources).relative_frobenius/with_site_scaledpromoted to the shared helpers module;make_identity_mponow delegates toMpo::identity.Scope subtractions: none. The Out of scope set is unchanged — the identity-specialized kernel, the MPO-free linear combination, and block-sparse support all remain deferred to #469.
Acceptance recalibration: "rounding reduces inflated bonds" holds, but the adaptive sweep only observes rank deficiency one
sketch_incrementafter the bond has grown past the true rank, so the final bond can exceed that rank by up to one increment. The rounding test therefore pins the bond to within onesketch_incrementof the dimension-counting rank bound (tested withsketch_increment = 1), together with the clamp of the output bond to the site's fused row count, rather than pinning the exact rank.