ut3_reciprocal_weights ====================== .. py:function:: t3toolbox.backend.ut3_operations.ut3_reciprocal_weights(weights) .. code-block:: python def ut3_reciprocal_weights( weights: UT3WeightsData, # (tucker_weight_supercore, tt_weight_supercore, masks) ) -> UT3WeightsData: # 1/w on the real slots; padding a canonical, finite 0; masks unchanged Elementwise ``1/w`` on the real slots (masks unchanged) -- e.g. to form inverse-singular-value weights. **Not just ``1/w``**, because a canonical weight's padding is zero and ``1/0 = inf``, which then poisons every masked reduction downstream (``0 * inf = nan``). That is the headline path, not a corner case: the Grasedyck-Kramer metric *is* ``from_ut3svd(x).reciprocal()``. The real slots are left alone (see :py:func:`_ut3_map_real_weights` for how the padding is handled). **The real slots are deliberately unprotected**: a genuinely zero singular value gives ``inf`` here, exactly as in the ragged layer. It is a real weight, not a padding artifact, so it is the caller's to avoid -- silently clamping it would hide a rank-deficient point.