dense_probe#

t3toolbox.backend.probing.dense_probe(vectors, T)#
def dense_probe(
        vectors: typ.Sequence[NDArray],
        T: NDArray,
) -> typ.Tuple[NDArray]:

Probe a dense tensor.

Parameters:
  • T (NDArray) – Tensor to be probed. shape=C+(N0,…,N(d-1))

  • vectors (typ.Sequence[NDArray]) – Probing input vectors. len=d. elm_shape=W+(Ni,)

Returns:

Probes. len=d. elm_shape=(Ni,) or elm_shape=W+C+(Ni,)

Return type:

typ.Tuple[NDArray]

Examples

Probe with one set of vectors; value-match each mode against a hand-written einsum:

>>> import numpy as np
>>> import t3toolbox.backend.probing as t3p
>>> np.random.seed(0)
>>> T = np.random.randn(10, 11, 12)
>>> u0, u1, u2 = np.random.randn(10), np.random.randn(11), np.random.randn(12)
>>> yy = t3p.dense_probe((u0, u1, u2), T)
>>> y0 = np.einsum('ijk,j,k', T, u1, u2)   # contract all modes but 0
>>> y1 = np.einsum('ijk,i,k', T, u0, u2)
>>> y2 = np.einsum('ijk,i,j', T, u0, u1)
>>> print([y.shape for y in yy])           # one probe per mode, elm_shape=(Ni,)
[(10,), (11,), (12,)]
>>> print([bool(np.allclose(y, ref)) for y, ref in zip(yy, (y0, y1, y2))])
[True, True, True]

Vectorize over probing vectors: a probe stack W rides through, elm_shape = W + (Ni,):

>>> import numpy as np
>>> import t3toolbox.backend.probing as t3p
>>> np.random.seed(0)
>>> T = np.random.randn(10, 11, 12)
>>> u0, u1, u2 = np.random.randn(2, 3, 10), np.random.randn(2, 3, 11), np.random.randn(2, 3, 12)
>>> yy = t3p.dense_probe((u0, u1, u2), T)
>>> y0 = np.einsum('ijk,uvj,uvk->uvi', T, u1, u2)
>>> y1 = np.einsum('ijk,uvi,uvk->uvj', T, u0, u2)
>>> y2 = np.einsum('ijk,uvi,uvj->uvk', T, u0, u1)
>>> print(yy[0].shape)                      # W=(2,3) outer, then N0=10
(2, 3, 10)
>>> print([bool(np.allclose(y, ref)) for y, ref in zip(yy, (y0, y1, y2))])
[True, True, True]

Vectorize over probing vectors AND a stacked (big) tensor: base-inner elm_shape = W + C + (Ni,):

>>> import numpy as np
>>> import t3toolbox.backend.probing as t3p
>>> np.random.seed(0)
>>> T = np.random.randn(4, 5, 6, 10, 11, 12)   # C=(4,5,6) stack on the tensor
>>> u0, u1, u2 = np.random.randn(2, 3, 10), np.random.randn(2, 3, 11), np.random.randn(2, 3, 12)
>>> yy = t3p.dense_probe((u0, u1, u2), T)
>>> y0 = np.einsum('xyzijk,uvj,uvk->uvxyzi', T, u1, u2)
>>> y1 = np.einsum('xyzijk,uvi,uvk->uvxyzj', T, u0, u2)
>>> y2 = np.einsum('xyzijk,uvi,uvj->uvxyzk', T, u0, u1)
>>> print(yy[0].shape)                      # W=(2,3) outer, C=(4,5,6) inner, then N0=10
(2, 3, 4, 5, 6, 10)
>>> print([bool(np.allclose(y, ref)) for y, ref in zip(yy, (y0, y1, y2))])
[True, True, True]