ufv_absorb_weights#

t3toolbox.backend.ufv_operations.ufv_absorb_weights(variations, weights)#
def ufv_absorb_weights(
        variations: typ.Tuple,       # UT3Variations .data: (tkv, ttv, shape, masks), stack = K + C
        weights:    UT3FrameWeightsData,  # (up, down, left, right, masks), stack = C
) -> typ.Tuple:                      # UT3Variations .data: weighted, same shape and masks

Absorb the four-family metric weights into the VARIATION supercores – the uniform twin of fv_absorb_weights (the tangent metric on coordinates: down -> V’s nD leg; up/left/right -> H’s nU/rL/rR legs). The frame is left orthonormal and untouched, so this is O(ranks) and does not disturb the tangent space.

The weight is frame-like (stack ``C``) and the variations are ``K + C``, and the broadcast is free: the ellipsis in 'd...i,d...io->d...io' right-aligns, so a C-stacked weight lifts over the tangent stack K at no cost. That works only because C is innermost – the library-wide frame-inner convention (docs/batching_and_stacking.md). One metric, shared by the K tangent vectors at that frame.

No entry masking, for the same reason as ut3_absorb_weights: this is a pointwise scale along each edge axis, not a reduction, so garbage never mixes into a real slot (garbage-transparent). The reduction that follows (utv_weighted_norm/_inner) masks its own input.

Precondition (structural, NOT enforced here): the weight’s masks, broadcast over K, must equal the variations’ masks – ufv_weights_consistent. Uniform padding hides a mismatch that ragged would raise as a shape error; the frontend enforces it.

Parameters:
  • variations (t3toolbox.backend.common.typ.Tuple)

  • weights (UT3FrameWeightsData)

Return type:

t3toolbox.backend.common.typ.Tuple