Skip to content

Commit afa00ea

Browse files
authored
[codex] Add quantics transform parity wrappers (#28)
* add quantics transform parity wrappers * pin fallback build to quantics transform C API
1 parent 1de1c76 commit afa00ea

12 files changed

Lines changed: 579 additions & 109 deletions

AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ As of commit `ca97593` (PR #302), tensor4all-rs uses **column-major** storage fo
3636
## Build & Test
3737

3838
- Rust library: `deps/build.jl` builds `libtensor4all_capi.so` from `tensor4all-rs`
39+
- When running `deps/build.jl` directly, use `julia --startup-file=no --project=. deps/build.jl`
3940
- Rust source resolution: `TENSOR4ALL_RS_PATH` env var > sibling `../tensor4all-rs/` > GitHub clone
4041
- Tests: `Pkg.test()` or `julia test/runtests.jl` (requires ITensors.jl in test deps)
4142
- Skip HDF5 tests: `T4A_SKIP_HDF5_TESTS=1`
43+
44+
## PR Checklist
45+
46+
- Before opening or updating a PR, review `README.md` and update user-facing examples and workflow notes if the API or expected commands changed.

README.md

Lines changed: 105 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -18,55 +18,48 @@ After installation, open a new terminal or run `source ~/.cargo/env`.
1818

1919
## Installation
2020

21-
The Rust shared library is **automatically compiled** by `Pkg.build()`. No manual build steps are required.
21+
The Rust shared library is compiled automatically by `Pkg.build()`.
2222

23-
### Option 1: Develop locally (for package development)
23+
### Option 1: Develop locally
2424

2525
```julia
2626
using Pkg
2727
Pkg.activate("/path/to/Tensor4all.jl")
28-
Pkg.build() # Automatically compiles the Rust backend
28+
Pkg.build()
2929
```
3030

31-
The shared library is installed to:
32-
```
33-
/path/to/Tensor4all.jl/deps/libtensor4all_capi.{dylib,so,dll}
34-
```
35-
36-
### Option 2: Develop from another environment or global
31+
### Option 2: Develop from another environment
3732

3833
```julia
3934
using Pkg
4035
Pkg.develop(path="/path/to/Tensor4all.jl")
41-
Pkg.build("Tensor4all") # Automatically compiles the Rust backend
42-
```
43-
44-
The shared library is installed to:
45-
```
46-
/path/to/Tensor4all.jl/deps/libtensor4all_capi.{dylib,so,dll}
36+
Pkg.build("Tensor4all")
4737
```
48-
(Same location as the source — `Pkg.develop` symlinks to the local directory.)
4938

50-
### Option 3: Add from another environment (e.g., from GitHub URL)
39+
### Option 3: Add from GitHub
5140

5241
```julia
5342
using Pkg
5443
Pkg.add(url="https://github.com/tensor4all/Tensor4all.jl.git")
55-
Pkg.build("Tensor4all") # Automatically compiles the Rust backend
44+
Pkg.build("Tensor4all")
5645
```
5746

58-
The shared library is installed to:
59-
```
60-
~/.julia/packages/Tensor4all/<hash>/deps/libtensor4all_capi.{dylib,so,dll}
61-
```
47+
The built shared library lives in `deps/libtensor4all_capi.{dylib,so,dll}` inside
48+
the package directory.
6249

6350
### Rust source resolution
6451

65-
The build script locates the `tensor4all-rs` Rust workspace in this priority order:
52+
`deps/build.jl` looks for `tensor4all-rs` in this order:
6653

6754
1. `TENSOR4ALL_RS_PATH` environment variable
68-
2. Sibling directory `../tensor4all-rs/` (relative to the package root)
69-
3. Automatic clone from GitHub at the pinned fallback commit in [deps/build.jl](deps/build.jl)
55+
2. sibling directory `../tensor4all-rs/`
56+
3. clone from GitHub at the pinned fallback commit in [deps/build.jl](deps/build.jl)
57+
58+
If you run the build script directly, use the package project:
59+
60+
```bash
61+
julia --startup-file=no --project=. deps/build.jl
62+
```
7063

7164
## Running Tests
7265

@@ -76,130 +69,138 @@ Pkg.activate("/path/to/Tensor4all.jl")
7669
Pkg.test()
7770
```
7871

79-
To skip HDF5 tests: set `T4A_SKIP_HDF5_TESTS=1` before running.
72+
To skip HDF5 tests, set `T4A_SKIP_HDF5_TESTS=1`.
73+
74+
## Modules
75+
76+
- `Tensor4all`: `Index`, `Tensor`, `onehot`, HDF5 save/load
77+
- `Tensor4all.SimpleTT`: simple tensor trains with fixed site dimensions
78+
- `Tensor4all.TreeTN`: MPS/MPO/tree tensor network operations
79+
- `Tensor4all.QuanticsGrids`: coordinate transforms between physical and quantics grids
80+
- `Tensor4all.QuanticsTransform`: quantics shift/flip/phase/cumsum/Fourier/affine operators
81+
- `Tensor4all.QuanticsTCI`: quantics tensor cross interpolation
82+
- `Tensor4all.TreeTCI`: tree-structured tensor cross interpolation
8083

8184
## Usage
8285

8386
```julia
8487
using Tensor4all
8588
```
8689

87-
### Index
90+
### Index and Tensor
8891

8992
```julia
90-
# Create an index with dimension 5
91-
i = Index(5)
92-
93-
# Create an index with tags
93+
i = Index(2)
9494
j = Index(3; tags="Site,n=1")
9595

96-
# Access properties
97-
dim(i) # 5
98-
id(i) # unique UInt64 ID
96+
dim(i) # 2
9997
tags(j) # "Site,n=1"
10098
hastag(j, "Site") # true
10199

102-
# Copy an index (same ID)
103-
j2 = copy(j)
100+
t = Tensor([i, j], rand(2, 3))
101+
rank(t) # 2
102+
dims(t) # (2, 3)
103+
storage_kind(t) # DenseF64
104+
indices(t) # [i, j]
104105

105-
# Create a similar index (new ID, same dim and tags)
106-
j3 = sim(j)
106+
z = Tensor([i, j], rand(ComplexF64, 2, 3))
107+
oh = onehot(i => 1, j => 2)
107108
```
108109

109-
### Tensor
110+
### Simple Tensor Trains
110111

111112
```julia
112-
i = Index(2)
113-
j = Index(3)
114-
115-
# Create a dense Float64 tensor
116-
data = rand(2, 3)
117-
t = Tensor([i, j], data)
118-
119-
# Access properties
120-
rank(t) # 2
121-
dims(t) # (2, 3)
122-
storage_kind(t) # DenseF64
123-
indices(t) # [i, j]
124-
125-
# Retrieve data (column-major Julia array)
126-
retrieved = Tensor4all.data(t)
127-
128-
# Retrieve data in a specific index order
129-
arr = Array(t, [j, i]) # shape (3, 2), transposed
130-
131-
# Create a complex tensor
132-
z = Tensor([i, j], rand(ComplexF64, 2, 3))
113+
using Tensor4all.SimpleTT
133114

134-
# Create a higher-rank tensor
135-
k = Index(4)
136-
t3 = Tensor([i, j, k], rand(2, 3, 4))
115+
tt = SimpleTensorTrain([2, 3, 4], 1.0)
137116

138-
# Create a one-hot tensor
139-
oh = onehot(i => 1, j => 2) # 1.0 at position [1, 2]
117+
tt(0, 0, 0) # 1.0
118+
Tensor4all.SimpleTT.site_dims(tt) # [2, 3, 4]
119+
Tensor4all.SimpleTT.link_dims(tt) # []
120+
Tensor4all.SimpleTT.site_tensor(tt, 0)
121+
sum(tt)
140122
```
141123

142-
### MPS (Matrix Product State) / Tensor Train
124+
### Tree Tensor Networks
143125

144126
```julia
145127
using Tensor4all.TreeTN
146128

147-
# Create a random MPS
148129
sites = [Index(2) for _ in 1:5]
149130
mps = random_mps(sites; linkdims=4)
150131

151-
# Properties
152-
length(mps) # 5
153-
nv(mps) # 5 (number of vertices)
154-
ne(mps) # 4 (number of edges)
155-
maxbonddim(mps) # 4
156-
linkdims(mps) # [4, 4, 4, 4]
132+
length(mps) # 5
133+
nv(mps) # 5
134+
ne(mps) # 4
135+
maxbonddim(mps) # 4
157136

158-
# Access tensors (1-indexed)
159-
mps[1] # first tensor
160-
collect(mps) # all tensors as a vector
161-
162-
# Orthogonalize (QR-based canonical form)
163137
orthogonalize!(mps, 3)
164-
canonical_form(mps) # Unitary
165-
166-
# Other canonical forms: LU, CI
167-
orthogonalize!(mps, 1; form=LU)
168-
169-
# Truncate bond dimensions
170138
truncate!(mps; maxdim=2)
139+
inner(mps, mps)
140+
to_dense(mps)
141+
```
171142

172-
# Inner product and norm
173-
ip = inner(mps, mps)
174-
n = norm(mps)
143+
`SimpleTensorTrain` can also be converted to an MPS:
175144

176-
# Contract to a dense tensor
177-
dense = to_dense(mps)
145+
```julia
146+
using Tensor4all.SimpleTT: SimpleTensorTrain
147+
using Tensor4all.TreeTN: MPS
178148

179-
# Contract two MPS/MPO
180-
result = contract(mps_a, mps_b) # zipup (default)
181-
result = contract(mps_a, mps_b; method=:fit) # fit
182-
result = contract(mps_a, mps_b; method=:naive) # naive
149+
mps = MPS(SimpleTensorTrain([2, 2, 2], 1.0))
183150
```
184151

185-
### Tensor Cross Interpolation (TCI)
152+
### Quantics Grids
186153

187154
```julia
188-
using Tensor4all.TensorCI
189-
using Tensor4all.SimpleTT
155+
using Tensor4all: DiscretizedGrid, localdimensions
156+
using Tensor4all.QuanticsGrids: origcoord_to_quantics, quantics_to_origcoord
190157

191-
# Approximate a function as a tensor train
192-
f(i, j, k) = Float64((1 + i) * (1 + j) * (1 + k)) # 0-based indices
193-
tt, err = crossinterpolate2(f, [3, 4, 5]; tolerance=1e-10)
158+
grid = DiscretizedGrid(2, [2, 2], [0.0, 0.0], [1.0, 1.0]; unfolding=:grouped)
194159

195-
# Evaluate the tensor train
196-
tt(0, 0, 0) # ≈ 1.0
197-
tt(2, 3, 4) # ≈ 60.0
160+
q = origcoord_to_quantics(grid, [0.25, 0.75])
161+
x = quantics_to_origcoord(grid, q)
198162

199-
# Sum over all elements
200-
sum(tt)
163+
length(q) # 4
164+
x # approximately [0.25, 0.75]
165+
localdimensions(grid) # [2, 2, 2, 2]
166+
```
167+
168+
### Quantics Transform
169+
170+
```julia
171+
using Tensor4all.SimpleTT: SimpleTensorTrain
172+
using Tensor4all.TreeTN: MPS
173+
using Tensor4all.QuanticsTransform
174+
175+
mps = MPS(SimpleTensorTrain([2, 2, 2], 1.0))
176+
177+
op = shift_operator(3, 1)
178+
set_iospaces!(op, mps)
179+
shifted = apply(op, mps; method=:naive)
180+
181+
multi = shift_operator_multivar(3, 1, 2, 0)
182+
flipped = flip_operator_multivar(3, 2, 1; bc=Open)
183+
phase = phase_rotation_operator_multivar(3, pi / 4, 2, 1)
184+
aff = affine_operator(
185+
3,
186+
Int64[1 -1; 1 0; 0 1],
187+
ones(Int64, 3, 2),
188+
Int64[0, 0, 0],
189+
ones(Int64, 3);
190+
bc=[Open, Periodic, Periodic],
191+
)
201192
```
202193

194+
### Interpolation Modules
195+
196+
High-level interpolation APIs are available in:
197+
198+
- `Tensor4all.QuanticsTCI`
199+
- `Tensor4all.TreeTCI`
200+
201+
See the module docstrings in `src/QuanticsTCI.jl` and `src/TreeTCI.jl` for the
202+
current entry points.
203+
203204
### HDF5 Save/Load
204205

205206
Tensors and MPS can be saved to HDF5 files in a format compatible with ITensors.jl.

deps/build.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ using Libdl
1212
using RustToolChain: cargo
1313

1414
# Configuration
15-
const TENSOR4ALL_RS_FALLBACK_COMMIT = "8a68db84d517286ee55fda3585eebb26667e200a"
15+
const TENSOR4ALL_RS_FALLBACK_COMMIT = "44ddedb3ff801f80c2f8d1609bf43eb28081a9f1"
1616
const TENSOR4ALL_RS_REPO = "https://github.com/tensor4all/tensor4all-rs.git"
1717

1818
# Paths

0 commit comments

Comments
 (0)