compute_continuation_ranks#
- t3toolbox.backend.ranks.compute_continuation_ranks(shape, tucker_singular_values, tt_singular_values, tau=10.0, n_chunk=1, kappa_guard=1000000000000.0, max_grow=None, sharing=None)#
def compute_continuation_ranks( shape: typ.Sequence[int], # (N0, ..., N(d-1)) tucker_singular_values: typ.Sequence[NDArray], # len=d, elm_shape=(n_i,), descending tt_singular_values: typ.Sequence[NDArray], # len=d+1, elm_shape=(r_i,), descending tau: float = 10.0, # grow edge i only if kappa_i < kappa_max / tau (tau > 1) n_chunk: int = 1, # rank increment added to each grown edge kappa_guard: float = 1e12, # absolute safety cap: never grow an edge with kappa_i >= this max_grow: typ.Optional[int] = None, # cap on #edges grown per call (None = all eligible) sharing: typ.Optional[typ.Sequence] = None, # len=d, static; one hashable group label per mode (None = unshared) ) -> typ.Tuple[ typ.Tuple[int, ...], # (n0', ..., n(d-1)') new Tucker ranks typ.Tuple[int, ...], # (r0', ..., rd') new TT ranks ]:
Rank-continuation update: choose new ranks from the current iterate’s unfolding singular values.
Section 5.4.1 (“Choosing the new ranks”) of Alger et al. (2026), “Tucker Tensor Train Taylor Series” (arXiv:2603.21141). Grow only the well-conditioned edges – those a factor
taubelow the worst-conditioned edge – so the increases bring all edges toward comparable conditioning:n_i' = n_i + n_chunk if kappa^Tucker_i < kappa_max / tau else n_i r_i' = r_i + n_chunk if kappa^TT_i < kappa_max / tau else r_i
with
kappa_maxthe largest (finite) edge condition number (edge_condition_numbers()). The current ranksn_i = len(tucker_singular_values[i])andr_i = len(tt_singular_values[i])are read off the provided singular values, so pass the structural-rank T3-SVD output (t3svd()with no truncation); a truncated SVD instead grows from the numerical rank. The boundary TT bondsr_0, r_dare never grown.Warning
Do not pass uniform (``ut3svd``) singular values here. This is a ragged, host-side function and it infers the current ranks from
len(s[i]). Uniform spectra are padded to the supercore’s nominal rank, so everylenis the padded width rather than the true rank, and the padding zeros makekappa_iinfinite – the call type-checks and returns silently wrong ranks (in a measured case((2,2,2),(1,2,2,1))where the truth was((3,3,3),(1,3,3,1)), i.e. a spurious “stop continuing”). Rank continuation is deliberately a ragged-layer activity: run the bookkeeping on the ragged point and drop into the uniform layer only for the fit itself (docs/rank_continuation.md, “On the uniform layer”).Proposed ranks are then de-degenerated by
compute_minimal_ranks()(the paper’s “useless-rank removal” – shape and ranks only, no linear algebra); if that leaves the ranks unchanged (every edge already comparably conditioned, or all increases removed) every (below-guard) rank is bumped byn_chunkand re-cleaned, so continuation makes progress unless the structure is already maximal.Absolute conditioning guard (
kappa_guard, a numerical safety net distinct from the relativetaurule): an edge is grown only ifkappa_i < kappa_guardas well – so an edge that is well conditioned relative to a catastrophic edge but ill conditioned in absolute terms is still frozen. If no edge is below the guard (every growable edge is extremely ill conditioned or rank-deficient), nothing grows and the returned ranks equal the input ranks – the caller’s signal to stop the whole continuation. The default1e12is large: it should fire only on genuine near-degeneracy, never during a well-behaved fit. (Note “ranks unchanged” is also returned when the structure is already maximal; both mean “stop”. The caller can calledge_condition_numbers()to tell the two apart for reporting.)Edges per round (
max_grow):None(default) grows every eligible edge at once – the Section 5.4.1 rule. An integerkgrows only thekbest-conditioned eligible edges that survive useless-rank removal (greedy, smallest condition number first, skipping a structurally-capped edge for the next candidate).max_grow=1is one edge at a time (thetau -> infinityintent, made robust against the spectrum-dependence and structural caps that make a largetauunreliable); pair it withtau=1.0to grow the single best-conditioned edge each round regardless of the conditioning spread. The uniform-bump fallback is not capped bymax_grow, so continuation can still escape a degenerate start (e.g. all-ones, where no single edge can grow – a Tucker rank and its neighboring bond must grow together).The paper uses
tau = 10.0and typicallyn_chunk = 1. Pure host arithmetic on ranks (structure), hence numpy-only – a between-solves decision, never inside a jit trace.With
sharing(one hashable group label per mode –validate_sharing()), a sharing group’s Tucker edges are ONE edge: the group modes must carry the IDENTICAL spectrum (the group spectrums_g, as the groupedt3svdreports at every group mode; a mismatch raises – unequal spectra are not a shared spectrum family), the group contributes onekappa_g = s_g[0]/s_g[-1]to the pool, one growth decision applies group-wide (kappa_guardguardskappa_g;max_growcounts the group as ONE candidate; the uniform-bump fallback bumps the group once), and useless-rank removal is the shared one (compute_minimal_ranks()withsharing– the group ceiling, so a shared rank is never clipped to a single mode’s local ceiling).s_gis representation-independent – the singular values of the concatenated matricization[T_(i1)|...|T_(ik)], equivalently the Jacobian spectrum of a gauged tied motion of the shared factor (seeSharedFrameData) – sokappa_gis exactly the conditioning of the tied Tucker subproblem, playing the same role the per-edge condition number plays for unshared edges in Section 5.4.1. It is never worse than the group’s worst per-mode condition number, and can be far better (under tying, a direction is well-determined if SOME mode of the group informs it); thesqrt(k)scale inflation ofs_gcancels in every ratio, so group and singleton edges compete fairly in one pool. Cf. Molozhavenko & Rakhuba (2026, SF-ETT); the shared-factor format originates with SF-Tucker (Peshekhonov, Arzhantsev & Rakhuba, 2024).- Parameters:
shape (t3toolbox.backend.common.typ.Sequence[int])
tucker_singular_values (t3toolbox.backend.common.typ.Sequence[NDArray])
tt_singular_values (t3toolbox.backend.common.typ.Sequence[NDArray])
tau (float)
n_chunk (int)
kappa_guard (float)
max_grow (t3toolbox.backend.common.typ.Optional[int])
sharing (t3toolbox.backend.common.typ.Optional[t3toolbox.backend.common.typ.Sequence])
- Return type:
t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Tuple[int, …], t3toolbox.backend.common.typ.Tuple[int, …]]