t3toolbox 2026.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- t3toolbox-2026.0.0/LICENSE +21 -0
- t3toolbox-2026.0.0/PKG-INFO +169 -0
- t3toolbox-2026.0.0/README.md +138 -0
- t3toolbox-2026.0.0/pyproject.toml +55 -0
- t3toolbox-2026.0.0/setup.cfg +4 -0
- t3toolbox-2026.0.0/t3toolbox/__init__.py +76 -0
- t3toolbox-2026.0.0/t3toolbox/backend/__init__.py +7 -0
- t3toolbox-2026.0.0/t3toolbox/backend/apply.py +388 -0
- t3toolbox-2026.0.0/t3toolbox/backend/common.py +459 -0
- t3toolbox-2026.0.0/t3toolbox/backend/contractions.py +2812 -0
- t3toolbox-2026.0.0/t3toolbox/backend/entries.py +298 -0
- t3toolbox-2026.0.0/t3toolbox/backend/fitting.py +289 -0
- t3toolbox-2026.0.0/t3toolbox/backend/fv_conversions.py +190 -0
- t3toolbox-2026.0.0/t3toolbox/backend/fv_operations.py +330 -0
- t3toolbox-2026.0.0/t3toolbox/backend/linalg.py +527 -0
- t3toolbox-2026.0.0/t3toolbox/backend/optimizers.py +409 -0
- t3toolbox-2026.0.0/t3toolbox/backend/probing.py +1447 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ranks.py +473 -0
- t3toolbox-2026.0.0/t3toolbox/backend/sampling_derivatives.py +1634 -0
- t3toolbox-2026.0.0/t3toolbox/backend/stacking.py +519 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_constructors.py +95 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_conversions.py +198 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_linalg.py +605 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_operations.py +360 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_orthogonalization.py +409 -0
- t3toolbox-2026.0.0/t3toolbox/backend/t3_svd.py +514 -0
- t3toolbox-2026.0.0/t3toolbox/backend/tt_operations.py +186 -0
- t3toolbox-2026.0.0/t3toolbox/backend/tt_orthogonalization.py +89 -0
- t3toolbox-2026.0.0/t3toolbox/backend/tv_operations.py +603 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ufv_conversions.py +327 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ufv_masking.py +148 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ufv_operations.py +235 -0
- t3toolbox-2026.0.0/t3toolbox/backend/uniform_fitting.py +474 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_constructors.py +185 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_conversions.py +168 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_linalg.py +153 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_masking.py +118 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_operations.py +202 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_orthogonalization.py +194 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_sampling.py +252 -0
- t3toolbox-2026.0.0/t3toolbox/backend/ut3_svd.py +229 -0
- t3toolbox-2026.0.0/t3toolbox/backend/utv_operations.py +506 -0
- t3toolbox-2026.0.0/t3toolbox/backend/utv_sampling.py +557 -0
- t3toolbox-2026.0.0/t3toolbox/backend/wt3_operations.py +130 -0
- t3toolbox-2026.0.0/t3toolbox/corewise.py +390 -0
- t3toolbox-2026.0.0/t3toolbox/fitting.py +547 -0
- t3toolbox-2026.0.0/t3toolbox/frame_variations_format.py +1316 -0
- t3toolbox-2026.0.0/t3toolbox/manifold.py +1462 -0
- t3toolbox-2026.0.0/t3toolbox/optimizers.py +228 -0
- t3toolbox-2026.0.0/t3toolbox/safety.py +244 -0
- t3toolbox-2026.0.0/t3toolbox/tucker_tensor_train.py +4384 -0
- t3toolbox-2026.0.0/t3toolbox/uniform_frame_variations_format.py +1071 -0
- t3toolbox-2026.0.0/t3toolbox/uniform_manifold.py +1250 -0
- t3toolbox-2026.0.0/t3toolbox/uniform_tucker_tensor_train.py +909 -0
- t3toolbox-2026.0.0/t3toolbox/weighted_tucker_tensor_train.py +669 -0
- t3toolbox-2026.0.0/t3toolbox.egg-info/PKG-INFO +169 -0
- t3toolbox-2026.0.0/t3toolbox.egg-info/SOURCES.txt +71 -0
- t3toolbox-2026.0.0/t3toolbox.egg-info/dependency_links.txt +1 -0
- t3toolbox-2026.0.0/t3toolbox.egg-info/requires.txt +4 -0
- t3toolbox-2026.0.0/t3toolbox.egg-info/top_level.txt +1 -0
- t3toolbox-2026.0.0/tests/test_dispatch.py +720 -0
- t3toolbox-2026.0.0/tests/test_fitting.py +406 -0
- t3toolbox-2026.0.0/tests/test_frame_variations_format.py +518 -0
- t3toolbox-2026.0.0/tests/test_manifold.py +960 -0
- t3toolbox-2026.0.0/tests/test_optimizers_frontend.py +153 -0
- t3toolbox-2026.0.0/tests/test_probe_derivatives.py +437 -0
- t3toolbox-2026.0.0/tests/test_safety.py +128 -0
- t3toolbox-2026.0.0/tests/test_t3m.py +166 -0
- t3toolbox-2026.0.0/tests/test_tucker_tensor_train.py +3077 -0
- t3toolbox-2026.0.0/tests/test_uniform_frame_variations_format.py +819 -0
- t3toolbox-2026.0.0/tests/test_uniform_manifold.py +1256 -0
- t3toolbox-2026.0.0/tests/test_uniform_probing.py +725 -0
- t3toolbox-2026.0.0/tests/test_uniform_tucker_tensor_train.py +590 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nick Alger and Blake Christierson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: t3toolbox
|
|
3
|
+
Version: 2026.0.0
|
|
4
|
+
Summary: Library for working with Tucker tensor trains (extended tensor trains)
|
|
5
|
+
Author-email: Nick Alger <nalger225@gmail.com>, Blake Christierson <bechristierson@utexas.edu>
|
|
6
|
+
Maintainer-email: Nick Alger <nalger225@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/NickAlger/T3Toolbox
|
|
9
|
+
Project-URL: Documentation, https://nickalger.github.io/T3Toolbox/
|
|
10
|
+
Project-URL: Repository, https://github.com/NickAlger/T3Toolbox
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/NickAlger/T3Toolbox/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/NickAlger/T3Toolbox/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: Tucker tensor train,extended tensor train,ETT,Tucker decomposition,tensor train,tensor
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Requires-Python: >=3.9
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: numpy>=1.22
|
|
28
|
+
Provides-Extra: jax
|
|
29
|
+
Requires-Dist: jax>=0.4.30; extra == "jax"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# T3Toolbox
|
|
33
|
+
|
|
34
|
+
[](https://github.com/NickAlger/T3Toolbox/actions/workflows/tests.yaml)
|
|
35
|
+
[](https://github.com/NickAlger/T3Toolbox/actions/workflows/build-sphinx-docs.yaml)
|
|
36
|
+
|
|
37
|
+
A pure-Python (NumPy + optional JAX) library for **Tucker tensor trains (T3)** — a Tucker
|
|
38
|
+
decomposition whose central core is stored as a tensor train. When the ranks are moderate, a T3
|
|
39
|
+
breaks the curse of dimensionality: storing a dense tensor costs O(N^d) memory, while the T3
|
|
40
|
+
representing it costs O(dnr^2 + dnN).
|
|
41
|
+
|
|
42
|
+
Tucker tensor trains are also known as **extended tensor trains (ETT)** — the two names refer to
|
|
43
|
+
the same format. This library uses "Tucker tensor train" (and the abbreviation T3) throughout, but
|
|
44
|
+
everything here applies equally if you know these objects as extended tensor trains.
|
|
45
|
+
|
|
46
|
+
Tensor network diagram for a Tucker tensor train:
|
|
47
|
+
|
|
48
|
+
r0 r1 r2 r(d-1) rd
|
|
49
|
+
1 ------ G0 ------ G1 ------ ... ------ G(d-1) ------ 1
|
|
50
|
+
| | |
|
|
51
|
+
| n0 | n1 | nd
|
|
52
|
+
| | |
|
|
53
|
+
B0 B1 Bd
|
|
54
|
+
| | |
|
|
55
|
+
| N0 | N1 | Nd
|
|
56
|
+
| | |
|
|
57
|
+
|
|
58
|
+
Here the Gi (TT cores) and Bi (Tucker cores) are small tensors contracted along the edges to form
|
|
59
|
+
a large dense N0 x ... x N(d-1) tensor. Unless stated otherwise, operations in this package are
|
|
60
|
+
defined with respect to the dense tensor that the T3 *represents*, even though that dense tensor
|
|
61
|
+
is never formed.
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
The package is pure Python. Dependencies: [`numpy`](https://numpy.org/install/) (required),
|
|
66
|
+
[`jax`](https://docs.jax.dev/en/latest/installation.html) (optional).
|
|
67
|
+
|
|
68
|
+
pip install t3toolbox
|
|
69
|
+
|
|
70
|
+
To include the optional JAX backend:
|
|
71
|
+
|
|
72
|
+
pip install "t3toolbox[jax]"
|
|
73
|
+
|
|
74
|
+
From source (development install):
|
|
75
|
+
|
|
76
|
+
git clone https://github.com/NickAlger/T3Toolbox.git
|
|
77
|
+
cd T3Toolbox
|
|
78
|
+
pip install -e .
|
|
79
|
+
|
|
80
|
+
## Quickstart
|
|
81
|
+
|
|
82
|
+
Create T3s and operate on the tensors they represent (arithmetic is dense-tensor arithmetic —
|
|
83
|
+
adding two T3s concatenates ranks; T3-SVD reduces back to minimal ranks):
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
import numpy as np
|
|
87
|
+
import t3toolbox as t3t
|
|
88
|
+
|
|
89
|
+
np.random.seed(0)
|
|
90
|
+
x = t3t.TuckerTensorTrain.randn((10, 11, 12), (3, 4, 3), (1, 2, 2, 1))
|
|
91
|
+
y = t3t.TuckerTensorTrain.randn((10, 11, 12), (2, 2, 2), (1, 2, 2, 1))
|
|
92
|
+
|
|
93
|
+
z = x + y
|
|
94
|
+
print(z.tucker_ranks, z.tt_ranks) # (5, 6, 5) (2, 4, 4, 2) <- ranks add ...
|
|
95
|
+
np.linalg.norm(z.to_dense() - (x.to_dense() + y.to_dense())) # ... tensors add: 0.0
|
|
96
|
+
|
|
97
|
+
z2, ss_tucker, ss_tt = z.t3svd() # reduce to minimal ranks (lossless)
|
|
98
|
+
print(z2.tucker_ranks, z2.tt_ranks) # (4, 6, 4) (1, 4, 4, 1)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Sample the represented tensor without forming it (`entries` / `apply` / `probe`, each also
|
|
102
|
+
available for tangent vectors and with symmetric-derivative generalizations):
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
ww = [np.random.randn(N) for N in x.shape]
|
|
106
|
+
zz = x.probe(ww) # d vectors, one per mode (all but one mode contracted)
|
|
107
|
+
a = x.apply(ww) # a scalar (all modes contracted)
|
|
108
|
+
e = x.entries(np.array([3, 1, 2])) # one entry
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Fit a fixed-rank T3 to sampled measurements by Riemannian optimization (a zero start on the
|
|
112
|
+
manifold; unit-norm probe rows keep the least-squares well-conditioned):
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
A = t3t.TuckerTensorTrain.randn((6, 7, 8), (2, 2, 2), (1, 2, 2, 1)) # the unknown target
|
|
116
|
+
ww = [np.random.randn(120, N) for N in A.shape]
|
|
117
|
+
ww = [w / np.linalg.norm(w, axis=1, keepdims=True) for w in ww] # unit-norm rows
|
|
118
|
+
b = A.apply(ww) # 120 measurements
|
|
119
|
+
|
|
120
|
+
x0 = t3t.TuckerTensorTrain.zeros((6, 7, 8), (2, 2, 2), (1, 2, 2, 1))
|
|
121
|
+
x_fit, stats = t3t.newton_cg(t3t.MANIFOLD, 'apply', ww, b, x0, max_newton=30)
|
|
122
|
+
# relative error of the recovery: < 1e-6
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Everything runs on NumPy or JAX — dispatch is inferred from the input array types, frontend
|
|
126
|
+
objects are jax pytrees (`jax.jit` applies to them directly), and passing a
|
|
127
|
+
`UniformTuckerTensorTrain` start runs the same fitting calls fully packed and jit-compile-once on
|
|
128
|
+
the uniform layer. See [Getting started](https://nickalger.github.io/T3Toolbox/getting_started.html)
|
|
129
|
+
for the full tour with verified outputs.
|
|
130
|
+
|
|
131
|
+
## Included functionality
|
|
132
|
+
|
|
133
|
+
- The **T3 format**: arithmetic with dense-tensor semantics, orthogonalization, minimal ranks,
|
|
134
|
+
**T3-SVD** (truncation / minimal-rank reduction), save/load, batching (`stack_shape`) on every
|
|
135
|
+
operation.
|
|
136
|
+
- The three **sampling operations** — `entries`, `apply`, `probe` — evaluating the represented
|
|
137
|
+
tensor without forming it, plus their **symmetric directional derivatives** (jets) and the
|
|
138
|
+
ambient/corewise/tangent **transposes**.
|
|
139
|
+
- The **fixed-rank T3 manifold**: orthogonal frame + gauged variations (`T3Frame`,
|
|
140
|
+
`T3Variations`, `T3Tangent`), gauge projections, retraction, and two geometries — the
|
|
141
|
+
Hilbert-Schmidt `MANIFOLD` and the Euclidean-coordinate `COREWISE`.
|
|
142
|
+
- **Least-squares fitting** from any of the sampling operations or their derivatives
|
|
143
|
+
(Gauss-Newton models) with four optimizers: `gradient_descent`, `mc_sgd`, `adam`, `newton_cg`.
|
|
144
|
+
- The **uniform layer**: zero-padded supercores + boolean rank masks mirroring the whole stack —
|
|
145
|
+
same results, uniform shapes — for `jax.lax.scan` vectorization, GPU efficiency, and
|
|
146
|
+
compile-once `jit` (optimizers included).
|
|
147
|
+
- **NumPy / JAX** backends with dispatch inferred from the input arrays; frontend classes are
|
|
148
|
+
registered jax pytrees.
|
|
149
|
+
- **Safe mode**: numerical preconditions (same tangent space, orthogonal frame, gauged
|
|
150
|
+
variations) checked by default, skippable for speed (`t3toolbox.unsafe()`); structural
|
|
151
|
+
problems always error.
|
|
152
|
+
|
|
153
|
+
## Documentation
|
|
154
|
+
|
|
155
|
+
https://nickalger.github.io/T3Toolbox/ — [getting started](https://nickalger.github.io/T3Toolbox/getting_started.html),
|
|
156
|
+
[user guide](https://nickalger.github.io/T3Toolbox/user_guide.html),
|
|
157
|
+
[design notes](https://nickalger.github.io/T3Toolbox/design_notes.html), and the full
|
|
158
|
+
[API reference](https://nickalger.github.io/T3Toolbox/api_reference.html) (frontend **and**
|
|
159
|
+
backend — the backend is a first-class, fully documented surface). Worked end-to-end fitting
|
|
160
|
+
examples live in [`examples/`](examples/). Contributing? Start with the
|
|
161
|
+
[Contributor guide](https://nickalger.github.io/T3Toolbox/contributor_guide.html).
|
|
162
|
+
|
|
163
|
+
## Authors
|
|
164
|
+
|
|
165
|
+
* Nick Alger (nalger225@gmail.com)
|
|
166
|
+
* Blake Christierson (bechristierson@utexas.edu)
|
|
167
|
+
|
|
168
|
+
MIT License. The algorithms are described in *Alger, Christierson, Chen & Ghattas (2026), "Tucker
|
|
169
|
+
Tensor Train Taylor Series"*, [arXiv:2603.21141](https://arxiv.org/abs/2603.21141).
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# T3Toolbox
|
|
2
|
+
|
|
3
|
+
[](https://github.com/NickAlger/T3Toolbox/actions/workflows/tests.yaml)
|
|
4
|
+
[](https://github.com/NickAlger/T3Toolbox/actions/workflows/build-sphinx-docs.yaml)
|
|
5
|
+
|
|
6
|
+
A pure-Python (NumPy + optional JAX) library for **Tucker tensor trains (T3)** — a Tucker
|
|
7
|
+
decomposition whose central core is stored as a tensor train. When the ranks are moderate, a T3
|
|
8
|
+
breaks the curse of dimensionality: storing a dense tensor costs O(N^d) memory, while the T3
|
|
9
|
+
representing it costs O(dnr^2 + dnN).
|
|
10
|
+
|
|
11
|
+
Tucker tensor trains are also known as **extended tensor trains (ETT)** — the two names refer to
|
|
12
|
+
the same format. This library uses "Tucker tensor train" (and the abbreviation T3) throughout, but
|
|
13
|
+
everything here applies equally if you know these objects as extended tensor trains.
|
|
14
|
+
|
|
15
|
+
Tensor network diagram for a Tucker tensor train:
|
|
16
|
+
|
|
17
|
+
r0 r1 r2 r(d-1) rd
|
|
18
|
+
1 ------ G0 ------ G1 ------ ... ------ G(d-1) ------ 1
|
|
19
|
+
| | |
|
|
20
|
+
| n0 | n1 | nd
|
|
21
|
+
| | |
|
|
22
|
+
B0 B1 Bd
|
|
23
|
+
| | |
|
|
24
|
+
| N0 | N1 | Nd
|
|
25
|
+
| | |
|
|
26
|
+
|
|
27
|
+
Here the Gi (TT cores) and Bi (Tucker cores) are small tensors contracted along the edges to form
|
|
28
|
+
a large dense N0 x ... x N(d-1) tensor. Unless stated otherwise, operations in this package are
|
|
29
|
+
defined with respect to the dense tensor that the T3 *represents*, even though that dense tensor
|
|
30
|
+
is never formed.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
The package is pure Python. Dependencies: [`numpy`](https://numpy.org/install/) (required),
|
|
35
|
+
[`jax`](https://docs.jax.dev/en/latest/installation.html) (optional).
|
|
36
|
+
|
|
37
|
+
pip install t3toolbox
|
|
38
|
+
|
|
39
|
+
To include the optional JAX backend:
|
|
40
|
+
|
|
41
|
+
pip install "t3toolbox[jax]"
|
|
42
|
+
|
|
43
|
+
From source (development install):
|
|
44
|
+
|
|
45
|
+
git clone https://github.com/NickAlger/T3Toolbox.git
|
|
46
|
+
cd T3Toolbox
|
|
47
|
+
pip install -e .
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
Create T3s and operate on the tensors they represent (arithmetic is dense-tensor arithmetic —
|
|
52
|
+
adding two T3s concatenates ranks; T3-SVD reduces back to minimal ranks):
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import numpy as np
|
|
56
|
+
import t3toolbox as t3t
|
|
57
|
+
|
|
58
|
+
np.random.seed(0)
|
|
59
|
+
x = t3t.TuckerTensorTrain.randn((10, 11, 12), (3, 4, 3), (1, 2, 2, 1))
|
|
60
|
+
y = t3t.TuckerTensorTrain.randn((10, 11, 12), (2, 2, 2), (1, 2, 2, 1))
|
|
61
|
+
|
|
62
|
+
z = x + y
|
|
63
|
+
print(z.tucker_ranks, z.tt_ranks) # (5, 6, 5) (2, 4, 4, 2) <- ranks add ...
|
|
64
|
+
np.linalg.norm(z.to_dense() - (x.to_dense() + y.to_dense())) # ... tensors add: 0.0
|
|
65
|
+
|
|
66
|
+
z2, ss_tucker, ss_tt = z.t3svd() # reduce to minimal ranks (lossless)
|
|
67
|
+
print(z2.tucker_ranks, z2.tt_ranks) # (4, 6, 4) (1, 4, 4, 1)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Sample the represented tensor without forming it (`entries` / `apply` / `probe`, each also
|
|
71
|
+
available for tangent vectors and with symmetric-derivative generalizations):
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
ww = [np.random.randn(N) for N in x.shape]
|
|
75
|
+
zz = x.probe(ww) # d vectors, one per mode (all but one mode contracted)
|
|
76
|
+
a = x.apply(ww) # a scalar (all modes contracted)
|
|
77
|
+
e = x.entries(np.array([3, 1, 2])) # one entry
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Fit a fixed-rank T3 to sampled measurements by Riemannian optimization (a zero start on the
|
|
81
|
+
manifold; unit-norm probe rows keep the least-squares well-conditioned):
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
A = t3t.TuckerTensorTrain.randn((6, 7, 8), (2, 2, 2), (1, 2, 2, 1)) # the unknown target
|
|
85
|
+
ww = [np.random.randn(120, N) for N in A.shape]
|
|
86
|
+
ww = [w / np.linalg.norm(w, axis=1, keepdims=True) for w in ww] # unit-norm rows
|
|
87
|
+
b = A.apply(ww) # 120 measurements
|
|
88
|
+
|
|
89
|
+
x0 = t3t.TuckerTensorTrain.zeros((6, 7, 8), (2, 2, 2), (1, 2, 2, 1))
|
|
90
|
+
x_fit, stats = t3t.newton_cg(t3t.MANIFOLD, 'apply', ww, b, x0, max_newton=30)
|
|
91
|
+
# relative error of the recovery: < 1e-6
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Everything runs on NumPy or JAX — dispatch is inferred from the input array types, frontend
|
|
95
|
+
objects are jax pytrees (`jax.jit` applies to them directly), and passing a
|
|
96
|
+
`UniformTuckerTensorTrain` start runs the same fitting calls fully packed and jit-compile-once on
|
|
97
|
+
the uniform layer. See [Getting started](https://nickalger.github.io/T3Toolbox/getting_started.html)
|
|
98
|
+
for the full tour with verified outputs.
|
|
99
|
+
|
|
100
|
+
## Included functionality
|
|
101
|
+
|
|
102
|
+
- The **T3 format**: arithmetic with dense-tensor semantics, orthogonalization, minimal ranks,
|
|
103
|
+
**T3-SVD** (truncation / minimal-rank reduction), save/load, batching (`stack_shape`) on every
|
|
104
|
+
operation.
|
|
105
|
+
- The three **sampling operations** — `entries`, `apply`, `probe` — evaluating the represented
|
|
106
|
+
tensor without forming it, plus their **symmetric directional derivatives** (jets) and the
|
|
107
|
+
ambient/corewise/tangent **transposes**.
|
|
108
|
+
- The **fixed-rank T3 manifold**: orthogonal frame + gauged variations (`T3Frame`,
|
|
109
|
+
`T3Variations`, `T3Tangent`), gauge projections, retraction, and two geometries — the
|
|
110
|
+
Hilbert-Schmidt `MANIFOLD` and the Euclidean-coordinate `COREWISE`.
|
|
111
|
+
- **Least-squares fitting** from any of the sampling operations or their derivatives
|
|
112
|
+
(Gauss-Newton models) with four optimizers: `gradient_descent`, `mc_sgd`, `adam`, `newton_cg`.
|
|
113
|
+
- The **uniform layer**: zero-padded supercores + boolean rank masks mirroring the whole stack —
|
|
114
|
+
same results, uniform shapes — for `jax.lax.scan` vectorization, GPU efficiency, and
|
|
115
|
+
compile-once `jit` (optimizers included).
|
|
116
|
+
- **NumPy / JAX** backends with dispatch inferred from the input arrays; frontend classes are
|
|
117
|
+
registered jax pytrees.
|
|
118
|
+
- **Safe mode**: numerical preconditions (same tangent space, orthogonal frame, gauged
|
|
119
|
+
variations) checked by default, skippable for speed (`t3toolbox.unsafe()`); structural
|
|
120
|
+
problems always error.
|
|
121
|
+
|
|
122
|
+
## Documentation
|
|
123
|
+
|
|
124
|
+
https://nickalger.github.io/T3Toolbox/ — [getting started](https://nickalger.github.io/T3Toolbox/getting_started.html),
|
|
125
|
+
[user guide](https://nickalger.github.io/T3Toolbox/user_guide.html),
|
|
126
|
+
[design notes](https://nickalger.github.io/T3Toolbox/design_notes.html), and the full
|
|
127
|
+
[API reference](https://nickalger.github.io/T3Toolbox/api_reference.html) (frontend **and**
|
|
128
|
+
backend — the backend is a first-class, fully documented surface). Worked end-to-end fitting
|
|
129
|
+
examples live in [`examples/`](examples/). Contributing? Start with the
|
|
130
|
+
[Contributor guide](https://nickalger.github.io/T3Toolbox/contributor_guide.html).
|
|
131
|
+
|
|
132
|
+
## Authors
|
|
133
|
+
|
|
134
|
+
* Nick Alger (nalger225@gmail.com)
|
|
135
|
+
* Blake Christierson (bechristierson@utexas.edu)
|
|
136
|
+
|
|
137
|
+
MIT License. The algorithms are described in *Alger, Christierson, Chen & Ghattas (2026), "Tucker
|
|
138
|
+
Tensor Train Taylor Series"*, [arXiv:2603.21141](https://arxiv.org/abs/2603.21141).
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
# Only the library package ships. Without this, setuptools' flat-layout auto-discovery finds every
|
|
6
|
+
# top-level directory that looks like a package (dev/, paper_experiments/, ...) and aborts with
|
|
7
|
+
# "Multiple top-level packages discovered in a flat-layout". Restrict discovery to t3toolbox (+ its
|
|
8
|
+
# subpackages, e.g. t3toolbox.backend); dev/, docs/, examples/, tests/, paper_experiments/ are not packaged.
|
|
9
|
+
[tool.setuptools.packages.find]
|
|
10
|
+
include = ["t3toolbox*"]
|
|
11
|
+
|
|
12
|
+
[project]
|
|
13
|
+
name = "t3toolbox"
|
|
14
|
+
version = "2026.0.0"
|
|
15
|
+
description = "Library for working with Tucker tensor trains (extended tensor trains)"
|
|
16
|
+
requires-python = ">=3.9"
|
|
17
|
+
# Floors = the tested compatibility floor (CI: numpy 1.x + jax 0.4.30 on py3.9; numpy 2.x + latest jax on py3.11)
|
|
18
|
+
dependencies = [
|
|
19
|
+
"numpy>=1.22",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
authors = [
|
|
23
|
+
{name = "Nick Alger", email = "nalger225@gmail.com"},
|
|
24
|
+
{name = "Blake Christierson", email="bechristierson@utexas.edu"},
|
|
25
|
+
]
|
|
26
|
+
maintainers = [
|
|
27
|
+
{name = "Nick Alger", email = "nalger225@gmail.com"}
|
|
28
|
+
]
|
|
29
|
+
readme = "README.md"
|
|
30
|
+
license = "MIT"
|
|
31
|
+
license-files = ["LICENSE"]
|
|
32
|
+
keywords = ["Tucker tensor train", "extended tensor train", "ETT", "Tucker decomposition", "tensor train", "tensor"]
|
|
33
|
+
classifiers = [
|
|
34
|
+
"Development Status :: 5 - Production/Stable",
|
|
35
|
+
"Intended Audience :: Science/Research",
|
|
36
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
37
|
+
"Operating System :: OS Independent",
|
|
38
|
+
"Programming Language :: Python :: 3",
|
|
39
|
+
"Programming Language :: Python :: 3.9",
|
|
40
|
+
"Programming Language :: Python :: 3.10",
|
|
41
|
+
"Programming Language :: Python :: 3.11",
|
|
42
|
+
"Programming Language :: Python :: 3.12",
|
|
43
|
+
"Programming Language :: Python :: 3.13",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.optional-dependencies]
|
|
47
|
+
jax = ["jax>=0.4.30"]
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
Homepage = "https://github.com/NickAlger/T3Toolbox"
|
|
51
|
+
Documentation = "https://nickalger.github.io/T3Toolbox/"
|
|
52
|
+
Repository = "https://github.com/NickAlger/T3Toolbox"
|
|
53
|
+
"Bug Tracker" = "https://github.com/NickAlger/T3Toolbox/issues"
|
|
54
|
+
Changelog = "https://github.com/NickAlger/T3Toolbox/blob/main/CHANGELOG.md"
|
|
55
|
+
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Authors: Nick Alger and Blake Christierson
|
|
2
|
+
# Copyright: MIT License (2026)
|
|
3
|
+
# Github: https://github.com/NickAlger/T3Toolbox
|
|
4
|
+
# Documentation: https://nickalger.github.io/T3Toolbox/index.html
|
|
5
|
+
"""T3Toolbox: Tucker tensor trains (T3) -- a Tucker decomposition whose central core is
|
|
6
|
+
stored as a tensor train.
|
|
7
|
+
|
|
8
|
+
This package root re-exports the **frontend** surface: the tensor classes (ragged and
|
|
9
|
+
uniform), the frame/variations/tangent classes, the geometry singletons, the Gauss-Newton
|
|
10
|
+
fitting models, and the optimizers. **Backend users import submodules explicitly** (e.g.
|
|
11
|
+
``from t3toolbox.backend import probing``) -- the backend is namespaced by module and
|
|
12
|
+
deliberately not re-exported here. Naming conventions: ``docs/naming_conventions.md``.
|
|
13
|
+
"""
|
|
14
|
+
from t3toolbox.tucker_tensor_train import TuckerTensorTrain
|
|
15
|
+
from t3toolbox.uniform_tucker_tensor_train import UniformTuckerTensorTrain
|
|
16
|
+
from t3toolbox.frame_variations_format import T3Frame, T3Variations, t3_orthogonal_representations
|
|
17
|
+
from t3toolbox.uniform_frame_variations_format import UT3Frame, UT3Variations, ut3_orthogonal_representations
|
|
18
|
+
from t3toolbox.manifold import T3Tangent, MANIFOLD, COREWISE
|
|
19
|
+
from t3toolbox.uniform_manifold import UT3Tangent, UNIFORM_MANIFOLD, UNIFORM_COREWISE
|
|
20
|
+
from t3toolbox.fitting import (
|
|
21
|
+
GaussNewtonModel,
|
|
22
|
+
UniformGaussNewtonModel,
|
|
23
|
+
apply_model,
|
|
24
|
+
entries_model,
|
|
25
|
+
probe_model,
|
|
26
|
+
apply_derivatives_model,
|
|
27
|
+
entries_derivatives_model,
|
|
28
|
+
probe_derivatives_model,
|
|
29
|
+
)
|
|
30
|
+
from t3toolbox.optimizers import gradient_descent, mc_sgd, adam, newton_cg
|
|
31
|
+
from t3toolbox import safety
|
|
32
|
+
from t3toolbox.safety import safe, unsafe
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
from importlib.metadata import version as _pkg_version
|
|
36
|
+
__version__ = _pkg_version('t3toolbox')
|
|
37
|
+
except Exception: # not installed (e.g. PYTHONPATH use) -- keep in sync with pyproject.toml
|
|
38
|
+
__version__ = '2026.0.0'
|
|
39
|
+
|
|
40
|
+
__all__ = [
|
|
41
|
+
# tensors
|
|
42
|
+
'TuckerTensorTrain',
|
|
43
|
+
'UniformTuckerTensorTrain',
|
|
44
|
+
# frames / variations / tangents
|
|
45
|
+
'T3Frame',
|
|
46
|
+
'T3Variations',
|
|
47
|
+
'T3Tangent',
|
|
48
|
+
'UT3Frame',
|
|
49
|
+
'UT3Variations',
|
|
50
|
+
'UT3Tangent',
|
|
51
|
+
't3_orthogonal_representations',
|
|
52
|
+
'ut3_orthogonal_representations',
|
|
53
|
+
# geometries
|
|
54
|
+
'MANIFOLD',
|
|
55
|
+
'COREWISE',
|
|
56
|
+
'UNIFORM_MANIFOLD',
|
|
57
|
+
'UNIFORM_COREWISE',
|
|
58
|
+
# fitting models
|
|
59
|
+
'GaussNewtonModel',
|
|
60
|
+
'UniformGaussNewtonModel',
|
|
61
|
+
'apply_model',
|
|
62
|
+
'entries_model',
|
|
63
|
+
'probe_model',
|
|
64
|
+
'apply_derivatives_model',
|
|
65
|
+
'entries_derivatives_model',
|
|
66
|
+
'probe_derivatives_model',
|
|
67
|
+
# optimizers
|
|
68
|
+
'gradient_descent',
|
|
69
|
+
'mc_sgd',
|
|
70
|
+
'adam',
|
|
71
|
+
'newton_cg',
|
|
72
|
+
# safety mode
|
|
73
|
+
'safety',
|
|
74
|
+
'safe',
|
|
75
|
+
'unsafe',
|
|
76
|
+
]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"""The pure-functional backend: stateless functions on raw core-tuple / supercore data.
|
|
2
|
+
|
|
3
|
+
Deliberately empty: backend users import submodules explicitly (e.g.
|
|
4
|
+
``from t3toolbox.backend import probing``) -- each module namespaces one
|
|
5
|
+
(representation family) x (operation kind) cell, and each carries its own ``__all__``.
|
|
6
|
+
See ``docs/naming_conventions.md`` for the family prefix grammar and the module map.
|
|
7
|
+
"""
|