The frame-variations representation (and why the cores are numbered as they are)#

A tangent vector to the fixed-rank manifold is stored as a frame plus variations (T3Frame + T3Variations, bundled as a T3Tangent). This note explains what those cores mean, why there are d of each but d+1 rank/bond indices, and why the variations behave like plain coordinates — which is what makes corewise linear algebra (and the weighted metric, T3FrameWeights) work.

A tangent is a sum of d terms#

The key picture: a tangent vector is the sum of d tensor-train diagrams, each with one variation core (in parentheses) surrounded by frame cores:

1--(H0)--R1---R2--1     1---L0--(H1)--R2--1     1---L0---L1--(H2)--1
    |    |    |             |    |    |             |    |    |
    U0   U1   U2            U0   U1   U2            U0   U1   U2

(plus a matching set with the Tucker variation (Vᵢ) in place of Uᵢ.) The frame cores encode the base point — where the tangent space attaches to the manifold — and the variation cores encode the tangent direction relative to that frame. There are four frame families and two variation families:

frame core

symbol

role

rank on its legs

up-Tucker Uᵢ

U

the Tucker factors (retained directions)

nU

down-TT Oᵢ

O

the Tucker complement (where V varies)

nD

left-TT Lᵢ

L/P

left environment (left of the variation)

rL

right-TT Rᵢ

R/Q

right environment (right of the variation)

rR

tucker-variation Vᵢ

V

Tucker-factor direction (in the nD complement)

nD

tt-variation Hᵢ

H

TT-core direction

nU, rL, rR

d cores, d+1 bonds — and the “extra” Ld, R0#

Each family has d cores (U0…U(d-1), L0…L(d-1), …), but the TT bonds run rL0 rLd and rR0 rRdd+1 of them. Mathematically there are only d natural left/right cores: in the diagrams above, Ld and R0 are never used (the leftmost term needs no left environment; the rightmost needs no right environment).

So why keep them? To give the base point a home. A frame is meant to remember the point it was constructed at, and that point is stored as a single extra variation term — the base point written as a gauged tangent, v_X, whose only nonzero variation is the last TT variation (= P_last, the Ld-adjacent slot). Keeping the padding Ld / R0 cores means:

  • there is a canonical, non-arbitrary place to put the base-point term (rather than picking one of the d cores by fiat), so T3Tangent.to_t3(include_shift=True) can fold the point back in; and

  • every family has a uniform length d with uniform bond indexing, which is an enormous win for code reuse and off-by-one safety — the numbering headaches (the “0-th right core sits in a different place than the 0-th left core”) largely disappear. This was a deliberate, hard-won choice: the austere d-core math versus the practical d+1 bookkeeping — practicality won.

Takeaway for reading the code: left_ranks / right_ranks have length d+1, but the last left bond and first right bond are frame-internal padding, “not really part of the frame.” The d things that are genuinely per-mode are the variation cores and their adjacent edges.

Gauge conditions make the variations coordinates#

When the frame is orthonormal and the variations are gauged (Uᵢᵀ Vᵢ = 0; Lᵢ left-orthogonal against all but the last Hᵢ — Appendix A.3 of the T4S paper), something powerful happens: plain “dumb” corewise linear algebra on the variation cores faithfully equals Hilbert–Schmidt linear algebra on the tangent vectors they represent. Adding variations adds tangents; corewise_norm/corewise_inner of the variations is the HS norm/inner (see T3Tangent.corewise_norm vs MANIFOLD.norm). The variation cores are, in this gauge, an orthonormal coordinate system for the tangent space.

That is exactly why the minimal T3Tangent stores only (frame, variations) and derives everything else, and why the K/C stack split is recovered rather than stored (see batching_and_stacking.md).

Weights are a diagonal metric on those coordinates#

This is where the weighted layer (weighting.md) plugs in, and it clarifies the whole picture:

  • A base point is a tensor; T3Weights weights all its internal edges (a weighted network).

  • A tangent is a set of coordinates; T3FrameWeights is a diagonal metric on those coordinates — one weight per variation-core edge (d each: upH.nU, downV.nD, leftH.rL, rightH.rR). The weighted norm is just corewise_norm of the weight-scaled variations; the frame stays orthonormal.

The d-natural-edges count is not a coincidence — it is the same d as the variation cores, and the padding Ld/R0 bonds (being base-point machinery, not tangent directions) correctly carry no weight. Putting inverse singular values on these coordinate edges penalises the poorly-informed tangent directions — the Grasedyck–Kramer preconditioner.

Where to look#

  • The core diagrams, orthogonality, and gauge conditions: the T3Frame docstring (frame_variations_format.py).

  • The tangent bundle + geometries (MANIFOLD HS vs COREWISE coordinate metric): manifold.py.

  • The doubled-rank point+tangent embedding (base point folded into the last core): T3Tangent.to_t3.

  • The K/C/W stack blocks: batching_and_stacking.md.