t3_probe_ambient_transpose ========================== .. py:function:: t3toolbox.backend.probing.t3_probe_ambient_transpose(ztildes, ww, sum_over_probes = False) .. code-block:: python def t3_probe_ambient_transpose( ztildes: typ.Sequence[NDArray], # probe residuals, len=d, elm_shape=W+C+(Ni,) ww: typ.Sequence[NDArray], # probe vectors, len=d, elm_shape=W+(Ni,) sum_over_probes: bool = False, # True: W folds into the CP rank ) -> typ.Sequence[NDArray]: # canonical (CP) factors. len=d, ith elm_shape=stack_shape+(R, Ni) Ambient transpose of :py:func:`t3_probe`: back-project probe residuals into CP factors. The *ambient* adjoint -- the transpose of ``probe`` as a linear map on the **full tensor space**. Probe returns ``d`` vectors (one free mode each), so the residual ``ztildes`` is ``d`` vectors; the back-projection is the rank-``d`` tensor sum_i w0 (x) ... (x) w_{i-1} (x) ztildes_i (x) w_{i+1} (x) ... (x) w_{d-1} (term ``i`` has the residual ``ztildes_i`` in slot ``i`` and the probe vectors elsewhere), whose natural representation is a **canonical (CP) decomposition** of rank ``d``. Frame-free. Distinct from the *corewise* transpose (gradient w.r.t. a frame's cores) and the *tangent* transpose (Riemannian gradient); see ``docs/transposes.md``. The ``apply``/``entries`` analog is the rank-1 (or rank-``|W|``) :py:func:`t3_apply_ambient_transpose`. - ``sum_over_probes=False`` (primary): ``W`` is a passthrough stacking axis -- a ``W (+ C)`` stack of rank-``d`` CP tensors. - ``sum_over_probes=True``: ``W`` folds into the CP rank -- one rank-``d|W|`` CP tensor ``sum_W sum_i (...)``. Cheap as CP (``O(d |W| N)``). Returns CP ``factors`` (factor ``k`` has the diagonal structure: rank slot ``k`` = ``ztildes_k``, the others = ``ww_k``), in the layout :py:func:`t3_conversions.t3_from_canonical` consumes.