UT3Weights#
- class t3toolbox.uniform_tucker_tensor_train.UT3Weights#
Diagonal weights on the internal edges of a
UniformTuckerTensorTrain– the uniform twin ofT3Weights.One vector per internal edge, packed into two supercores + a
UT3Masksholder:tucker_weight_supercore:(d,) + stack_shape + (n,)– the Tucker-rank edgestt_weight_supercore:(d+1,) + stack_shape + (r,)– the TT-bond edgesmasks: 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 – seeis_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.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
reciprocalcannot naively divide (1/0 = infwould poison every masked reduction downstream: masking multiplies, and0 * 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
- property data: Tuple[NDArray, NDArray, Tuple[NDArray, NDArray]]#
(tucker_weight_supercore, tt_weight_supercore, (2 rank masks)). Backendut3_*_weightsfunctions take this layout. Note it is a 3-tuple, one shorter thanUniformTuckerTensorTrain.data– there is noshapeslot.
- property d: int#
Number of modes.
- Return type:
int
- property n: int#
Padded Tucker rank.
- Return type:
int
- property r: int#
Padded TT rank.
- Return type:
int
- property stack_shape: Tuple[int, Ellipsis]#
Stack shape (
()if unstacked). Lives at axes1 .. len(stack_shape)(dis axis 0).- Return type:
Tuple[int, Ellipsis]
Methods#
|
Check the structural invariants (supercore shapes agree with the masks; masks boolean). |
|
|
True iff these weights can be absorbed into |
|
Elementwise |
|
|
Elementwise |
|
Per-edge concatenation with |
|
Per-edge Kronecker product with |
|
The singular values of |
|
Pack a ragged |
Convert back to ragged form. |