Skip to content

Commit

Permalink
Moving to GitHub
Browse files Browse the repository at this point in the history
  • Loading branch information
shinaoka committed May 3, 2024
1 parent 218c047 commit 212c528
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 257 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
# Skip intermediate builds: always.
# Cancel intermediate builds: only if it is a pull request build.
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1.9'
- '1'
os:
- ubuntu-latest
#- macOS-latest
#- windows-latest
arch:
- x64
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
continue-on-error: ${{ matrix.version == 'nightly' }}
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v3
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1'
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
33 changes: 33 additions & 0 deletions .github/workflows/TagBot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: TagBot
on:
issue_comment:
types:
- created
workflow_dispatch:
inputs:
lookback:
default: "3"
permissions:
actions: read
checks: read
contents: write
deployments: read
issues: read
discussions: read
packages: read
pages: read
pull-requests: read
repository-projects: read
security-events: read
statuses: read
jobs:
TagBot:
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
runs-on: ubuntu-latest
steps:
- uses: JuliaRegistries/TagBot@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Edit the following line to reflect the actual name of the GitHub Secret containing your private key
ssh: ${{ secrets.DOCUMENTER_KEY }}
# ssh: ${{ secrets.NAME_OF_MY_SSH_PRIVATE_KEY_SECRET }}
260 changes: 6 additions & 254 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,266 +1,18 @@
# QuanticsGrids

[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://tensors4fields.gitlab.io/QuanticsGrids.jl/dev/index.html)
[![pipeline status](https://gitlab.com/tensors4fields/QuanticsGrids.jl/badges/main/pipeline.svg)](https://gitlab.com/tensors4fields/QuanticsGrids.jl/-/commits/main)
[![coverage report](https://gitlab.com/tensors4fields/QuanticsGrids.jl/badges/main/coverage.svg)](https://gitlab.com/tensors4fields/QuanticsGrids.jl/-/commits/main)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://tensor4all.github.io/QuanticsGrids.jl/dev)
[![CI](https://github.com/tensor4all/QuanticsGrids.jl/actions/workflows/CI.yml/badge.svg)](https://github.com/tensor4all/QuanticsGrids.jl/actions/workflows/CI.yml)

This module contains utilities for interpolations of functions in the quantics TCI / quantics tensor train (QTT) format.
This library provides utilities for interpolations of functions in the quantics TCI / quantics tensor train (QTT) format.

## Installation

This module has been registered in the General registry. It can be installed by typing the following in a Julia REPL:
The following will install QuanticsGrids.jl:

```julia
julia> using Pkg; Pkg.add("QuanticsGrids.jl")
```

## Definition
We first introduce a $B$-base presentation ($B=2, 3, 4, \cdots$).
To avoid confusing, we will use the 1-based indexing of Julia below.
We represent a positive integer $X~(\ge 1)$ as

$$
X= \sum_{i=1}^R (x_i-1) \times B^{R-i+1} + 1,
$$

where $x_i$ is either 1 or 2 and $R$ is the number of digits.
In this library, the $B$-base representation of $X$ is represented by the vector

$$[x_1, \cdots, x_R].$$

This library supports two unfolding schemes (interleaved and fused representations) for handling multiple variables.
As an example, we consider three variables $X$, $Y$ and $Z$.
Their $B$-base representations are given by

$$[x_1, \cdots, x_R], [y_1, \cdots, y_R], [z_1, \cdots, z_R],$$

respectively.
The interleaved representation of these variables reads

$$[x_1, y_1, z_1, x_2, y_2, z_2, \cdots, x_R, y_R, z_R].$$

The fused representation is given by

$$[\alpha_1, \alpha_2, \cdots, \alpha_R],$$

where

$$
\alpha_i = (x_i-1) + B(y_i-1) + B^2 (z_i-1) + 1
$$

with

$$
1 \le \alpha_i \le B^3.
$$

This convention is consistent with the column major used in Julia: At each digit level $i$, the bit for $x$ runs fastest.
The fused representaion generalizes to any number of variables.


## Usage
This package contains two main functionalities:

1. Low-level functions for converting betwen linear and quantics representations
2. High-level interface for creating a grid

The normal users will use the second high-level interface.
We will describe its usage.

## Discretized grid
`DiscretizedGrid` can be used to discretize a $d$-dimensional space.

## Creating a one-dimensional grid

We can create a one-dimensional grid by discretizing $x$ axis on $[0, 1)$ with $R$ bits as

```julia
import QuanticsGrids as QD
xmin = 0.0
xmax = 1.0
R = 4
grid = QD.DiscretizedGrid{1}(R, xmin, xmax)
````

Here, `DiscretizedGrid` takes one parameter `1`, which denotes the dimension of the grid.
There are six functions for translating between different reprenstations:
`grididx` (1-based linear index), `quantics` and `origcoord` (original coordiate, i.e., $x$).

Example:
```julia
quantics = fill(1, R)
origcoord = 0.0
grididx = 1
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
quantics = fill(2, R)
origcoord = 1-1/2^R
grididx = 2^R
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
```

Optionally, one can include the end point `grid_max` in a grid as

```julia
import QuanticsGrids as QD
xmin = 0.0
xmax = 1.0
R = 4
grid = QD.DiscretizedGrid{1}(R, xmin, xmax; includeendpoint=true)
@assert QD.grididx_to_origcoord(grid, 1) == xmin
@assert QD.grididx_to_origcoord(grid, 2^R) == xmax
````

## Creating a $d$-dimensional grid
A $d$-dimensional grid, where each axis is discretized with $R$ bits, can be generated in a similar way as follows.
As an option, you can choose the fused representation (`:fused`) or the interleaved representation (`:interleaved`).

### fused representation
```julia
import QuanticsGrids as QD
xmin, xmax = 0.0, 1.0
ymin, ymax = 0.0, 1.0
zmin, zmax = 0.0, 1.0
R = 4
grid = QD.DiscretizedGrid{3}(R, (xmin,ymin,zmin), (xmax,ymax,zmax); unfoldingscheme=:fused)
quantics = fill(1, R)
origcoord = (0.0, 0.0, 0.0)
grididx = (1, 1, 1)
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
# Incrementing the least significant fused bits increments the $x$ index.
quantics = vcat(fill(1, R-1), 2) # [1, 1, ..., 1, 2]
origcoord = (1/2^R, 0.0, 0.0)
grididx = (2, 1, 1)
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
```

### Interleaved representation
```julia
import QuanticsGrids as QD
xmin, xmax = 0.0, 1.0
ymin, ymax = 0.0, 1.0
zmin, zmax = 0.0, 1.0
R = 4
grid = QD.DiscretizedGrid{3}(R, (xmin,ymin,zmin), (xmax,ymax,zmax); unfoldingscheme=QD.UnfoldingSchemes.interleaved)
# (x1, y1, z1, ...., xR, yR, zR)
quantics = fill(1, 3R) # length is 3R
origcoord = (0.0, 0.0, 0.0)
grididx = (1, 1, 1)
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
quantics = vcat(fill(1, 3R-3), [2, 1, 1]) # [1, 1, 1, ..., 2, 1, 1]
origcoord = (1/2^R, 0.0, 0.0)
grididx = (2, 1, 1)
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
```

## Inherent discrete grid
`InherentDiscreteGrid` can be used if the target space is discrete.
`InherentDiscreteGrid` has a very similar interface to `DiscretizedGrid`.
We provide one example.

```julia
import QuanticsGrids as QD
R = 4
# Grid: [0, 1, ..., 2^R-1]. The second argument (0,) specifies the origin.
grid = QD.InherentDiscreteGrid{1}(R, 0; step=1)
quantics = fill(1, R)
origcoord = 0
grididx = 1
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
quantics = fill(2, R)
origcoord = 2^R-1
grididx = 2^R
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
```

## Use a base other than `2`
When creating a grid, we may want to choose a different base other than 2.

```julia
import QuanticsGrids as QD
R = 4
base = 10
# Grid: [0, 1, ..., 10^R-1]
grid = QD.InherentDiscreteGrid{1}(R, (0,); base=10)
quantics = fill(base, R)
origcoord = base^R-1
grididx = base^R
@assert QD.quantics_to_grididx(grid, quantics) == grididx
@assert QD.quantics_to_origcoord(grid, quantics) == origcoord
@assert QD.grididx_to_quantics(grid, grididx) == quantics
@assert QD.grididx_to_origcoord(grid, grididx) == origcoord
@assert QD.origcoord_to_quantics(grid, origcoord) == quantics
@assert QD.origcoord_to_grididx(grid, origcoord) == grididx
```

## Create a function that takes a quantics index as its input
When using `QuanticsGrids.jl` in combination with `TensorCrossInterpolation.jl`,
one can wrap a function to be interpolated to make a fuction that takes a quantics index:

```julia
import QuanticsGrids as QD
import TensorCrossInterpolation as TCI
R = 4
grid = QD.DiscretizedGrid{2}(R, (0.0, 0.0), (1.0, 1.0))
f(x, y) = sin(x + y) # Function to be interpolated
initialpivots = [fill(1, R)]
localdims = fill(2^2, R)
fq = QD.quanticsfunction(Float64, grid, f) # fq takes an quantics index as an input
tci, ranks, errors = TCI.crossinterpolate2(Float64, fq, localdims, initialpivots; tolerance=1e-8)
````

## References
- M. K. Ritter, Y. N. Fernández, M. Wallerberger, J. von Delft, H. Shinaoka, and X. Waintal, *Quantics Tensor Cross Interpolation for High-Resolution, Parsimonious Representations of Multivariate Functions in Physics and Beyond*, [Phys. Rev. Lett. <b>132</b>, 056501 (2024)](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.132.056501)/[arXiv:2303.11819](http://arxiv.org/abs/2303.11819).
Please refer to the [documentation](https://tensor4all.github.io/QuanticsGrids.jl/) for usage.
1 change: 1 addition & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
QuanticsGrids = "634c7f73-3e90-4749-a1bd-001b8efc642d"
TensorCrossInterpolation = "b261b2ec-6378-4871-b32e-9173bb050604"

[compat]
Documenter = "1"
9 changes: 6 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ DocMeta.setdocmeta!(QuanticsGrids, :DocTestSetup, :(using QuanticsGrids); recurs
makedocs(;
modules=[QuanticsGrids],
authors="Ritter.Marc <[email protected]> and contributors",
repo="https://gitlab.com/tensors4fields/QuanticsGrids.jl/blob/{commit}{path}#{line}",
sitename="QuanticsGrids.jl",
format=Documenter.HTML(;
prettyurls=get(ENV, "CI", "false") == "true",
repolink="https://gitlab.com/tensors4fields/QuanticsGrids.jl",
canonical="https://github.com/tensor4all/QuanticsGrids.jl",
edit_link="main",
assets=String[]),
pages=[
"Home" => "index.md",
"API Reference" => "apireference.md",
])

deploydocs(;
repo="github.com/tensor4all/QuanticsGrids.jl.git",
devbranch="main",
)
Loading

0 comments on commit 212c528

Please sign in to comment.