diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 79bbb9d..043af15 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -46,11 +46,32 @@ jobs: - name: Run tests run: cargo nextest run --release + docs: + name: Docs + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Install mdBook + run: cargo install mdbook --no-default-features --features search --vers "^0.5" --locked + + - name: Verify executable book examples + run: ./scripts/test-book-examples.sh + + - name: Build mdBook + run: mdbook build + rollup: runs-on: ubuntu-latest needs: - lint - test + - docs if: always() steps: - name: All checks passed diff --git a/.github/workflows/docs-pages.yml b/.github/workflows/docs-pages.yml new file mode 100644 index 0000000..6ea9dfc --- /dev/null +++ b/.github/workflows/docs-pages.yml @@ -0,0 +1,57 @@ +name: Docs Pages + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: docs-pages + cancel-in-progress: true + +jobs: + build: + name: Build docs artifact + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Install mdBook + run: cargo install mdbook --no-default-features --features search --vers "^0.5" --locked + + - name: Verify executable book examples + run: ./scripts/test-book-examples.sh + + - name: Build mdBook + run: mdbook build + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: book + + deploy: + name: Deploy docs + runs-on: ubuntu-latest + needs: build + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index ea8c4bf..037d408 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ /target +.worktrees/ +/book +/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 48a7d5f..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,654 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - -[[package]] -name = "anstyle" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "bumpalo" -version = "3.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" - -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" -dependencies = [ - "clap_builder", -] - -[[package]] -name = "clap_builder" -version = "4.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" -dependencies = [ - "anstyle", - "clap_lex", -] - -[[package]] -name = "clap_lex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" - -[[package]] -name = "criterion" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" -dependencies = [ - "anes", - "cast", - "ciborium", - "clap", - "criterion-plot", - "is-terminal", - "itertools", - "num-traits", - "once_cell", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "zerocopy", -] - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "is-terminal" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" - -[[package]] -name = "js-sys" -version = "0.3.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" - -[[package]] -name = "memchr" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" - -[[package]] -name = "oorandom" -version = "11.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" - -[[package]] -name = "plotters" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" - -[[package]] -name = "plotters-svg" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quanticsgrids" -version = "0.1.0" -dependencies = [ - "criterion", - "rand", - "thiserror", -] - -[[package]] -name = "quote" -version = "1.0.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "regex" -version = "1.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "syn" -version = "2.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "unicode-ident" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "wasip2" -version = "1.0.2+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" - -[[package]] -name = "zerocopy" -version = "0.8.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index ce86131..4aaa653 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ authors = [ "Hiroshi Shinaoka ", "Samuel Badr ", ] -license = "MIT" +license = "MIT OR Apache-2.0" repository = "https://github.com/tensor4all/quanticsgrids-rs" description = "Quantics grid structures for efficient conversion between quantics, grid indices, and original coordinates" diff --git a/LICENSE b/LICENSE index 7402fe9..e5399e7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,5 @@ -MIT License +This project is licensed under either of the following, at your option: -Copyright (c) 2026 tensor4all - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +- Apache License, Version 2.0 (see LICENSE-APACHE or + https://www.apache.org/licenses/LICENSE-2.0) +- MIT license (see LICENSE-MIT or https://opensource.org/licenses/MIT) diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..739aad3 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 tensor4all + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..7402fe9 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 tensor4all + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d15fa16..3088582 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ Grid structures for efficient conversion between quantics representation, grid indices, and original coordinates. This is a Rust port of [QuanticsGrids.jl](https://github.com/tensor4all/QuanticsGrids.jl). +## Documentation + +- User guide: https://tensor4all.github.io/quanticsgrids-rs/ + ## Features - **InherentDiscreteGrid**: Low-level grid for integer coordinates @@ -41,4 +45,7 @@ let local_dims = grid.local_dimensions(); ## License -MIT License +Licensed under either of the following, at your option: + +- Apache License, Version 2.0 +- MIT license diff --git a/book.toml b/book.toml new file mode 100644 index 0000000..573f9f3 --- /dev/null +++ b/book.toml @@ -0,0 +1,20 @@ +[book] +title = "quanticsgrids User Guide" +authors = ["tensor4all contributors"] +language = "en" +src = "docs/src" + +[build] +build-dir = "book" + +[output.html] +git-repository-url = "https://github.com/tensor4all/quanticsgrids-rs" +edit-url-template = "https://github.com/tensor4all/quanticsgrids-rs/edit/main/{path}" +site-url = "/quanticsgrids-rs/" +mathjax-support = true + +[output.html.playground] +copyable = true +editable = false +runnable = false +line-numbers = false diff --git a/docs/examples/discretized-grid-1d-endpoint.rs b/docs/examples/discretized-grid-1d-endpoint.rs new file mode 100644 index 0000000..ccc11c2 --- /dev/null +++ b/docs/examples/discretized-grid-1d-endpoint.rs @@ -0,0 +1,14 @@ +use quanticsgrids::DiscretizedGrid; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let grid = DiscretizedGrid::builder(&[r]) + .with_bounds(0.0, 1.0) + .include_endpoint(true) + .build()?; + + assert!((grid.grididx_to_origcoord(&[1])?[0] - 0.0).abs() < 1e-12); + assert!((grid.grididx_to_origcoord(&[2_i64.pow(r as u32)])?[0] - 1.0).abs() < 1e-12); + + Ok(()) +} diff --git a/docs/examples/discretized-grid-1d.rs b/docs/examples/discretized-grid-1d.rs new file mode 100644 index 0000000..0e57676 --- /dev/null +++ b/docs/examples/discretized-grid-1d.rs @@ -0,0 +1,29 @@ +use quanticsgrids::DiscretizedGrid; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let grid = DiscretizedGrid::builder(&[r]) + .with_bounds(0.0, 1.0) + .build()?; + + let quantics = vec![1; r]; + let grididx = vec![1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert!((grid.grididx_to_origcoord(&grididx)?[0] - 0.0).abs() < 1e-12); + assert_eq!(grid.origcoord_to_grididx(&[0.0])?, grididx); + + let quantics = vec![2; r]; + let grididx = vec![2_i64.pow(r as u32)]; + let x = 1.0 - 1.0 / 2.0_f64.powi(r as i32); + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert!((grid.quantics_to_origcoord(&quantics)?[0] - x).abs() < 1e-12); + assert!((grid.grididx_to_origcoord(&grididx)?[0] - x).abs() < 1e-12); + assert_eq!(grid.origcoord_to_grididx(&[x])?, grididx); + assert_eq!(grid.origcoord_to_quantics(&[x])?, quantics); + + Ok(()) +} diff --git a/docs/examples/discretized-grid-3d-fused.rs b/docs/examples/discretized-grid-3d-fused.rs new file mode 100644 index 0000000..af8fad9 --- /dev/null +++ b/docs/examples/discretized-grid-3d-fused.rs @@ -0,0 +1,30 @@ +use quanticsgrids::{DiscretizedGrid, UnfoldingScheme}; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let grid = DiscretizedGrid::builder(&[r, r, r]) + .with_lower_bound(&[0.0, 0.0, 0.0]) + .with_upper_bound(&[1.0, 1.0, 1.0]) + .with_unfolding_scheme(UnfoldingScheme::Fused) + .build()?; + + let quantics = vec![1; r]; + let grididx = vec![1, 1, 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert_eq!(grid.origcoord_to_grididx(&[0.0, 0.0, 0.0])?, grididx); + + let quantics = vec![1, 1, 1, 2]; + let grididx = vec![2, 1, 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + + let coord = grid.quantics_to_origcoord(&quantics)?; + assert!((coord[0] - 1.0 / 16.0).abs() < 1e-12); + assert!((coord[1] - 0.0).abs() < 1e-12); + assert!((coord[2] - 0.0).abs() < 1e-12); + + Ok(()) +} diff --git a/docs/examples/discretized-grid-3d-interleaved.rs b/docs/examples/discretized-grid-3d-interleaved.rs new file mode 100644 index 0000000..fa9652a --- /dev/null +++ b/docs/examples/discretized-grid-3d-interleaved.rs @@ -0,0 +1,30 @@ +use quanticsgrids::{DiscretizedGrid, UnfoldingScheme}; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let grid = DiscretizedGrid::builder(&[r, r, r]) + .with_lower_bound(&[0.0, 0.0, 0.0]) + .with_upper_bound(&[1.0, 1.0, 1.0]) + .with_unfolding_scheme(UnfoldingScheme::Interleaved) + .build()?; + + let quantics = vec![1; 3 * r]; + let grididx = vec![1, 1, 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert_eq!(grid.origcoord_to_grididx(&[0.0, 0.0, 0.0])?, grididx); + + let quantics = vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1]; + let grididx = vec![2, 1, 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + + let coord = grid.quantics_to_origcoord(&quantics)?; + assert!((coord[0] - 1.0 / 16.0).abs() < 1e-12); + assert!((coord[1] - 0.0).abs() < 1e-12); + assert!((coord[2] - 0.0).abs() < 1e-12); + + Ok(()) +} diff --git a/docs/examples/inherent-discrete-grid.rs b/docs/examples/inherent-discrete-grid.rs new file mode 100644 index 0000000..18a6e63 --- /dev/null +++ b/docs/examples/inherent-discrete-grid.rs @@ -0,0 +1,31 @@ +use quanticsgrids::InherentDiscreteGrid; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let grid = InherentDiscreteGrid::builder(&[r]) + .with_origin(&[0]) + .with_step(&[1]) + .build()?; + + let quantics = vec![1; r]; + let grididx = vec![1]; + let origcoord = vec![0]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert_eq!(grid.grididx_to_origcoord(&grididx)?, origcoord); + assert_eq!(grid.origcoord_to_grididx(&origcoord)?, grididx); + assert_eq!(grid.origcoord_to_quantics(&origcoord)?, quantics); + + let quantics = vec![2; r]; + let grididx = vec![2_i64.pow(r as u32)]; + let origcoord = vec![2_i64.pow(r as u32) - 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert_eq!(grid.grididx_to_origcoord(&grididx)?, origcoord); + assert_eq!(grid.origcoord_to_grididx(&origcoord)?, grididx); + assert_eq!(grid.origcoord_to_quantics(&origcoord)?, quantics); + + Ok(()) +} diff --git a/docs/examples/non-binary-base.rs b/docs/examples/non-binary-base.rs new file mode 100644 index 0000000..82b18e9 --- /dev/null +++ b/docs/examples/non-binary-base.rs @@ -0,0 +1,23 @@ +use quanticsgrids::InherentDiscreteGrid; + +fn main() -> quanticsgrids::Result<()> { + let r = 4; + let base = 10; + let grid = InherentDiscreteGrid::builder(&[r]) + .with_origin(&[0]) + .with_step(&[1]) + .with_base(base) + .build()?; + + let quantics = vec![base as i64; r]; + let grididx = vec![(base as i64).pow(r as u32)]; + let origcoord = vec![(base as i64).pow(r as u32) - 1]; + + assert_eq!(grid.quantics_to_grididx(&quantics)?, grididx); + assert_eq!(grid.grididx_to_quantics(&grididx)?, quantics); + assert_eq!(grid.grididx_to_origcoord(&grididx)?, origcoord); + assert_eq!(grid.origcoord_to_grididx(&origcoord)?, grididx); + assert_eq!(grid.origcoord_to_quantics(&origcoord)?, quantics); + + Ok(()) +} diff --git a/docs/examples/quantics-function.rs b/docs/examples/quantics-function.rs new file mode 100644 index 0000000..9fc9b10 --- /dev/null +++ b/docs/examples/quantics-function.rs @@ -0,0 +1,16 @@ +use quanticsgrids::{DiscretizedGrid, quantics_function}; + +fn main() -> quanticsgrids::Result<()> { + let grid = DiscretizedGrid::builder(&[4, 4]).build()?; + + let f = |coords: &[f64]| coords[0].sin() + coords[1]; + let fq = quantics_function(&grid, f); + + let quantics = grid.origcoord_to_quantics(&[0.0, 0.5])?; + let coords = grid.quantics_to_origcoord(&quantics)?; + let value = fq(&quantics)?; + + assert!((value - (coords[0].sin() + coords[1])).abs() < 1e-12); + + Ok(()) +} diff --git a/docs/plans/2026-03-26-rust-user-guide-design.md b/docs/plans/2026-03-26-rust-user-guide-design.md new file mode 100644 index 0000000..f930673 --- /dev/null +++ b/docs/plans/2026-03-26-rust-user-guide-design.md @@ -0,0 +1,110 @@ +# Rust User Guide Design + +## Goal + +Add a Rust user guide that covers the same topics as the Julia documentation for +`QuanticsGrids.jl`, with executable examples and GitHub Pages publishing. + +## Constraints + +- The Rust crate is not yet published on crates.io. +- The guide must cover the same content as `../QuanticsGrids.jl/docs/src/index.md`. +- Example code should be executable and checked automatically. +- The guide should be published via GitHub Pages. + +## Decisions + +### Documentation Technology + +Use `mdBook` for the user guide. + +Rationale: + +- It supports multi-page narrative documentation cleanly. +- It fits GitHub Pages deployment well. +- `mdbook test` can validate Rust code examples. +- It is better suited than `rustdoc` alone for a Julia-style user guide. + +### Coverage + +The Rust guide will cover the same content areas as the Julia guide: + +1. Installation +2. Definition +3. Usage overview +4. Discretized grid +5. Creating a one-dimensional grid +6. Creating a d-dimensional grid +7. Inherent discrete grid +8. Using a base other than 2 +9. Creating a function that takes a quantics index as input + +The wording and examples will be adapted to the Rust API and idioms rather than +ported line-for-line from Julia syntax. + +### Executable Examples + +Primary examples in the guide will be written so they can be checked with +`mdbook test`. + +Guidelines: + +- Each code block should be self-contained. +- Each example should import the required crate items explicitly. +- Examples returning `Result` should use `fn main() -> quanticsgrids::Result<()>`. +- Floating-point examples should use tolerance-based assertions. + +`cargo test --doc` will remain in place for API docs, but the user guide will be +validated separately through `mdbook test`. + +### Repository Layout + +Add: + +- `book.toml` +- `docs/src/SUMMARY.md` +- `docs/src/index.md` +- `docs/src/installation.md` +- `docs/src/definition.md` +- `docs/src/discretized-grid.md` +- `docs/src/inherent-discrete-grid.md` +- `docs/src/non-binary-base.md` +- `docs/src/quantics-function.md` + +Adjust: + +- `README.md` to point to the GitHub Pages guide +- CI workflows to build and test the guide + +### Installation Instructions + +Because the crate is not yet published, installation examples will use the Git +dependency form: + +```toml +[dependencies] +quanticsgrids = { git = "https://github.com/tensor4all/quanticsgrids-rs" } +``` + +Optionally mention: + +```bash +cargo add quanticsgrids --git https://github.com/tensor4all/quanticsgrids-rs +``` + +### Publishing + +Publish the generated `mdBook` site to GitHub Pages through a dedicated GitHub +Actions workflow. + +CI should separately verify: + +- `mdbook build` +- `mdbook test` + +## Open Notes + +- `Cargo.lock` should be removed from version control because this repository is + a library crate. +- Existing license updates should be retained and finished alongside the docs + work. diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 0000000..36b17ff --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,9 @@ +# Summary + +- [Home](index.md) +- [Installation](installation.md) +- [Definition](definition.md) +- [Discretized Grid](discretized-grid.md) +- [Inherent Discrete Grid](inherent-discrete-grid.md) +- [Use a Base Other Than 2](non-binary-base.md) +- [Quantics Function](quantics-function.md) diff --git a/docs/src/definition.md b/docs/src/definition.md new file mode 100644 index 0000000..a7c3f78 --- /dev/null +++ b/docs/src/definition.md @@ -0,0 +1,54 @@ +# Definition + +We first introduce a base-`B` representation with `B = 2, 3, 4, ...`. +Throughout this guide, quantics digits and grid indices are 1-based. + +We represent a positive integer `X >= 1` as + +$$ +X = \sum_{i=1}^{R} (x_i - 1) B^{R-i} + 1, +$$ + +where each digit `x_i` satisfies `1 <= x_i <= B` and `R` is the number of +digits. In this crate, the base-`B` representation of `X` is stored as the +vector + +$$ +[x_1, \ldots, x_R]. +$$ + +For multiple variables, the crate supports fused and interleaved unfolding +schemes. For three variables `X`, `Y`, and `Z`, suppose their base-`B` +representations are + +$$ +[x_1, \ldots, x_R], \quad [y_1, \ldots, y_R], \quad [z_1, \ldots, z_R]. +$$ + +The interleaved representation is + +$$ +[x_1, y_1, z_1, x_2, y_2, z_2, \ldots, x_R, y_R, z_R]. +$$ + +The fused representation is + +$$ +[\alpha_1, \alpha_2, \ldots, \alpha_R], +$$ + +where + +$$ +\alpha_i = (x_i - 1) + B (y_i - 1) + B^2 (z_i - 1) + 1 +$$ + +and therefore + +$$ +1 \le \alpha_i \le B^3. +$$ + +In fused ordering, the `x` digit runs fastest at each digit level. This matches +the convention used by the Julia package and generalizes to any number of +variables. diff --git a/docs/src/discretized-grid.md b/docs/src/discretized-grid.md new file mode 100644 index 0000000..a6d93bb --- /dev/null +++ b/docs/src/discretized-grid.md @@ -0,0 +1,45 @@ +# Discretized Grid + +`DiscretizedGrid` discretizes a continuous `d`-dimensional domain and supports +conversions between: + +- quantics indices +- grid indices +- original coordinates + +Unlike the Julia package, the Rust API returns an error when original +coordinates fall outside the configured domain. + +## Creating a one-dimensional grid + +We can discretize the interval `[0, 1)` with `R` bits as follows: + +```rust +{{#include ../examples/discretized-grid-1d.rs}} +``` + +The Rust builder also supports including the upper endpoint: + +```rust +{{#include ../examples/discretized-grid-1d-endpoint.rs}} +``` + +## Creating a `d`-dimensional grid + +A `d`-dimensional grid is created in the same way by supplying one resolution +per dimension. You can choose either fused or interleaved unfolding. + +### Fused representation + +```rust +{{#include ../examples/discretized-grid-3d-fused.rs}} +``` + +Incrementing the least significant fused index increments the `x` coordinate +first. + +### Interleaved representation + +```rust +{{#include ../examples/discretized-grid-3d-interleaved.rs}} +``` diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..4334d61 --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,14 @@ +# quanticsgrids user guide + +This library provides utilities for working with functions on quantics grids and +for converting between quantics indices, grid indices, and original +coordinates. + +`quanticsgrids` provides two main layers: + +1. Low-level discrete grids with integer coordinates +2. High-level discretized grids over continuous domains + +Most users will want the high-level interface built around +`DiscretizedGrid`. The following chapters mirror the Julia guide while using the +Rust API and Rust idioms. diff --git a/docs/src/inherent-discrete-grid.md b/docs/src/inherent-discrete-grid.md new file mode 100644 index 0000000..e297c76 --- /dev/null +++ b/docs/src/inherent-discrete-grid.md @@ -0,0 +1,12 @@ +# Inherent Discrete Grid + +`InherentDiscreteGrid` is the low-level grid type for discrete target spaces. It +has an interface parallel to `DiscretizedGrid`, but original coordinates are +integer-valued and are defined by an origin and a step size. + +```rust +{{#include ../examples/inherent-discrete-grid.rs}} +``` + +As with `DiscretizedGrid`, the Rust API returns an error when original +coordinates fall outside the representable range. diff --git a/docs/src/installation.md b/docs/src/installation.md new file mode 100644 index 0000000..043897f --- /dev/null +++ b/docs/src/installation.md @@ -0,0 +1,17 @@ +# Installation + +This crate is not yet published on crates.io. For now, depend on the GitHub +repository directly. + +Add this to `Cargo.toml`: + +```toml +[dependencies] +quanticsgrids = { git = "https://github.com/tensor4all/quanticsgrids-rs" } +``` + +Or use `cargo add`: + +```bash +cargo add quanticsgrids --git https://github.com/tensor4all/quanticsgrids-rs +``` diff --git a/docs/src/non-binary-base.md b/docs/src/non-binary-base.md new file mode 100644 index 0000000..1b35802 --- /dev/null +++ b/docs/src/non-binary-base.md @@ -0,0 +1,8 @@ +# Use a Base Other Than 2 + +You can choose a base other than `2` when building a grid. The example below +uses base `10`. + +```rust +{{#include ../examples/non-binary-base.rs}} +``` diff --git a/docs/src/quantics-function.md b/docs/src/quantics-function.md new file mode 100644 index 0000000..4a037f3 --- /dev/null +++ b/docs/src/quantics-function.md @@ -0,0 +1,11 @@ +# Quantics Function + +When working with algorithms that expect a function of quantics indices, you can +wrap a coordinate-space function with `quantics_function`. + +```rust +{{#include ../examples/quantics-function.rs}} +``` + +This is the Rust equivalent of first defining a function in the original +coordinate space and then obtaining a quantics-index wrapper around it. diff --git a/scripts/test-book-examples.sh b/scripts/test-book-examples.sh new file mode 100755 index 0000000..5db63d0 --- /dev/null +++ b/scripts/test-book-examples.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$repo_root" + +examples_dir="docs/examples" +output_dir="target/book-examples" + +cargo build +mkdir -p "$output_dir" + +for src in "$examples_dir"/*.rs; do + name="$(basename "$src" .rs)" + rustc \ + --edition=2021 \ + --extern "quanticsgrids=target/debug/libquanticsgrids.rlib" \ + -L dependency=target/debug/deps \ + "$src" \ + -o "$output_dir/$name" + "$output_dir/$name" +done