T3Tangent.apply_transpose#
- static t3toolbox.manifold.T3Tangent.apply_transpose(c, ww, frame, sum_over_probes=False)#
def apply_transpose( c: NDArray, # residual, shape=W+C ww: typ.Sequence[NDArray], # apply vectors, len=d, elm_shape=W+(Ni,) frame: bvf.T3Frame, sum_over_probes: bool = False, # True: sum the apply stack W (Gauss-Newton apply^T c) ) -> 'T3Tangent':
Apply the transpose
apply^Tofapply(): back-project a residualcinto a tangent.The adjoint of the (linear-in-the-variation) all-modes
apply(). Withsum_over_probes=False(default) the apply-vector stackWbecomes the result’s tangent stack (one tangent per apply-set); withsum_over_probes=TrueWis summed – the usual Gauss-Newtonapply^T cback-projection (a single tangent whenW = ()). Needs only the frame sweep + a single-term scatter assembly (cheaper than a generalprobe_transpose()).Falseis the primary transpose;sum_over_probes=True == Σ_W sum_over_probes=False. See Batching & stacking §11 (docs/batching_and_stacking.md) for which mode to use and why.Examples
Adjoint identity
<apply^T c, v> == c * apply(v)(no stacks):>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.frame_variations_format as bvf >>> import t3toolbox.manifold as t3m >>> import t3toolbox.corewise as cw >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1)) >>> frame, _ = bvf.t3_orthogonal_representations(x) >>> v = t3m.COREWISE.randn(frame) >>> ww = (np.random.randn(10), np.random.randn(11), np.random.randn(12)) >>> ATc = t3m.T3Tangent.apply_transpose(np.asarray(1.7), ww, frame, sum_over_probes=True) >>> lhs = float(cw.corewise_dot(ATc.variations.data, v.variations.data)) >>> print(bool(abs(lhs - 1.7 * float(v.apply(ww))) < 1e-9)) True