t3toolbox.backend.probing.probe_tangent#
- t3toolbox.backend.probing.probe_tangent(ww: t3toolbox.backend.common.typ.Union[t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.NDArray], variation: t3toolbox.backend.common.typ.Union[t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray]], t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray]], base: t3toolbox.backend.common.typ.Union[t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray]], t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray]], edge_weights: t3toolbox.backend.common.typ.Union[t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray]], t3toolbox.backend.common.typ.Tuple[t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray, t3toolbox.backend.common.NDArray]] = (None, None, None, None, None), use_jax: bool = False) t3toolbox.backend.common.typ.Union[t3toolbox.backend.common.typ.Sequence[t3toolbox.backend.common.NDArray], t3toolbox.backend.common.NDArray]#
Probe a tangent vector.
- See Section 5.2.3 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:
x (t3m.T3Tangent) – Tangent vector to probe. shape=(N1,…,Nd)
ww (typ.Sequence[NDArray]) – input vectors to probe with. len=d, elm_shape=(…,Ni)
xnp – Linear algebra backend. Default: np (numpy)
- Returns:
Probes, zz. len=d, elm_shape=(Ni,) or (num_probes,Ni)
- Return type:
typ.Tuple[NDArray,…]
See also
probe_t3,probe_tangent_transpose,compute_xis,compute_mus,compute_nus,compute_etas,compute_dxis,compute_sigmas,assemble_probes,compute_detas,assemble_tangent_probesExamples
Probe tangent with one set of vectors:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.backend.probing as t3p >>> import t3toolbox.orthogonalization as orth >>> p = t3.t3_corewise_randn((10,11,12),(5,6,4),(2,3,4,2)) >>> base, _ = orth.orthogonal_representations(p) >>> variation = t3m.tangent_randn(base) >>> ww = (np.random.randn(10), np.random.randn(11), np.random.randn(12)) >>> zz = t3p.probe_tangent(ww, variation, base) >>> zz2 = t3p.probe_dense(ww, t3m.tangent_to_dense(variation, base)) >>> print([np.linalg.norm(z - z2) for z, z2 in zip(zz, zz2)]) [4.6257812371663175e-15, 3.628238740198284e-15, 5.6097341748343224e-15]
Probe tangent with two sets of vectors:
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.backend.probing as t3p >>> import t3toolbox.orthogonalization as orth >>> p = t3.t3_corewise_randn((10,11,12),(5,6,4),(2,3,4,2)) >>> base, _ = orth.orthogonal_representations(p) >>> variation = t3m.tangent_randn(base) >>> www = (np.random.randn(2,10), np.random.randn(2,11), np.random.randn(2,12)) >>> zzz = t3p.probe_tangent(www, variation, base) # Compute probes! >>> zzz2 = t3p.probe_dense(www,t3m.tangent_to_dense(variation, base)) >>> print([np.linalg.norm(zz - zz2) for zz, zz2 in zip(zzz, zzz2)]) [3.863711710898517e-15, 5.474255194514171e-15, 5.930347504865667e-15]
Example with weights
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.backend.probing as t3p >>> import t3toolbox.orthogonalization as orth >>> randn = np.random.randn >>> p = t3.t3_corewise_randn((10,11,12),(5,6,4),(2,3,5,4)) >>> base, _ = orth.orthogonal_representations(p) >>> variation = t3m.tangent_randn(base) >>> NN = [U.shape[1] for U in base[0]] >>> nnU = [U.shape[0] for U in base[0]] >>> rrL = [L.shape[0] for L in base[1]] >>> rrR = [R.shape[2] for R in base[2]] >>> nnO = [O.shape[1] for O in base[3]] >>> shape_weights = [randn(N) for N in NN] >>> up_tucker_weights = [randn(nU) for nU in nnU] >>> outer_tucker_weights = [randn(nO) for nO in nnO] >>> left_tt_weights = [randn(rL) for rL in rrL] >>> right_tt_weights = [randn(rR) for rR in rrR] >>> edge_weights = (shape_weights, up_tucker_weights, outer_tucker_weights, left_tt_weights, right_tt_weights) >>> www = (np.random.randn(2,10), np.random.randn(2,11), np.random.randn(2,12)) >>> zzz = t3p.probe_tangent(www, variation, base, edge_weights=edge_weights) >>> weighted_variation, weighted_base = t3m.absorb_weights_into_tangent_cores(variation, base, edge_weights) >>> zzz2 = t3p.probe_tangent(www, weighted_variation, weighted_base) >>> print([np.linalg.norm(zz - zz2) for zz, zz2 in zip(zzz, zzz2)]) [1.5683512051190777e-15, 4.368484248906507e-15, 1.855735793037041e-15]
Uniform tangent
>>> import numpy as np >>> import t3toolbox.tucker_tensor_train as t3 >>> import t3toolbox.uniform as ut3 >>> import t3toolbox.manifold as t3m >>> import t3toolbox.backend.probing as t3p >>> import t3toolbox.orthogonalization as orth >>> p = t3.t3_corewise_randn((10,11,12),(5,6,4),(2,3,4,2)) >>> base, _ = orth.orthogonal_representations(p) >>> variation = t3m.tangent_randn(base) >>> www = (np.random.randn(2,10), np.random.randn(2,11), np.random.randn(2,12)) >>> uniform_variation, uniform_base, masks = ut3.bv_to_ubv(variation, base)
>>> inv_masks = cw.corewise_logical_not(masks) >>> junk = ut3.uniform_randn(ut3.get_uniform_structure(uniform_x), masks=inv_masks) >>> uniform_x = cw.corewise_add(uniform_x, junk) # Add random junk outside the masks
>>> uniform_www = ut3.pack_tensors(www) >>> uniform_zzz = t3p.probe_tangent(uniform_www, uniform_variation, uniform_base, edge_weights=masks) >>> zzz2 = t3p.probe_tangent(www, variation, base) >>> uniform_zzz2 = ut3.pack_tensors(zzz2) >>> print(np.linalg.norm(uniform_zzz - uniform_zzz2)) 5.3316719684500096e-15