t3_probe#

t3toolbox.backend.probing.t3_probe(ww, x)#
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

Parameters:
  • ww (typ.Sequence[NDArray]) – input vectors to probe with. len=d, elm_shape=(…,Ni)

  • x (t3.TuckerTensorTrain.data) – 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))

Returns:

Probes, zz. len=d, elm_shape=(…,Ni)

Return type:

typ.Tuple[NDArray,…]

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]