t3_probe ======== .. py:function:: t3toolbox.backend.probing.t3_probe(ww, x) .. code-block:: python def t3_probe( ww: typ.Union[typ.Sequence[NDArray], NDArray], # len=d, elm_shape=W+(Ni,) x: typ.Union[ typ.Tuple[typ.Sequence[NDArray], typ.Sequence[NDArray]], # ragged, (tucker_cores, tt_cores) typ.Tuple[NDArray, NDArray], # uniform, (tucker_supercore, tt_supercore) ], ) -> typ.Union[typ.Sequence[NDArray], NDArray]: # len=d, elm_shape=(...,Ni) Probe a Tucker tensor train. See Section 6.2, particularly Figure 7 and Algorithm 5, 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 x: Tucker tensor train to probe, as a (tucker_cores, tt_cores) data tuple. structure=((N0,...,N(d-1)),(n0,...,n(d-1)),(1,r1,...,r(d-1),1)) :type x: t3.TuckerTensorTrain.data :returns: Probes, zz. len=d, elm_shape=(...,Ni) :rtype: typ.Tuple[NDArray,...] .. seealso:: :py:obj:`tv_probe`, :py:obj:`tv_probe_transpose`, :py:obj:`compute_xi`, :py:obj:`compute_mu`, :py:obj:`compute_nu`, :py:obj:`compute_eta`, :py:obj:`assemble_z` .. rubric:: Examples Probe a T3 with one set of vectors; value-match against the dense reference: >>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.backend.probing as t3p >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1)).data >>> ww = (np.random.randn(10), np.random.randn(11), np.random.randn(12)) >>> zz = t3p.t3_probe(ww, x) >>> zz_dense = t3p.dense_probe(ww, t3.TuckerTensorTrain(*x).to_dense()) # dense reference >>> 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] Vectorize over probes: a probe stack ``W`` rides through to ``elm_shape = W + (Ni,)``: >>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.backend.probing as t3p >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1)).data >>> ww = (np.random.randn(2, 3, 10), np.random.randn(2, 3, 11), np.random.randn(2, 3, 12)) >>> zz = t3p.t3_probe(ww, x) >>> zz_dense = t3p.dense_probe(ww, t3.TuckerTensorTrain(*x).to_dense()) >>> print([z.shape for z in zz]) # W=(2,3) outer, mode index inner [(2, 3, 10), (2, 3, 11), (2, 3, 12)] >>> print([bool(np.allclose(z, z2)) for z, z2 in zip(zz, zz_dense)]) [True, True, True] Vectorize over probes AND T3s: both stacks ride through, base-inner ``elm_shape = W + C + (Ni,)``: >>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.backend.probing as t3p >>> np.random.seed(0) >>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1), stack_shape=(4, 5)).data >>> ww = (np.random.randn(2, 3, 10), np.random.randn(2, 3, 11), np.random.randn(2, 3, 12)) >>> zz = t3p.t3_probe(ww, x) >>> zz_dense = t3p.dense_probe(ww, t3.TuckerTensorTrain(*x).to_dense()) >>> print(zz[0].shape) # W=(2,3) outer, C=(4,5) inner, then N0=10 (2, 3, 4, 5, 10) >>> print([bool(np.allclose(z, z2)) for z, z2 in zip(zz, zz_dense)]) [True, True, True]