ut3_absorb_weights#
- t3toolbox.backend.ut3_operations.ut3_absorb_weights(x, weights)#
def ut3_absorb_weights( x: UT3Data, # (tucker_supercore, tt_supercore, shape, masks) weights: UT3WeightsData, # (tucker_weight_supercore, tt_weight_supercore, masks) ) -> UT3Data: # the weighted train: same shape, same masks (absorb preserves both)
Contract diagonal edge weights into a uniform Tucker tensor train’s supercores (shape-preserving).
The uniform twin of
t3_absorb_weights, with the same side-convention, but vectorized over the leading(d,)instead of looping the cores:Tucker weights -> the Tucker supercore (its rank leg
n).TT bond weights leftward: bond
r(k+1)into corek’s right leg; the leftmost boundary bondr0(which has no left neighbour) goes rightward into core0’s left leg instead. So each of thed+1bonds is absorbed exactly once.
No entry masking, deliberately – absorb is garbage-transparent. It is a pointwise scale along each edge axis, not a reduction: real slot
iof the output depends only on slotiof the core and slotiof the weight, so garbage can never mix into a real slot. Garbage padding in gives garbage padding out, which the equivalence contract declares don’t-care (docs/uniform_equivalence_contract.md). Do not add a defensive entry-mask: it would be dead work, and masking is a separate concern from weighting (docs/contributor/weighted_internals.md§2).Precondition (structural; NOT enforced here):
weights’ masks must equalx’s masks –ut3_weights_consistent(). Ragged catches a rank mismatch as a loud einsum shape error, but uniform pads both to the common(n, r), so a mismatch is silent and corrupting (a weight whose mask calls slotipadding carries a canonical zero there, and absorbing it would zero a real slot ofx). The frontend enforces it; a raw-.datauser should call the predicate first. This is the same precondition uniform adds to variation add/sub (docs/uniform_masks_vs_ranks.md).- Parameters:
x (UT3Data)
weights (UT3WeightsData)
- Return type:
UT3Data