UT3Weights ========== .. toctree:: :hidden: /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.validate /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.__post_init__ /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.__repr__ /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.is_consistent_with /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.reciprocal /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.sqrt /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.concatenate /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.kronecker /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.from_ut3svd /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.from_t3weights /autoapi/t3toolbox/uniform_tucker_tensor_train/UT3Weights.to_t3weights .. py:class:: t3toolbox.uniform_tucker_tensor_train.UT3Weights Diagonal weights on the internal edges of a :py:class:`UniformTuckerTensorTrain` -- the uniform twin of :py:class:`~t3toolbox.tucker_tensor_train.T3Weights`. One vector per internal edge, packed into two supercores + a :py:class:`UT3Masks` holder: - ``tucker_weight_supercore``: ``(d,) + stack_shape + (n,)`` -- the Tucker-rank edges - ``tt_weight_supercore``: ``(d+1,) + stack_shape + (r,)`` -- the TT-bond edges - ``masks``: **the same two edge masks as the train it weights** (a weight's edges *are* the tensor's edges, so it declares the same ranks). This is a genuine precondition, not bookkeeping -- see :py:meth:`is_consistent_with`. There is deliberately **no ``shape`` field** (unlike ``UniformTuckerTensorTrain``): weights live only on the *internal* edges, so a weight has no physical mode legs at all. .. rubric:: Examples >>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.uniform_tucker_tensor_train as ut3 >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((6, 7, 8), (2, 2, 2), (1, 2, 2, 1)) >>> ux = ut3.UniformTuckerTensorTrain.from_t3(x, n=4, r=3) # padded ABOVE the real ranks >>> W = ut3.UT3Weights.from_t3weights(t3.T3Weights.from_t3svd(x), n=ux.n, r=ux.r) >>> print(W.is_consistent_with(ux)) # same edges -> same masks True >>> print(W.tucker_weight_supercore.shape, np.asarray(W.tucker_ranks).tolist()) # padded to 4, real 2 (3, 4) [2, 2, 2] >>> xw = ut3.ut3_absorb_weights(ux, W) # shape-preserving; masks unchanged >>> print(xw.tucker_supercore.shape == ux.tucker_supercore.shape, xw.masks == ux.masks) True True The padding is a canonical zero, so ``reciprocal`` cannot naively divide (``1/0 = inf`` would poison every masked reduction downstream: masking multiplies, and ``0 * inf = nan``). It guards the padding instead -- which matters because the Grasedyck-Kramer metric *is* a reciprocal of singular values: >>> with np.errstate(divide='ignore'): # the naive divide DOES blow up ... naive = 1.0 / W.tucker_weight_supercore >>> print(bool(np.isinf(naive).any())) True >>> Wr = W.reciprocal() # ...the guarded one does not >>> print(bool(np.isfinite(Wr.tucker_weight_supercore).all())) True >>> print(bool(np.isfinite(ut3.ut3_weighted_norm(ux, Wr)))) # so the GK norm stays finite True .. py:attribute:: tucker_weight_supercore :type: t3toolbox.backend.common.NDArray .. py:attribute:: tt_weight_supercore :type: t3toolbox.backend.common.NDArray .. py:attribute:: masks :type: UT3Masks .. py:property:: supercores :type: Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray] ``(tucker_weight_supercore, tt_weight_supercore)``. .. py:property:: data :type: Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray]] ``(tucker_weight_supercore, tt_weight_supercore, (2 rank masks))``. Backend ``ut3_*_weights`` functions take this layout. Note it is a **3-tuple**, one shorter than ``UniformTuckerTensorTrain.data`` -- there is no ``shape`` slot. :type: Raw-array view, mirroring the fields .. py:property:: d :type: int Number of modes. .. py:property:: n :type: int Padded Tucker rank. .. py:property:: r :type: int Padded TT rank. .. py:property:: stack_shape :type: Tuple[int, Ellipsis] Stack shape (``()`` if unstacked). Lives at axes ``1 .. len(stack_shape)`` (``d`` is axis 0). .. py:property:: tucker_ranks :type: t3toolbox.backend.common.NDArray Real Tucker ranks (from ``tucker_edge_mask``; may vary across the stack). .. py:property:: tt_ranks :type: t3toolbox.backend.common.NDArray Real TT ranks (from ``tt_edge_mask``; may vary across the stack). Methods ------- .. autoapisummary:: t3toolbox.uniform_tucker_tensor_train.UT3Weights.validate t3toolbox.uniform_tucker_tensor_train.UT3Weights.__post_init__ t3toolbox.uniform_tucker_tensor_train.UT3Weights.__repr__ t3toolbox.uniform_tucker_tensor_train.UT3Weights.is_consistent_with t3toolbox.uniform_tucker_tensor_train.UT3Weights.reciprocal t3toolbox.uniform_tucker_tensor_train.UT3Weights.sqrt t3toolbox.uniform_tucker_tensor_train.UT3Weights.concatenate t3toolbox.uniform_tucker_tensor_train.UT3Weights.kronecker t3toolbox.uniform_tucker_tensor_train.UT3Weights.from_ut3svd t3toolbox.uniform_tucker_tensor_train.UT3Weights.from_t3weights t3toolbox.uniform_tucker_tensor_train.UT3Weights.to_t3weights