tv_probe ======== .. py:function:: t3toolbox.backend.probing.tv_probe(ww, variation, frame) .. code-block:: python def tv_probe( ww: typ.Union[typ.Sequence[NDArray], NDArray], # input vectors, len=d, elm_shape=(...,Ni) variation: typ.Union[ typ.Tuple[ typ.Sequence[NDArray], # var_tucker_cores. len=d, elm_shape=(nOi,Ni) typ.Sequence[NDArray], # var_tt_cores. len=d, elm_shape=(rLi,nUi,rRi) ], typ.Tuple[ NDArray, # var_tucker_supercore. NDArray, # var_tt_supercore. ], ], frame: typ.Union[ typ.Tuple[ typ.Sequence[NDArray], # up_tucker_cores. len=d. U_xo U_yo = I_xy, U.shape = (nU, N) typ.Sequence[NDArray], # down_tt_cores. len=d. O_ixj O_iyj = I_xy O.shape = (rL, nO, rR) typ.Sequence[NDArray], # left_tt_cores. len=d. P_iax P_iay = I_xy, P.shape = (rL, nU, rR) typ.Sequence[NDArray], # right_tt_cores. len=d. Q_xaj Q_yaj = I_xy Q.shape = (rL, nU, rR) ], typ.Tuple[ NDArray, # up_tucker_supercore. shape=(d, nU, N), up orthogonal elements NDArray, # down_tt_supercore. shape=(d, rL, nO, rR), down orthogonal elements NDArray, # left_tt_supercore. shape=(d, rL, nU, rR), left orthogonal elements NDArray, # right_tt_supercore. shape=(d, rL, nU, rR), right orthogonal elements ], ], # frame order = T3Frame.data = (up, down, left, right) = (U, O, P, Q) ) -> typ.Union[typ.Sequence[NDArray], NDArray]: # len=d, elm_shape=(...,Ni) Probe a tangent vector. Applies the (single-sample) least-squares Jacobian J^(s). Two independent stackings may ride along (handled by the W/C custom contractions in ``contractions.py``): the T3 stack ``C`` (the frame/variation cores' ``stack_shape``) and the probe stack ``W`` (the probing vectors' batch). When both are present the probes are double-stacked, ``elm_shape = W + C + (Ni,)`` (probe outer, frame inner). See Section 6.2.2, particularly Algorithms 6 and 7, in: Alger, N., Christierson, B., Chen, P., & Ghattas, O. (2026). "Tucker Tensor Train Taylor Series." arXiv preprint arXiv:2603.21141. `https://arxiv.org/abs/2603.21141 `_ :param ww: input vectors to probe with. len=d, elm_shape=(...,Ni) :type ww: typ.Sequence[NDArray] :param variation: Tangent direction, as a (tucker_variations, tt_variations) data tuple. :type variation: bvf.T3Variations.data :param frame: Orthogonal frame for the point where the tangent space attaches to the manifold. This is exactly ``T3Frame.data`` order (U, O, P, Q) -- pass ``frame.data`` directly, no reorder. :type frame: (up_tucker_cores, down_tt_cores, left_tt_cores, right_tt_cores) :returns: Probes, zz. len=d, elm_shape=(Ni,) or (...,Ni) :rtype: typ.Tuple[NDArray,...] .. seealso:: :py:obj:`t3_probe`, :py:obj:`tv_probe_transpose`, :py:obj:`compute_dxi`, :py:obj:`compute_sigma`, :py:obj:`compute_tau`, :py:obj:`compute_deta`, :py:obj:`assemble_tangent_z` .. rubric:: Examples Probe a tangent vector with one set of vectors; value-match against the dense reference: >>> 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.backend.probing as t3p >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1)) >>> frame, variations = bvf.t3_orthogonal_representations(x) >>> probe_frame = frame.data # probing's frame order == T3Frame.data, no reorder >>> v = t3m.T3Tangent(frame, variations) >>> ww = (np.random.randn(10), np.random.randn(11), np.random.randn(12)) >>> zz = t3p.tv_probe(ww, variations.data, probe_frame) >>> zz_dense = t3p.dense_probe(ww, v.to_dense()) # dense reference J^(s) v >>> print([z.shape for z in zz]) # one probe per mode, elm_shape=(Ni,) [(10,), (11,), (12,)] >>> print([bool(np.allclose(z, z2)) for z, z2 in zip(zz, zz_dense)]) [True, True, True] Probe with a stack of vectors: the probe stack ``W`` rides through, ``elm_shape = W + (Ni,)``: >>> 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.backend.probing as t3p >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1)) >>> frame, variations = bvf.t3_orthogonal_representations(x) >>> v = t3m.T3Tangent(frame, variations) >>> www = (np.random.randn(2, 10), np.random.randn(2, 11), np.random.randn(2, 12)) >>> zzz = t3p.tv_probe(www, variations.data, frame.data) >>> zzz_dense = t3p.dense_probe(www, v.to_dense()) >>> print(zzz[0].shape) # W=(2,) outer, then N0=10 (2, 10) >>> print([bool(np.allclose(z, z2)) for z, z2 in zip(zzz, zzz_dense)]) [True, True, True]