T3Tangent.probe_derivatives_transpose#

static t3toolbox.manifold.T3Tangent.probe_derivatives_transpose(ztildes, ww, pp, frame, order, sum_over_probes=False, chunk_size=100)#
def probe_derivatives_transpose(
        ztildes:            typ.Sequence[NDArray],  # residual jets, len=d, elm_shape=(order+1,)+W+K+C+(Ni,)
        ww:                 typ.Sequence[NDArray],  # probe vectors X,        len=d, elm_shape=W+(Ni,)
        pp:                 typ.Sequence[NDArray],  # perturbation vectors P, len=d, elm_shape=W+(Ni,)
        frame:              bvf.T3Frame,
        order:              int,                    # highest derivative order
        sum_over_probes:    bool = False,           # True: sum the sample stack W (Gauss-Newton J^T r)
        chunk_size:         typ.Optional[int] = 100,  # W-chunk size for the gradient assembly; None -> dense
) -> 'T3Tangent':

Transpose (J^(s))^T of probe_derivatives(); returns a T3Tangent at frame.

The adjoint of probe_derivatives(). Residual jets ztildes live in its output space ((order+1)+W+K+C+(Ni,)); the tangent batch K rides through, the sample stack W is summed (sum_over_probes=True, the Gauss-Newton J^T r) or kept (False, W becomes the tangent stack). Bare (J^(s))^T (no gauge projector).

chunk_size bounds the peak memory of the (uniform+jax) gradient assembly by processing the sample stack in slices; None runs the dense assembly. See Memory chunking of the derivative transpose (chunk_size).

Examples

Adjoint identity <r, J v> = <J^T r, v> (sum over probes):

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import t3toolbox.frame_variations_format as bvf
>>> import t3toolbox.manifold as t3m
>>> np.random.seed(0)
>>> x = t3.TuckerTensorTrain.randn((10, 11, 12), (5, 6, 4), (1, 2, 3, 1))
>>> frame, _ = bvf.t3_orthogonal_representations(x)
>>> v = t3m.COREWISE.randn(frame)
>>> ww = (np.random.randn(10), np.random.randn(11), np.random.randn(12))
>>> pp = (np.random.randn(10), np.random.randn(11), np.random.randn(12))
>>> Jv = v.probe_derivatives(ww, pp, 2)
>>> r = [np.random.randn(*z.shape) for z in Jv]
>>> JTr = t3m.T3Tangent.probe_derivatives_transpose(r, ww, pp, frame, 2, sum_over_probes=True)
>>> lhs = sum(float(np.sum(ri * zi)) for ri, zi in zip(r, Jv))
>>> print(bool(abs(lhs - float(JTr.corewise_inner(v))) < 1e-9))
True
Parameters:
  • ztildes (t3toolbox.backend.common.typ.Sequence[NDArray])

  • ww (t3toolbox.backend.common.typ.Sequence[NDArray])

  • pp (t3toolbox.backend.common.typ.Sequence[NDArray])

  • frame (T3Frame)

  • order (int)

  • sum_over_probes (bool)

  • chunk_size (t3toolbox.backend.common.typ.Optional[int])

Return type:

T3Tangent