ut3_orthogonal_representations#

t3toolbox.backend.ufv_conversions.ut3_orthogonal_representations(data, already_left_orthogonal=False, squash_tails=True)#
def ut3_orthogonal_representations(
        data: typ.Tuple[
            NDArray,                          # tucker_supercore
            NDArray,                          # tt_supercore
            typ.Tuple[int, ...],              # shape
            typ.Tuple[NDArray, NDArray],      # (tucker_edge_mask, tt_edge_mask) -- the plain-UT3 rank masks
        ],
        already_left_orthogonal: bool = False,
        squash_tails:                  bool = True,
) -> typ.Tuple[
    typ.Tuple[                                # frame .data:
        NDArray, NDArray, NDArray, NDArray,   #   up_sc, down_sc, left_sc, right_sc
        typ.Tuple[int, ...],                  #   shape
        typ.Tuple[NDArray, NDArray, NDArray, NDArray],  # (up, down, frame_left, frame_right) masks
    ],
    typ.Tuple[                                # variations .data:
        NDArray, NDArray,                     #   tucker_var_sc, tt_var_sc
        typ.Tuple[int, ...],                  #   shape
        typ.Tuple[NDArray, NDArray, NDArray, NDArray],  # (variations up, down, left, right) masks
    ],
]:

Orthogonal (frame, variations) representation of a uniform Tucker tensor train, on raw .data.

Backend twin of the frontend ut3_orthogonal_representations (which wraps this into the OO UT3Frame / UT3Variations). Takes a plain UniformTuckerTensorTrain.data and returns the frame and variation .data tuples (supercores + shape + the rank masks).

WHY THIS IS A BACKEND FUNCTION (and not something to open-code): the output frame masks are prefix masks built from the orthogonal-representation ranks (ufv_make_frame_masks = arange < rank) – they assert the real orthonormal content sits in the upper-left [0, rank) slots of each supercore. That is correct ONLY because the orthogonalization is SVD-based: the SVD sorts content by singular value into the leading slots, with zeros / orthonormal completion trailing. A QR-based orthogonalization would scatter the real content across non-prefix positions and these masks would be WRONG – see docs/contributor/uniform_svd_prefix_orthogonalization.md. Building the masks any other way (e.g. from raw supercore magnitudes) is the easy mistake this function exists to prevent.

The frame masks come from the orthogonal-representation ranks; the variation masks reuse the up/down masks and the frame left/right masks shifted by one (a variation occupies one TT slot, not a boundary edge – hence left[:-1] / right[1:]).

Parameters:
  • data (t3toolbox.backend.common.typ.Tuple[NDArray, NDArray, t3toolbox.backend.common.typ.Tuple[int, Ellipsis], t3toolbox.backend.common.typ.Tuple[NDArray, NDArray]])

  • already_left_orthogonal (bool)

  • squash_tails (bool)

Return type:

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