tv_project_dense_onto_tangent_space =================================== .. py:function:: t3toolbox.backend.tv_operations.tv_project_dense_onto_tangent_space(frame, Z) .. code-block:: python def tv_project_dense_onto_tangent_space( frame: typ.Tuple[ typ.Sequence[NDArray], # up_tucker_cores typ.Sequence[NDArray], # down_tt_cores typ.Sequence[NDArray], # left_tt_cores typ.Sequence[NDArray], # right_tt_cores ], Z: NDArray, # dense ambient tensor. shape = stack_shape + (N0, ..., N(d-1)) ) -> typ.Tuple[ typ.Tuple[NDArray, ...], # gauged tucker_variations typ.Tuple[NDArray, ...], # gauged tt_variations ]: Orthogonal projection of a *dense* tensor onto the tangent space at an orthogonal frame. Contraction-only: contracts ``Z`` directly against the frame's orthonormal frames -- no SVD and no large intermediate Tucker tensor train (unlike densifying ``Z`` with the T3-SVD first). Returns gauged variations representing the orthogonal projection of ``Z`` *directly* onto the tangent space (a linear subspace); it does not subtract the base point. Stack-aware (leading axes beyond the ``d`` tensor modes are a stack). Ragged path only (uniform deferred). Requires an **orthogonal** frame: the canonical conditions (U row-orthonormal, L/R left/right- canonical, O outer-orthonormal) make each surrounding frame an isometry -- so a bare contraction yields the orthogonal-projection coefficient -- and make the gauged single-core directions mutually orthogonal. A *minimal-rank* frame is **not** required. Algorithm. For each mode ``i``, reduce ``Z`` over every *other* mode against the frame chains -- the left interface ``(U, L)`` over modes ``< i`` and the right interface ``(U, R)`` over modes ``> i`` -- leaving the single mode ``x_i`` open, giving the shared environment ``core_env_i`` of shape ``(r_i, N_i, r_{i+1})``. Both variations at ``i`` read off it: ``dG_i = `` (the TT variation) and ``dU_i = `` (the Tucker variation; ``O`` = the outer/down cores). A single left sweep builds the left-reduced environments; each slot finishes with a right reduction. Finally :py:func:`tv_orthogonal_gauge_projection` orthogonalizes the ``2d`` directions so the sum of their per-direction projections equals the projection onto the tangent space.