diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml index 08f664c..4c49a86 100644 --- a/.JuliaFormatter.toml +++ b/.JuliaFormatter.toml @@ -1,2 +1,3 @@ +# See https://domluna.github.io/JuliaFormatter.jl/stable/ for a list of options style = "blue" indent = 2 diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..2c4bd9d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,62 @@ +--- +name: SymmetrySectors.jl bug report +about: Create a bug report to help us improve SymmetrySectors.jl +title: "[BUG] YOUR SHORT DESCRIPTION OF THE BUG HERE" +labels: ["bug"] +assignees: '' + +--- + +**Description of bug** + +Please give a brief description of the bug or unexpected behavior here. + +**Minimal code demonstrating the bug or unexpected behavior** + +If applicable, provide a minimal code that can be run to demonstrate the bug or unexpected behavior. + +If you are unable to construct a minimal code that demonstrates the bug or unexpected behavior, provide detailed steps for how to reproduce the behavior you are seeing. + +
Minimal runnable code

+ +```julia +[YOUR MINIMAL RUNNABLE CODE HERE] +``` + +

+ + +**Expected output or behavior** + +Describe what you expected to happen. + +If you provided a minimal code that can be run to demonstrate the bug or unexpected behavior, describe what you expected the output would be. + + +**Actual output or behavior** + +Describe what actually happened. + +If you provided a minimal code that demonstrates the bug or unexpected behavior, provide the output you get from that code. If the code leads to an error or warning, include the full error or warning below. + +
Output of minimal runnable code

+ +```julia +[OUTPUT OF YOUR MINIMAL RUNNABLE CODE HERE] +``` + +

+ + +**Version information** + + - Output from `versioninfo()`: +```julia +julia> versioninfo() +[YOUR OUTPUT HERE] +``` + - Output from `using Pkg; Pkg.status("SymmetrySectors")`: +```julia +julia> using Pkg; Pkg.status("SymmetrySectors") +[YOUR OUTPUT HERE] +``` diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..13f9138 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,24 @@ +--- +name: SymmetrySectors.jl feature request +about: Suggest an idea for SymmetrySectors.jl +title: "[ENHANCEMENT] YOUR SHORT DESCRIPTION OF THE FEATURE REQUEST HERE" +labels: ["enhancement"] +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..58e6963 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,42 @@ +# Description + +Please include a summary of the change and which issue is fixed (if applicable). Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes #(issue) + +If practical and applicable, please include a minimal demonstration of the previous behavior and new behavior below. + +
Minimal demonstration of previous behavior

+ +```julia +[YOUR MINIMAL DEMONSTRATION OF PREVIOUS BEHAVIOR] +``` + +

+ +
Minimal demonstration of new behavior

+ +```julia +[YOUR MINIMAL DEMONSTRATION OF NEW BEHAVIOR] +``` + +

+ +# How Has This Been Tested? + +Please add tests that verify your changes to a file in the `test` directory. + +Please give a summary of the tests that you added to verify your changes. + +- [ ] Test A +- [ ] Test B + +# Checklist: + +- [ ] My code follows the style guidelines of this project. Please run `using JuliaFormatter; format(".")` in the base directory of the repository (`~/.julia/dev/SymmetrySectors`) to format your code according to our style guidelines. +- [ ] I have performed a self-review of my own code. +- [ ] I have commented my code, particularly in hard-to-understand areas. +- [ ] I have added tests that verify the behavior of the changes I made. +- [ ] I have made corresponding changes to the documentation. +- [ ] My changes generate no new warnings. +- [ ] Any dependent changes have been merged and published in downstream modules. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..21df312 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,79 @@ +name: CI +on: + push: + branches: + - main + tags: ['*'] + pull_request: + workflow_dispatch: +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 }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + strategy: + fail-fast: false + matrix: + version: + # - 'lts' # TODO: Reenable once dependencie are registered. + - '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@v2 + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v5 + with: + files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + docs: + name: Documentation + runs-on: ubuntu-latest + permissions: + actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created + contents: write + statuses: write + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - uses: julia-actions/cache@v2 + - name: Configure doc environment + shell: julia --project=docs --color=yes {0} + run: | + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-docdeploy@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + - name: Run doctests + shell: julia --project=docs --color=yes {0} + run: | + using Documenter: DocMeta, doctest + using SymmetrySectors + DocMeta.setdocmeta!(SymmetrySectors, :DocTestSetup, :(using SymmetrySectors); recursive=true) + doctest(SymmetrySectors) diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 0000000..cba9134 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/FormatCheck.yml b/.github/workflows/FormatCheck.yml new file mode 100644 index 0000000..bb6d933 --- /dev/null +++ b/.github/workflows/FormatCheck.yml @@ -0,0 +1,35 @@ +name: Format check +on: + push: + branches: [main] + tags: [v*] + pull_request: + +jobs: + format: + name: "Format Check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: 1 + - name: Install JuliaFormatter and format + run: | + julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))' + julia -e 'using JuliaFormatter; format(".", verbose=true)' + - name: Check format + run: | + julia -e ' + out = Cmd(`git diff --name-only`) |> read |> String + if out == "" + exit(0) + else + @error "The following files have not been formatted:" + write(stdout, out) + out_diff = Cmd(`git diff`) |> read |> String + @error "Diff:" + write(stdout, out_diff) + exit(1) + @error "" + end' diff --git a/.github/workflows/LiterateCheck.yml b/.github/workflows/LiterateCheck.yml new file mode 100644 index 0000000..1ce06c4 --- /dev/null +++ b/.github/workflows/LiterateCheck.yml @@ -0,0 +1,42 @@ +name: Literate check +on: + push: + branches: [main] + tags: [v*] + pull_request: + +jobs: + literate: + name: "Literate Check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: 1 + - name: Install Literate and generate docs + run: | + julia -e ' + using Pkg + # TODO: Delete once they are registered. + Pkg.add(url="https://github.com/ITensor/LabelledNumbers.jl") + Pkg.add(url="https://github.com/ITensor/GradedUnitRanges.jl") + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + Pkg.add(PackageSpec(name="Literate"))' + julia -e 'include("docs/make_readme.jl")' + - name: Check if docs need to be updated + run: | + julia -e ' + out = Cmd(`git diff --name-only`) |> read |> String + if out == "" + exit(0) + else + @error "The docs are outdated, rerun Literate to regenerate them." + write(stdout, out) + out_diff = Cmd(`git diff`) |> read |> String + @error "Diff:" + write(stdout, out_diff) + exit(1) + @error "" + end' diff --git a/.github/workflows/Register.yml b/.github/workflows/Register.yml new file mode 100644 index 0000000..5b7cd3b --- /dev/null +++ b/.github/workflows/Register.yml @@ -0,0 +1,16 @@ +name: Register Package +on: + workflow_dispatch: + inputs: + version: + description: Version to register or component to bump + required: true +jobs: + register: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: julia-actions/RegisterAction@latest + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..0cd3114 --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,31 @@ +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 }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10593a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.jl.*.cov +*.jl.cov +*.jl.mem +*.o +*.swp +.DS_Store +.benchmarkci +.tmp +.vscode/ +Manifest.toml +benchmark/*.json +docs/Manifest.toml +docs/build/ +docs/src/index.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..bff1fb7 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-merge-conflict + - id: check-toml + - id: check-yaml + - id: end-of-file-fixer + exclude_types: [markdown] # incompatible with Literate.jl +- repo: https://github.com/qiaojunfeng/pre-commit-julia-format + rev: v0.2.0 + hooks: + - id: julia-format diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7f5c8c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ITensor developers + +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/Project.toml b/Project.toml index e69de29..9c09fbd 100644 --- a/Project.toml +++ b/Project.toml @@ -0,0 +1,30 @@ +name = "SymmetrySectors" +uuid = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" +authors = ["ITensor developers and contributors"] +version = "0.1.0" + +[deps] +BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" +GradedUnitRanges = "e2de450a-8a67-46c7-b59c-01d5a3d041c5" +HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721" +LabelledNumbers = "f856a3a6-4152-4ec4-b2a7-02c1a55d7993" + +[sources] +GradedUnitRanges = {url = "https://github.com/ITensor/GradedUnitRanges.jl"} +LabelledNumbers = {url = "https://github.com/ITensor/LabelledNumbers.jl"} + +[compat] +Aqua = "0.8.9" +BlockArrays = "1.2.0" +GradedUnitRanges = "0.1.0" +HalfIntegers = "1.6.0" +LabelledNumbers = "0.1.0" +Test = "1.10" +julia = "1.10" + +[extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Aqua", "Test"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a31fda --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# SymmetrySectors.jl + +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://ITensor.github.io/SymmetrySectors.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://ITensor.github.io/SymmetrySectors.jl/dev/) +[![Build Status](https://github.com/ITensor/SymmetrySectors.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ITensor/SymmetrySectors.jl/actions/workflows/CI.yml?query=branch%3Amain) +[![Coverage](https://codecov.io/gh/ITensor/SymmetrySectors.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/SymmetrySectors.jl) +[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) +[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) + +## Installation instructions + +```julia +julia> using Pkg: Pkg + +julia> Pkg.add("https://github.com/ITensor/SymmetrySectors.jl") +``` + +## Examples + +````julia +using SymmetrySectors: SymmetrySectors +```` + +Examples go here. + +--- + +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* + diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl new file mode 100644 index 0000000..da81828 --- /dev/null +++ b/benchmark/benchmarks.jl @@ -0,0 +1,7 @@ +using SymmetrySectors +using BenchmarkTools + +SUITE = BenchmarkGroup() +SUITE["rand"] = @benchmarkable rand(10) + +# Write your benchmarks here. diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..cd1fab4 --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,10 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +GradedUnitRanges = "e2de450a-8a67-46c7-b59c-01d5a3d041c5" +LabelledNumbers = "f856a3a6-4152-4ec4-b2a7-02c1a55d7993" +Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +SymmetrySectors = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" + +[sources] +GradedUnitRanges = {url = "https://github.com/ITensor/GradedUnitRanges.jl"} +LabelledNumbers = {url = "https://github.com/ITensor/LabelledNumbers.jl"} diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..70aa7ae --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,24 @@ +using SymmetrySectors: SymmetrySectors +using Documenter: Documenter, DocMeta, deploydocs, makedocs + +DocMeta.setdocmeta!( + SymmetrySectors, :DocTestSetup, :(using SymmetrySectors); recursive=true +) + +include("make_index.jl") + +makedocs(; + modules=[SymmetrySectors], + authors="ITensor developers and contributors", + sitename="SymmetrySectors.jl", + format=Documenter.HTML(; + canonical="https://ITensor.github.io/SymmetrySectors.jl", + edit_link="main", + assets=String[], + ), + pages=["Home" => "index.md"], +) + +deploydocs(; + repo="github.com/ITensor/SymmetrySectors.jl", devbranch="main", push_preview=true +) diff --git a/docs/make_index.jl b/docs/make_index.jl new file mode 100644 index 0000000..c4b4818 --- /dev/null +++ b/docs/make_index.jl @@ -0,0 +1,9 @@ +using Literate: Literate +using SymmetrySectors: SymmetrySectors + +Literate.markdown( + joinpath(pkgdir(SymmetrySectors), "examples", "README.jl"), + joinpath(pkgdir(SymmetrySectors), "docs", "src"); + flavor=Literate.DocumenterFlavor(), + name="index", +) diff --git a/docs/make_readme.jl b/docs/make_readme.jl new file mode 100644 index 0000000..e58f867 --- /dev/null +++ b/docs/make_readme.jl @@ -0,0 +1,9 @@ +using Literate: Literate +using SymmetrySectors: SymmetrySectors + +Literate.markdown( + joinpath(pkgdir(SymmetrySectors), "examples", "README.jl"), + joinpath(pkgdir(SymmetrySectors)); + flavor=Literate.CommonMarkFlavor(), + name="README", +) diff --git a/examples/Project.toml b/examples/Project.toml new file mode 100644 index 0000000..d0c76ae --- /dev/null +++ b/examples/Project.toml @@ -0,0 +1,9 @@ +[deps] +GradedUnitRanges = "e2de450a-8a67-46c7-b59c-01d5a3d041c5" +LabelledNumbers = "f856a3a6-4152-4ec4-b2a7-02c1a55d7993" +SymmetrySectors = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" + +[sources] +GradedUnitRanges = {url = "https://github.com/ITensor/GradedUnitRanges.jl"} +LabelledNumbers = {url = "https://github.com/ITensor/LabelledNumbers.jl"} + diff --git a/examples/README.jl b/examples/README.jl new file mode 100644 index 0000000..87ac9c6 --- /dev/null +++ b/examples/README.jl @@ -0,0 +1,23 @@ +# # SymmetrySectors.jl +# +# [![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://ITensor.github.io/SymmetrySectors.jl/stable/) +# [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://ITensor.github.io/SymmetrySectors.jl/dev/) +# [![Build Status](https://github.com/ITensor/SymmetrySectors.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ITensor/SymmetrySectors.jl/actions/workflows/CI.yml?query=branch%3Amain) +# [![Coverage](https://codecov.io/gh/ITensor/SymmetrySectors.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/SymmetrySectors.jl) +# [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) +# [![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) + +# ## Installation instructions + +#= +```julia +julia> using Pkg: Pkg + +julia> Pkg.add("https://github.com/ITensor/SymmetrySectors.jl") +``` +=# + +# ## Examples + +using SymmetrySectors: SymmetrySectors +# Examples go here. diff --git a/src/abstractsector.jl b/src/abstractsector.jl index 2257e9f..b2a773f 100644 --- a/src/abstractsector.jl +++ b/src/abstractsector.jl @@ -2,8 +2,9 @@ # all fusion categories (Z{2}, SU2, Ising...) are subtypes of AbstractSector using BlockArrays: blocklengths -using ..LabelledNumbers: LabelledInteger, label, label_type, labelled, unlabel, unlabel_type -using ..GradedAxes: GradedAxes, blocklabels, fuse_blocklengths, gradedrange, tensor_product +using LabelledNumbers: LabelledInteger, label, label_type, labelled, unlabel, unlabel_type +using GradedUnitRanges: + GradedUnitRanges, blocklabels, fuse_blocklengths, gradedrange, tensor_product abstract type AbstractSector end @@ -67,16 +68,16 @@ function label_fusion_rule(sector_type::Type{<:AbstractSector}, l1, l2) return [abelian_label_fusion_rule(sector_type, l1, l2) => 1] end -# ================================ GradedAxes interface ================================== +# ================================ GradedUnitRanges interface ================================== # tensor_product interface -function GradedAxes.fuse_blocklengths( +function GradedUnitRanges.fuse_blocklengths( l1::LabelledInteger{<:Integer,<:AbstractSector}, l2::LabelledInteger{<:Integer,<:AbstractSector}, ) return fuse_blocklengths(combine_styles(SymmetryStyle(l1), SymmetryStyle(l2)), l1, l2) end -function GradedAxes.fuse_blocklengths( +function GradedUnitRanges.fuse_blocklengths( ::NotAbelianStyle, l1::LabelledInteger, l2::LabelledInteger ) fused = label(l1) ⊗ label(l2) @@ -84,7 +85,7 @@ function GradedAxes.fuse_blocklengths( return gradedrange(v) end -function GradedAxes.fuse_blocklengths( +function GradedUnitRanges.fuse_blocklengths( ::AbelianStyle, l1::LabelledInteger, l2::LabelledInteger ) fused = label(l1) ⊗ label(l2) @@ -97,18 +98,18 @@ to_gradedrange(l::LabelledInteger) = gradedrange([l]) to_gradedrange(g::AbstractUnitRange) = g # allow to fuse a Sector with a GradedUnitRange -function GradedAxes.tensor_product(c::AbstractSector, g::AbstractUnitRange) +function GradedUnitRanges.tensor_product(c::AbstractSector, g::AbstractUnitRange) return tensor_product(to_gradedrange(c), g) end -function GradedAxes.tensor_product(g::AbstractUnitRange, c::AbstractSector) +function GradedUnitRanges.tensor_product(g::AbstractUnitRange, c::AbstractSector) return tensor_product(g, to_gradedrange(c)) end -function GradedAxes.tensor_product(c1::AbstractSector, c2::AbstractSector) +function GradedUnitRanges.tensor_product(c1::AbstractSector, c2::AbstractSector) return to_gradedrange(fusion_rule(c1, c2)) end -function GradedAxes.fusion_product(c::AbstractSector) +function GradedUnitRanges.fusion_product(c::AbstractSector) return to_gradedrange(c) end diff --git a/src/sector_definitions/fib.jl b/src/sector_definitions/fib.jl index d7fded5..bc90174 100644 --- a/src/sector_definitions/fib.jl +++ b/src/sector_definitions/fib.jl @@ -3,7 +3,7 @@ # # (same fusion rules as subcategory {0,1} of su2{3}) # -using ..GradedAxes: GradedAxes +using ..GradedUnitRanges: GradedUnitRanges struct Fib <: AbstractSector l::Int @@ -21,7 +21,7 @@ end SymmetryStyle(::Type{Fib}) = NotAbelianStyle() -GradedAxes.dual(f::Fib) = f +GradedUnitRanges.dual(f::Fib) = f sector_label(f::Fib) = f.l diff --git a/src/sector_definitions/ising.jl b/src/sector_definitions/ising.jl index d4a9550..e8b79c6 100644 --- a/src/sector_definitions/ising.jl +++ b/src/sector_definitions/ising.jl @@ -5,7 +5,7 @@ # using HalfIntegers: Half, twice -using ..GradedAxes: GradedAxes +using ..GradedUnitRanges: GradedUnitRanges struct Ising <: AbstractSector l::Half{Int} @@ -21,7 +21,7 @@ end SymmetryStyle(::Type{Ising}) = NotAbelianStyle() -GradedAxes.dual(i::Ising) = i +GradedUnitRanges.dual(i::Ising) = i sector_label(i::Ising) = i.l diff --git a/src/sector_definitions/o2.jl b/src/sector_definitions/o2.jl index 4a0dcf7..34e12a2 100644 --- a/src/sector_definitions/o2.jl +++ b/src/sector_definitions/o2.jl @@ -10,7 +10,7 @@ # using HalfIntegers: Half, HalfInteger -using ..GradedAxes: GradedAxes +using ..GradedUnitRanges: GradedUnitRanges # here we use only one half-integer as label: # - l=0 for trivial @@ -36,7 +36,7 @@ iszero_odd(l::HalfInteger) = l == sector_label(zero_odd(O2)) quantum_dimension(::NotAbelianStyle, s::O2) = 2 - is_zero_even_or_odd(s) -GradedAxes.dual(s::O2) = s +GradedUnitRanges.dual(s::O2) = s function Base.show(io::IO, s::O2) if iszero_odd(s) diff --git a/src/sector_definitions/su.jl b/src/sector_definitions/su.jl index b44ef4d..83d95b4 100644 --- a/src/sector_definitions/su.jl +++ b/src/sector_definitions/su.jl @@ -3,7 +3,7 @@ # using HalfIntegers: HalfInteger, half, twice -using ...GradedAxes: GradedAxes +using ...GradedUnitRanges: GradedUnitRanges struct SU{N,M} <: AbstractSector # l is the first row of the @@ -43,7 +43,7 @@ function quantum_dimension(::NotAbelianStyle, s::SU) return Int(d) end -function GradedAxes.dual(s::SU) +function GradedUnitRanges.dual(s::SU) l = sector_label(s) nl = reverse(cumsum((l[begin:(end - 1)] .- l[(begin + 1):end]..., l[end]))) return typeof(s)(nl) @@ -87,7 +87,7 @@ end # optimize implementation quantum_dimension(s::SU{2}) = sector_label(s)[1] + 1 -GradedAxes.dual(s::SU{2}) = s +GradedUnitRanges.dual(s::SU{2}) = s function label_fusion_rule(::Type{<:SU{2}}, s1, s2) irreps = [SU{2}((i,)) for i in (abs(s1[1] - s2[1])):2:(s1[1] + s2[1])] diff --git a/src/sector_definitions/su2k.jl b/src/sector_definitions/su2k.jl index cdf9bfb..3e10ef5 100644 --- a/src/sector_definitions/su2k.jl +++ b/src/sector_definitions/su2k.jl @@ -3,7 +3,7 @@ # using HalfIntegers: Half -using ...GradedAxes: GradedAxes +using ...GradedUnitRanges: GradedUnitRanges struct su2{k} <: AbstractSector j::Half{Int} @@ -11,7 +11,7 @@ end SymmetryStyle(::Type{<:su2}) = NotAbelianStyle() -GradedAxes.dual(s::su2) = s +GradedUnitRanges.dual(s::su2) = s sector_label(s::su2) = s.j diff --git a/src/sector_definitions/trivial.jl b/src/sector_definitions/trivial.jl index 27b3fec..78af09d 100644 --- a/src/sector_definitions/trivial.jl +++ b/src/sector_definitions/trivial.jl @@ -3,7 +3,7 @@ # acts as a trivial sector for any AbstractSector # -using ...GradedAxes: GradedAxes +using ...GradedUnitRanges: GradedUnitRanges # Trivial is special as it does not have a label struct TrivialSector <: AbstractSector end @@ -12,7 +12,7 @@ SymmetryStyle(::Type{TrivialSector}) = AbelianStyle() trivial(::Type{TrivialSector}) = TrivialSector() -GradedAxes.dual(::TrivialSector) = TrivialSector() +GradedUnitRanges.dual(::TrivialSector) = TrivialSector() # TrivialSector acts as trivial on any AbstractSector function fusion_rule(::NotAbelianStyle, ::TrivialSector, c::AbstractSector) @@ -21,6 +21,10 @@ end function fusion_rule(::NotAbelianStyle, c::AbstractSector, ::TrivialSector) return to_gradedrange(c) end +# Fix ambiguity error. +function fusion_rule(::NotAbelianStyle, c::TrivialSector, ::TrivialSector) + return to_gradedrange(TrivialSector()) +end # abelian case: return Sector fusion_rule(::AbelianStyle, c::AbstractSector, ::TrivialSector) = c diff --git a/src/sector_definitions/u1.jl b/src/sector_definitions/u1.jl index 2d79796..5e030e4 100644 --- a/src/sector_definitions/u1.jl +++ b/src/sector_definitions/u1.jl @@ -2,7 +2,7 @@ # U₁ group (circle group, or particle number, total Sz etc.) # -using ...GradedAxes: GradedAxes +using ...GradedUnitRanges: GradedUnitRanges # Parametric type to allow both integer label as well as # HalfInteger for easy conversion to/from SU(2) @@ -14,7 +14,7 @@ SymmetryStyle(::Type{<:U1}) = AbelianStyle() sector_label(u::U1) = u.n set_sector_label(s::U1, sector_label) = typeof(s)(sector_label) -GradedAxes.dual(s::U1) = set_sector_label(s, -sector_label(s)) +GradedUnitRanges.dual(s::U1) = set_sector_label(s, -sector_label(s)) trivial(::Type{U1}) = trivial(U1{Int}) trivial(::Type{U1{T}}) where {T} = U1(zero(T)) diff --git a/src/sector_definitions/zn.jl b/src/sector_definitions/zn.jl index 8628288..d3446a0 100644 --- a/src/sector_definitions/zn.jl +++ b/src/sector_definitions/zn.jl @@ -2,7 +2,7 @@ # Cyclic group Zₙ # -using ...GradedAxes: GradedAxes +using ...GradedUnitRanges: GradedUnitRanges struct Z{N} <: AbstractSector m::Int @@ -16,7 +16,7 @@ SymmetryStyle(::Type{<:Z}) = AbelianStyle() sector_label(c::Z) = c.m set_sector_label(s::Z, sector_label) = typeof(s)(sector_label) -GradedAxes.dual(s::Z) = set_sector_label(s, -sector_label(s)) +GradedUnitRanges.dual(s::Z) = set_sector_label(s, -sector_label(s)) trivial(sector_type::Type{<:Z}) = sector_type(0) diff --git a/src/sector_product.jl b/src/sector_product.jl index 12a72d0..32f4da8 100644 --- a/src/sector_product.jl +++ b/src/sector_product.jl @@ -2,8 +2,8 @@ # e.g. U(1)×U(1), U(1)×SU2(2)×SU(3) using BlockArrays: blocklengths -using ..LabelledNumbers: LabelledInteger, label, labelled, unlabel -using ..GradedAxes: AbstractGradedUnitRange, GradedAxes, dual +using LabelledNumbers: LabelledInteger, label, labelled, unlabel +using GradedUnitRanges: AbstractGradedUnitRange, GradedUnitRanges, dual # ===================================== Definition ======================================= struct SectorProduct{Sectors} <: AbstractSector @@ -25,7 +25,7 @@ function quantum_dimension(::NotAbelianStyle, s::SectorProduct) end # use map instead of broadcast to support both Tuple and NamedTuple -GradedAxes.dual(s::SectorProduct) = SectorProduct(map(dual, arguments(s))) +GradedUnitRanges.dual(s::SectorProduct) = SectorProduct(map(dual, arguments(s))) function trivial(type::Type{<:SectorProduct}) return SectorProduct(arguments_trivial(arguments_type(type))) @@ -122,8 +122,12 @@ end function fusion_rule(style::SymmetryStyle, c1::AbstractSector, c2::SectorProduct) return fusion_rule(style, SectorProduct(c1), c2) end +# Fix ambiguity error. +function fusion_rule(style::SymmetryStyle, c1::SectorProduct, c2::SectorProduct) + return throw(ArgumentError("SectorProduct fusion not defined for symmetry style $style.")) +end -# generic case: fusion returns a GradedAxes, even for fusion with Empty +# generic case: fusion returns a GradedUnitRanges, even for fusion with Empty function fusion_rule(::NotAbelianStyle, s1::SectorProduct, s2::SectorProduct) return to_gradedrange(arguments_fusion_rule(arguments(s1), arguments(s2))) end diff --git a/src/symmetry_style.jl b/src/symmetry_style.jl index f3e443d..74dbf1d 100644 --- a/src/symmetry_style.jl +++ b/src/symmetry_style.jl @@ -1,7 +1,7 @@ # This file defines SymmetryStyle, a trait to distinguish abelian groups, non-abelian groups # and non-group fusion categories. -using ..LabelledNumbers: LabelledInteger, label_type +using LabelledNumbers: LabelledInteger, label_type abstract type SymmetryStyle end diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..597b95f --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,5 @@ +[deps] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +GradedUnitRanges = "e2de450a-8a67-46c7-b59c-01d5a3d041c5" +SymmetrySectors = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/runtests.jl b/test/runtests.jl index 5bf73eb..eba722e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,12 +1,12 @@ @eval module $(gensym()) -using Test: @test, @testset -@testset "$(@__DIR__)" begin +using Test: @testset + +@testset "SymmetrySectors.jl" begin filenames = filter(readdir(@__DIR__)) do f startswith("test_")(f) && endswith(".jl")(f) end - @testset "Test $(@__DIR__)/$filename" for filename in filenames - println("Running $(@__DIR__)/$filename") - @time include(filename) + @testset "Test $filename" for filename in filenames + include(filename) end end end diff --git a/test/test_aqua.jl b/test/test_aqua.jl new file mode 100644 index 0000000..ccff0a8 --- /dev/null +++ b/test/test_aqua.jl @@ -0,0 +1,10 @@ +@eval module $(gensym()) +using SymmetrySectors: SymmetrySectors +using Aqua: Aqua +using Test: @testset + +@testset "Code quality (Aqua.jl)" begin + # TODO: Reenable once dependencies are registered" + # Aqua.test_all(SymmetrySectors) +end +end diff --git a/test/test_basics.jl b/test/test_basics.jl new file mode 100644 index 0000000..df6a272 --- /dev/null +++ b/test/test_basics.jl @@ -0,0 +1,8 @@ +@eval module $(gensym()) +using SymmetrySectors: SymmetrySectors +using Test: @test, @testset + +@testset "SymmetrySectors" begin + # Tests go here. +end +end diff --git a/test/test_examples.jl b/test/test_examples.jl new file mode 100644 index 0000000..1d9ba7a --- /dev/null +++ b/test/test_examples.jl @@ -0,0 +1,8 @@ +@eval module $(gensym()) +using SymmetrySectors: SymmetrySectors +using Test: @test, @testset + +@testset "examples" begin + include(joinpath(pkgdir(SymmetrySectors), "examples", "README.jl")) +end +end diff --git a/test/test_fusion_rules.jl b/test/test_fusion_rules.jl index bd00abe..600630a 100644 --- a/test/test_fusion_rules.jl +++ b/test/test_fusion_rules.jl @@ -1,7 +1,7 @@ @eval module $(gensym()) -using NDTensors.GradedAxes: +using GradedUnitRanges: dual, fusion_product, space_isequal, gradedrange, flip, tensor_product -using NDTensors.SymmetrySectors: +using SymmetrySectors: ⊗, Fib, Ising, @@ -31,7 +31,7 @@ using Test: @inferred, @test, @testset, @test_throws @test (@inferred q ⊗ z0) == z0 @test (@inferred z1 ⊗ q) == z1 - # using GradedAxes interface + # using GradedUnitRanges interface @test space_isequal(fusion_product(z0, z0), gradedrange([z0 => 1])) @test space_isequal(fusion_product(z0, z1), gradedrange([z1 => 1])) diff --git a/test/test_sector_product.jl b/test/test_sector_product.jl index de046fc..487a749 100644 --- a/test/test_sector_product.jl +++ b/test/test_sector_product.jl @@ -1,5 +1,5 @@ @eval module $(gensym()) -using NDTensors.SymmetrySectors: +using SymmetrySectors: ×, ⊗, Fib, @@ -14,7 +14,7 @@ using NDTensors.SymmetrySectors: quantum_dimension, arguments, trivial -using NDTensors.GradedAxes: dual, fusion_product, space_isequal, gradedrange +using GradedUnitRanges: dual, fusion_product, space_isequal, gradedrange using Test: @inferred, @test, @testset, @test_throws @testset "Test Ordered Products" begin diff --git a/test/test_simple_sectors.jl b/test/test_simple_sectors.jl index a2b243c..20b2c88 100644 --- a/test/test_simple_sectors.jl +++ b/test/test_simple_sectors.jl @@ -1,6 +1,6 @@ @eval module $(gensym()) -using NDTensors.GradedAxes: dual -using NDTensors.SymmetrySectors: +using GradedUnitRanges: dual +using SymmetrySectors: Fib, Ising, O2,