t3_apply_ambient_transpose ========================== .. py:function:: t3toolbox.backend.apply.t3_apply_ambient_transpose(c, ww, sum_over_probes = False) .. code-block:: python def t3_apply_ambient_transpose( c: NDArray, # residual, shape=W+C ww: typ.Sequence[NDArray], # apply vectors, len=d, elm_shape=W+(Ni,) sum_over_probes: bool = False, # True: W becomes the CP rank (ambient J^T r) ) -> typ.Sequence[NDArray]: # canonical (CP) factors. len=d, ith elm_shape=stack_shape+(R, Ni) Ambient transpose of :py:func:`t3_apply`: back-project ``c`` into CP factors. The *ambient* adjoint -- the transpose of ``apply`` as a linear map on the **full tensor space** (``X -> ( )_W``). Frame-free; the back-projection ``c * (w0 (x) ... (x) w_{d-1})`` is rank-1, whose natural representation is a **canonical (CP) decomposition** (``apply`` consumes one vector per mode; its adjoint emits one scaled vector per mode). This is distinct from the *corewise* transpose (gradient w.r.t. a base point's cores) and the *tangent* transpose (Riemannian gradient) -- see ``docs/transposes.md`` for the full taxonomy. - ``sum_over_probes=False`` (primary): ``W`` is a passthrough stacking axis -- a ``W (+ C)`` stack of rank-1 CP tensors (CP rank ``R=1``). - ``sum_over_probes=True``: ``W`` becomes the CP **rank** -- one rank-``|W|`` CP tensor ``sum_W c_W * (w0^W (x) ...)`` (the ambient ``J^T r``). Cheap as CP (``O(d |W| N)``, the shared rank index stays implicit); the ``|W|^2`` cost of a *dense* Tucker tensor train is incurred only if you convert with ``t3_conversions.t3_from_canonical``. Returns the CP ``factors`` (``c`` folded into the first), in the layout ``t3_conversions.t3_from_canonical`` consumes.