manifold_dim#

t3toolbox.manifold.manifold_dim(s, sharing=None)#
def manifold_dim(
        s,                                          # structure: (shape, tucker_ranks, tt_ranks) = ((N0,...), (n0,...), (1,r1,...,1))
        sharing: typ.Optional[typ.Sequence] = None, # len=d, static; one hashable group label per mode (None = unshared)
) -> int:  # dimension of the fixed-rank (shared-factor) T3 manifold

Get the dimension of the fixed rank T3 manifold with a given structure.

The fixed-rank Tucker tensor train manifold M_{n,r} is described in Appendix A.3 of Alger et al. (2026), “Tucker Tensor Train Taylor Series” (arXiv:2603.21141). With sharing (one hashable group label per mode), the dimension of the shared-factor submanifold – Tucker factors tied within each group (cf. Molozhavenko & Rakhuba (2026); arbitrary partitions are our extension): the minimal-rank reduction is the shared one, and each group contributes ONE Stiefel term n_g*(N_g - n_g) instead of one per mode. See compute_manifold_dim().

Examples

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import t3toolbox.manifold as t3m
>>> s = ((15,16,13), (9,10,8), (2,7,6,3))
>>> mdim = t3m.manifold_dim(s)
>>> print(mdim)
578

In the following more detailed example, we verify that the manifold dim is correct by generating an excessive number of random dense tangent vectors and performing an SVD on them. The number of nonzero singular values is the dimension of the tangent space, which is the dimension of the manifold.

>>> import numpy as np
>>> import t3toolbox.tucker_tensor_train as t3
>>> import t3toolbox.manifold as t3m
>>> import t3toolbox.frame_variations_format as bvf
>>> s = ((5, 6, 3), (5, 3, 2), (2, 2, 4, 1))
>>> mdim = t3m.manifold_dim(s)
>>> print(mdim)
29
>>> frame, _ = bvf.t3_orthogonal_representations(t3.TuckerTensorTrain.randn(*s))
>>> tucker_shapes, tt_shapes = frame.variation_shapes
>>> n_entries = sum(int(np.prod(sh)) for sh in tucker_shapes) + sum(int(np.prod(sh)) for sh in tt_shapes)
>>> dense_vv = np.stack([t3m.MANIFOLD.randn(frame).to_dense().reshape(-1)
...                      for _ in range(n_entries)])
>>> ss = np.linalg.svd(dense_vv, compute_uv=False)
>>> print(int(np.sum(ss > 1e-9 * ss[0])))   # number of nonzero singular values == manifold_dim
29

With sharing=, the dimension of the shared-factor manifold. Tying factors removes parameters – here one Stiefel term for the 3-mode group instead of three:

>>> import t3toolbox.manifold as t3m
>>> s = ((5, 5, 5), (3, 3, 3), (1, 3, 3, 1))
>>> print(t3m.manifold_dim(s))
45
>>> print(t3m.manifold_dim(s, sharing=(0, 0, 0)))
33
Parameters:

sharing (t3toolbox.backend.common.typ.Optional[t3toolbox.backend.common.typ.Sequence])

Return type:

int