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)#
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)
) -> 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 tau below 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_max the largest (finite) edge condition number (edge_condition_numbers()). The current ranks n_i = len(tucker_singular_values[i]) and r_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 bonds r_0, r_d are never grown. 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 by n_chunk and re-cleaned, so continuation makes progress unless the structure is already maximal.

Absolute conditioning guard (kappa_guard, a numerical safety net distinct from the relative tau rule): an edge is grown only if kappa_i < kappa_guard as 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 default 1e12 is 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 call edge_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 integer k grows only the k best-conditioned eligible edges that survive useless-rank removal (greedy, smallest condition number first, skipping a structurally-capped edge for the next candidate). max_grow=1 is one edge at a time (the tau -> infinity intent, made robust against the spectrum-dependence and structural caps that make a large tau unreliable); pair it with tau=1.0 to grow the single best-conditioned edge each round regardless of the conditioning spread. The uniform-bump fallback is not capped by max_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.0 and typically n_chunk = 1. Pure host arithmetic on ranks (structure), hence numpy-only – a between-solves decision, never inside a jit trace.

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])

Return type:

t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Tuple[int, Ellipsis], t3toolbox.backend.common.typ.Tuple[int, Ellipsis]]