diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
new file mode 100644
index 0000000..47f6f79
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
@@ -0,0 +1,62 @@
+---
+name: ITensorVisualizationBase.jl bug report
+about: Create a bug report to help us improve ITensorVisualizationBase.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("ITensorVisualizationBase")`:
+```julia
+julia> using Pkg; Pkg.status("ITensorVisualizationBase")
+[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..910ff1b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
@@ -0,0 +1,24 @@
+---
+name: ITensorVisualizationBase.jl feature request
+about: Suggest an idea for ITensorVisualizationBase.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..a3c5d5b
--- /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 the [ITensorFormatter](https://github.com/ITensor/ITensorFormatter.jl) in the base directory of the repository (`~/.julia/dev/ITensorVisualizationBase`) 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
index 700707c..5ace460 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,7 +1,6 @@
-# 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
+ directory: "/"
schedule:
interval: "weekly"
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
deleted file mode 100644
index d8890e0..0000000
--- a/.github/workflows/CI.yml
+++ /dev/null
@@ -1,79 +0,0 @@
-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 }} - ${{ github.event_name }}
- 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'
- - '1'
- os:
- - ubuntu-latest
- - macOS-latest
- - windows-latest
- arch:
- - x64
- steps:
- - uses: actions/checkout@v6
- - uses: julia-actions/setup-julia@v2
- with:
- version: ${{ matrix.version }}
- arch: ${{ matrix.arch }}
- - uses: julia-actions/cache@v3
- - 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@v6
- - uses: julia-actions/setup-julia@v2
- with:
- version: '1'
- - uses: julia-actions/cache@v3
- - 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 ITensorVisualizationBase
- DocMeta.setdocmeta!(ITensorVisualizationBase, :DocTestSetup, :(using ITensorVisualizationBase); recursive=true)
- doctest(ITensorVisualizationBase)
diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml
new file mode 100644
index 0000000..c3b11ec
--- /dev/null
+++ b/.github/workflows/Documentation.yml
@@ -0,0 +1,20 @@
+name: "Documentation"
+on:
+ push:
+ branches:
+ - "main"
+ tags: "*"
+ pull_request: ~
+ schedule:
+ - cron: "1 4 * * 4"
+concurrency:
+ group: "${{ github.workflow }}-${{ github.ref }}"
+ cancel-in-progress: "${{ github.ref_name != github.event.repository.default_branch || github.ref != 'refs/tags/v*' }}"
+jobs:
+ build-and-deploy-docs:
+ name: "Documentation"
+ uses: "ITensor/ITensorActions/.github/workflows/Documentation.yml@main"
+ with:
+ localregistry: "https://github.com/ITensor/ITensorRegistry.git"
+ secrets:
+ CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
diff --git a/.github/workflows/FormatCheck.yml b/.github/workflows/FormatCheck.yml
new file mode 100644
index 0000000..3c290ea
--- /dev/null
+++ b/.github/workflows/FormatCheck.yml
@@ -0,0 +1,16 @@
+name: "Format Check"
+on:
+ pull_request_target:
+ types:
+ - "opened"
+ - "synchronize"
+ - "reopened"
+ - "ready_for_review"
+permissions:
+ contents: "read"
+ actions: "write"
+ pull-requests: "write"
+jobs:
+ format-check:
+ name: "Format Check"
+ uses: "ITensor/ITensorActions/.github/workflows/FormatCheck.yml@main"
diff --git a/.github/workflows/FormatPullRequest.yml b/.github/workflows/FormatPullRequest.yml
new file mode 100644
index 0000000..5a8b627
--- /dev/null
+++ b/.github/workflows/FormatPullRequest.yml
@@ -0,0 +1,16 @@
+name: "Format Pull Request"
+on:
+ schedule:
+ - cron: "0 0 * * *"
+ workflow_dispatch: ~
+ issue_comment:
+ types:
+ - "created"
+permissions:
+ contents: "write"
+ pull-requests: "write"
+jobs:
+ format-pull-request:
+ name: "Format Pull Request"
+ uses: "ITensor/ITensorActions/.github/workflows/FormatPullRequest.yml@main"
+ secrets: "inherit"
diff --git a/.github/workflows/IntegrationTest.yml b/.github/workflows/IntegrationTest.yml
new file mode 100644
index 0000000..3531704
--- /dev/null
+++ b/.github/workflows/IntegrationTest.yml
@@ -0,0 +1,39 @@
+name: "IntegrationTest"
+on:
+ push:
+ branches:
+ - "main"
+ tags: "*"
+ paths:
+ - "Project.toml"
+ pull_request:
+ types:
+ - "opened"
+ - "synchronize"
+ - "reopened"
+ - "ready_for_review"
+ - "converted_to_draft"
+ paths:
+ - "Project.toml"
+jobs:
+ integration-test:
+ name: "IntegrationTest"
+ strategy:
+ matrix:
+ pkg:
+ - "__none__"
+ uses: "ITensor/ITensorActions/.github/workflows/IntegrationTest.yml@main"
+ with:
+ localregistry: "https://github.com/ITensor/ITensorRegistry.git"
+ pkg: "${{ matrix.pkg }}"
+ integration-gate:
+ name: "IntegrationTest"
+ needs: "integration-test"
+ if: "${{ always() && needs.integration-test.result != 'skipped' }}"
+ runs-on: "ubuntu-latest"
+ steps:
+ - name: "Fail if any downstream integration test failed"
+ run: |
+ echo "integration-test.result = ${{ needs.integration-test.result }}"
+ test "${{ needs.integration-test.result }}" = "success"
+
diff --git a/.github/workflows/IntegrationTestRequest.yml b/.github/workflows/IntegrationTestRequest.yml
new file mode 100644
index 0000000..6f58e45
--- /dev/null
+++ b/.github/workflows/IntegrationTestRequest.yml
@@ -0,0 +1,14 @@
+name: "Integration Test Request"
+on:
+ issue_comment:
+ types:
+ - "created"
+jobs:
+ integrationrequest:
+ if: |
+ github.event.issue.pull_request &&
+ contains(fromJSON('["OWNER", "COLLABORATOR", "MEMBER"]'), github.event.comment.author_association)
+
+ uses: "ITensor/ITensorActions/.github/workflows/IntegrationTestRequest.yml@main"
+ with:
+ localregistry: "https://github.com/ITensor/ITensorRegistry.git"
diff --git a/.github/workflows/Register.yml b/.github/workflows/Register.yml
deleted file mode 100644
index 5b7cd3b..0000000
--- a/.github/workflows/Register.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-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/Registrator.yml b/.github/workflows/Registrator.yml
new file mode 100644
index 0000000..97dc033
--- /dev/null
+++ b/.github/workflows/Registrator.yml
@@ -0,0 +1,22 @@
+name: "Register Package"
+on:
+ workflow_dispatch: ~
+ push:
+ branches:
+ - "master"
+ - "main"
+ paths:
+ - "Project.toml"
+ issue_comment:
+ types:
+ - "created"
+permissions:
+ contents: "write"
+ pull-requests: "write"
+ issues: "write"
+jobs:
+ Register:
+ uses: "ITensor/ITensorActions/.github/workflows/Registrator.yml@main"
+ with:
+ localregistry: "ITensor/ITensorRegistry"
+ secrets: "inherit"
diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml
index 0cd3114..f535119 100644
--- a/.github/workflows/TagBot.yml
+++ b/.github/workflows/TagBot.yml
@@ -1,31 +1,11 @@
-name: TagBot
+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
+ - "created"
+ workflow_dispatch: ~
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 }}
+ if: "github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'"
+ uses: "ITensor/ITensorActions/.github/workflows/TagBot.yml@main"
+ secrets: "inherit"
diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml
new file mode 100644
index 0000000..70f6c8d
--- /dev/null
+++ b/.github/workflows/Tests.yml
@@ -0,0 +1,53 @@
+name: "Tests"
+on:
+ push:
+ branches:
+ - "master"
+ - "main"
+ - "release-"
+ tags: "*"
+ paths-ignore:
+ - "docs/**"
+ pull_request:
+ types:
+ - "opened"
+ - "synchronize"
+ - "reopened"
+ - "ready_for_review"
+ - "converted_to_draft"
+ workflow_dispatch: ~
+concurrency:
+ group: "${{ github.workflow }}-${{ github.ref }}"
+ cancel-in-progress: "${{ startsWith(github.ref, 'refs/pull/') }}"
+jobs:
+ tests:
+ name: "Tests"
+ strategy:
+ fail-fast: false
+ matrix:
+ version:
+ - "lts"
+ - "1"
+ os:
+ - "ubuntu-latest"
+ - "macOS-latest"
+ - "windows-latest"
+ uses: "ITensor/ITensorActions/.github/workflows/Tests.yml@main"
+ with:
+ group: "${{ matrix.group }}"
+ julia-version: "${{ matrix.version }}"
+ os: "${{ matrix.os }}"
+ localregistry: "https://github.com/ITensor/ITensorRegistry.git"
+ secrets:
+ CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"
+ tests-gate:
+ name: "Tests"
+ needs: "tests"
+ if: "${{ always() && needs.tests.result != 'skipped' }}"
+ runs-on: "ubuntu-latest"
+ steps:
+ - name: "Fail if any matrix leg failed"
+ run: |
+ echo "tests.result = ${{ needs.tests.result }}"
+ test "${{ needs.tests.result }}" = "success"
+
diff --git a/.github/workflows/VersionCheck.yml b/.github/workflows/VersionCheck.yml
new file mode 100644
index 0000000..bb0df88
--- /dev/null
+++ b/.github/workflows/VersionCheck.yml
@@ -0,0 +1,9 @@
+name: "Version Check"
+on:
+ pull_request: ~
+jobs:
+ version-check:
+ name: "Version Check"
+ uses: "ITensor/ITensorActions/.github/workflows/VersionCheck.yml@main"
+ with:
+ localregistry: "https://github.com/ITensor/ITensorRegistry.git"
diff --git a/.gitignore b/.gitignore
index faa7bfd..d5d9e4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,14 @@
-Manifest.toml
-.*.swp
+*.cov
+*.mem
+*.o
+*.swp
+.DS_Store
+.benchmarkci
+.tmp
+.vscode/
+LocalPreferences.toml
+Manifest*.toml
+benchmark/*.json
+dev/
+docs/build/
+docs/src/index.md
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..d5593c0
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,17 @@
+ci:
+ skip:
+ - "itensor-formatter"
+repos:
+ - repo: "https://github.com/pre-commit/pre-commit-hooks"
+ rev: "v6.0.0"
+ hooks:
+ - id: "check-merge-conflict"
+ - id: "check-toml"
+ - id: "check-yaml"
+ - id: "end-of-file-fixer"
+ exclude_types:
+ - "markdown"
+ - repo: "https://github.com/ITensor/itensorformatter-pre-commit"
+ rev: "v1.0.0"
+ hooks:
+ - id: "itensor-formatter"
diff --git a/Project.toml b/Project.toml
index 65abd68..3c35ea1 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
name = "ITensorVisualizationBase"
uuid = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23"
+version = "0.1.15"
authors = ["Matthew Fishman and contributors"]
-version = "0.1.14"
[workspace]
projects = ["benchmark", "dev", "docs", "examples", "test"]
@@ -21,12 +21,14 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
[compat]
AbstractTrees = "0.4"
-Compat = "3.40.0, 4"
+Compat = "3.40, 4"
GeometryBasics = "0.4.1, 0.5"
Graphs = "1.4.1"
ITensorMPS = "0.3"
ITensors = "0.7, 0.8, 0.9"
+LinearAlgebra = "1.10"
MetaGraphs = "0.7.1, 0.8, 0.9"
NetworkLayout = "0.4.3"
+SparseArrays = "1.10"
Statistics = "1.10"
julia = "1.10"
diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl
new file mode 100644
index 0000000..45b79f4
--- /dev/null
+++ b/benchmark/benchmarks.jl
@@ -0,0 +1,7 @@
+using BenchmarkTools
+using ITensorVisualizationBase
+
+SUITE = BenchmarkGroup()
+SUITE["rand"] = @benchmarkable rand(10)
+
+# Write your benchmarks here.
diff --git a/docs/Project.toml b/docs/Project.toml
index 1814eb3..1b4c563 100644
--- a/docs/Project.toml
+++ b/docs/Project.toml
@@ -1,5 +1,12 @@
[deps]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
+ITensorFormatter = "b6bf39f1-c9d3-4bad-aad8-593d802f65fd"
+ITensorVisualizationBase = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23"
+
+[sources.ITensorVisualizationBase]
+path = ".."
[compat]
Documenter = "1"
+ITensorFormatter = "0.2.27"
+ITensorVisualizationBase = "0.1"
diff --git a/docs/make.jl b/docs/make.jl
index 7508ce6..b9e70b9 100644
--- a/docs/make.jl
+++ b/docs/make.jl
@@ -1,20 +1,27 @@
-using ITensorVisualizationBase
-using Documenter
+using Documenter: Documenter, DocMeta, deploydocs, makedocs
+using ITensorFormatter: ITensorFormatter
+using ITensorVisualizationBase: ITensorVisualizationBase
DocMeta.setdocmeta!(
- ITensorVisualizationBase, :DocTestSetup, :(using ITensorVisualizationBase); recursive=true
+ ITensorVisualizationBase, :DocTestSetup, :(using ITensorVisualizationBase);
+ recursive = true
)
+ITensorFormatter.make_index!(pkgdir(ITensorVisualizationBase))
+
makedocs(;
- modules=[ITensorVisualizationBase],
- authors="ITensor developers",
- sitename="ITensorVisualizationBase.jl",
- format=Documenter.HTML(;
- canonical="https://ITensor.github.io/ITensorVisualizationBase.jl",
- edit_link="main",
- assets=String[],
- ),
- pages=["Home" => "index.md"],
+ modules = [ITensorVisualizationBase],
+ authors = "ITensor developers and contributors",
+ sitename = "ITensorVisualizationBase.jl",
+ format = Documenter.HTML(;
+ canonical = "https://itensor.github.io/ITensorVisualizationBase.jl",
+ edit_link = "main",
+ assets = ["assets/favicon.ico", "assets/extras.css"]
+ ),
+ pages = ["Home" => "index.md", "Reference" => "reference.md"]
)
-deploydocs(; repo="github.com/ITensor/ITensorVisualizationBase.jl", devbranch="main")
+deploydocs(;
+ repo = "github.com/ITensor/ITensorVisualizationBase.jl", devbranch = "main",
+ push_preview = true
+)
diff --git a/docs/src/assets/CCQ-dark.png b/docs/src/assets/CCQ-dark.png
new file mode 100644
index 0000000..fbaef52
Binary files /dev/null and b/docs/src/assets/CCQ-dark.png differ
diff --git a/docs/src/assets/CCQ.png b/docs/src/assets/CCQ.png
new file mode 100644
index 0000000..e13f908
Binary files /dev/null and b/docs/src/assets/CCQ.png differ
diff --git a/docs/src/assets/extras.css b/docs/src/assets/extras.css
new file mode 100644
index 0000000..aaab0f8
--- /dev/null
+++ b/docs/src/assets/extras.css
@@ -0,0 +1,15 @@
+.display-light-only {
+ display: block;
+}
+
+.display-dark-only {
+ display: none;
+}
+
+.theme--documenter-dark .display-light-only {
+ display: none;
+}
+
+.theme--documenter-dark .display-dark-only {
+ display: block;
+}
diff --git a/docs/src/assets/favicon.ico b/docs/src/assets/favicon.ico
new file mode 100644
index 0000000..0b06780
Binary files /dev/null and b/docs/src/assets/favicon.ico differ
diff --git a/docs/src/assets/logo-dark.png b/docs/src/assets/logo-dark.png
new file mode 100644
index 0000000..7450635
Binary files /dev/null and b/docs/src/assets/logo-dark.png differ
diff --git a/docs/src/assets/logo.png b/docs/src/assets/logo.png
new file mode 100644
index 0000000..2682e14
Binary files /dev/null and b/docs/src/assets/logo.png differ
diff --git a/docs/src/reference.md b/docs/src/reference.md
new file mode 100644
index 0000000..8d30075
--- /dev/null
+++ b/docs/src/reference.md
@@ -0,0 +1,5 @@
+# Reference
+
+```@autodocs
+Modules = [ITensorVisualizationBase]
+```
diff --git a/examples/Project.toml b/examples/Project.toml
index e10076a..6d84b76 100644
--- a/examples/Project.toml
+++ b/examples/Project.toml
@@ -1,17 +1,8 @@
[deps]
-GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
-Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
-ITensorMPS = "0d1a4710-d33b-49a5-8f18-73bdf49b47e2"
ITensorVisualizationBase = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23"
-ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
-LayeredLayouts = "f4a74d36-062a-4d48-97cd-1356bad1de4e"
-NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
+
+[sources.ITensorVisualizationBase]
+path = ".."
[compat]
-GeometryBasics = "0.4.1, 0.5"
-Graphs = "1.4.1"
-ITensorMPS = "0.3"
ITensorVisualizationBase = "0.1"
-ITensors = "0.7, 0.8, 0.9"
-LayeredLayouts = "0.2"
-NetworkLayout = "0.4.3"
diff --git a/examples/ex_2d_tensor_network_layered.jl b/examples/ex_2d_tensor_network_layered.jl
index 8a652b8..733021f 100644
--- a/examples/ex_2d_tensor_network_layered.jl
+++ b/examples/ex_2d_tensor_network_layered.jl
@@ -1,9 +1,9 @@
-using ITensors
+using Graphs
using ITensorVisualizationBase
+using ITensors
using LayeredLayouts
-using Graphs
-tn = itensornetwork(grid((4, 4)); linkspaces=3)
+tn = itensornetwork(grid((4, 4)); linkspaces = 3)
layout(g) = layered_layout(solve_positions(Zarate(), g))
@visualize fig tn arrow_show = true layout = layout
diff --git a/examples/ex_dmrg.jl b/examples/ex_dmrg.jl
index b4c3778..b80151f 100644
--- a/examples/ex_dmrg.jl
+++ b/examples/ex_dmrg.jl
@@ -1,17 +1,17 @@
-using ITensors
using ITensorVisualizationBase
+using ITensors
N = 10
-sites(n) = Index([QN("Sz", 0) => 1, QN("Sz", 1) => 1]; tags="S=1/2,Site,n=$n")
-l(n) = Index([QN("Sz", 0) => 10, QN("Sz", 1) => 10]; tags="Link,l=$n")
-h(n) = Index([QN("Sz", 0) => 5, QN("Sz", 1) => 5]; tags="ham,Link,l=$n")
+sites(n) = Index([QN("Sz", 0) => 1, QN("Sz", 1) => 1]; tags = "S=1/2,Site,n=$n")
+l(n) = Index([QN("Sz", 0) => 10, QN("Sz", 1) => 10]; tags = "Link,l=$n")
+h(n) = Index([QN("Sz", 0) => 5, QN("Sz", 1) => 5]; tags = "ham,Link,l=$n")
s⃗ = [sites(n) for n in 1:N]
l⃗ = [l(n) for n in 1:(N - 1)]
h⃗ = [h(n) for n in 1:(N - 1)]
# Add some more indices between two of the tensors
-x = Index([QN("Sz", 0) => 2]; tags="X")
-y = Index([QN("Sz", 0) => 2]; tags="Y")
+x = Index([QN("Sz", 0) => 2]; tags = "X")
+y = Index([QN("Sz", 0) => 2]; tags = "Y")
n = 2
ψn1n2 = random_itensor(l⃗[n - 1], s⃗[n], s⃗[n + 1], l⃗[n + 1], dag(x), dag(y))
@@ -20,10 +20,10 @@ hn2 = random_itensor(dag(h⃗[n]), s⃗[n + 1]', dag(s⃗[n + 1]), h⃗[n + 1])
ELn0 = random_itensor(l⃗[n - 1]', h⃗[n - 1], dag(l⃗[n - 1]))
ERn2 = random_itensor(l⃗[n + 1]', dag(h⃗[n + 1]), dag(l⃗[n + 1]))
-edge_labels = (; plevs=true)
+edge_labels = (; plevs = true)
R = @visualize fig1 ELn0 * ψn1n2 * hn1 * hn2 * ERn2 edge_labels = edge_labels vertex_size =
- 50
+ 50
@show R ≈ ELn0 * ψn1n2 * hn1 * hn2 * ERn2
# Split it up into multiple contractions
diff --git a/examples/ex_grid_layout.jl b/examples/ex_grid_layout.jl
index 9795c23..6244a12 100644
--- a/examples/ex_grid_layout.jl
+++ b/examples/ex_grid_layout.jl
@@ -1,12 +1,12 @@
-using ITensors
-using ITensorVisualizationBase
using GeometryBasics
using Graphs
+using ITensorVisualizationBase
+using ITensors
using NetworkLayout
N = 10
g = grid((N,))
-tn = itensornetwork(g; linkspaces=10, sitespaces=2)
-@visualize fig tn siteinds_direction = Point(1, -0.5) layout = SquareGrid(; cols=1) width =
- 20 height = 50
+tn = itensornetwork(g; linkspaces = 10, sitespaces = 2)
+@visualize fig tn siteinds_direction = Point(1, -0.5) layout = SquareGrid(; cols = 1) width =
+ 20 height = 50
fig
diff --git a/examples/ex_itensor_graph_makie.jl b/examples/ex_itensor_graph_makie.jl
index 802d0ef..3db9568 100644
--- a/examples/ex_itensor_graph_makie.jl
+++ b/examples/ex_itensor_graph_makie.jl
@@ -1,9 +1,9 @@
-using ITensors
-using ITensorVisualizationBase
using Graphs
+using ITensorVisualizationBase
+using ITensors
g = grid((5,))
-tn = itensornetwork(g; linkspaces=10, sitespaces=2)
+tn = itensornetwork(g; linkspaces = 10, sitespaces = 2)
@visualize fig tn
fig
diff --git a/examples/ex_itensor_graph_unicode.jl b/examples/ex_itensor_graph_unicode.jl
index 802d0ef..3db9568 100644
--- a/examples/ex_itensor_graph_unicode.jl
+++ b/examples/ex_itensor_graph_unicode.jl
@@ -1,9 +1,9 @@
-using ITensors
-using ITensorVisualizationBase
using Graphs
+using ITensorVisualizationBase
+using ITensors
g = grid((5,))
-tn = itensornetwork(g; linkspaces=10, sitespaces=2)
+tn = itensornetwork(g; linkspaces = 10, sitespaces = 2)
@visualize fig tn
fig
diff --git a/examples/ex_qn_mps.jl b/examples/ex_qn_mps.jl
index 583ba34..20d8e7a 100644
--- a/examples/ex_qn_mps.jl
+++ b/examples/ex_qn_mps.jl
@@ -1,14 +1,14 @@
-using ITensors
using ITensorMPS
using ITensorVisualizationBase
+using ITensors
-s = siteinds("S=1/2", 5; conserve_qns=true)
-ψ = random_mps(s, n -> isodd(n) ? "↑" : "↓"; linkdims=2)
+s = siteinds("S=1/2", 5; conserve_qns = true)
+ψ = random_mps(s, n -> isodd(n) ? "↑" : "↓"; linkdims = 2)
orthogonalize!(ψ, 2)
ψdag = prime(linkinds, dag(ψ))
tn = [ψ..., ψdag...]
-edge_labels = (; plevs=true, qns=true)
+edge_labels = (; plevs = true, qns = true)
@visualize fig tn edge_labels = edge_labels edge_textsize = 20
fig
diff --git a/examples/ex_quantum_circuit.jl b/examples/ex_quantum_circuit.jl
index 8e121df..25893a7 100644
--- a/examples/ex_quantum_circuit.jl
+++ b/examples/ex_quantum_circuit.jl
@@ -1,8 +1,8 @@
-using ITensors
+using Graphs
using ITensorMPS
using ITensorVisualizationBase
+using ITensors
using LayeredLayouts
-using Graphs
N = 10
layers = 10
@@ -14,11 +14,11 @@ layer(N) = append!(layer(N, 1), layer(N, 2))
layer_N = layer(N)
gates = []
for _ in 1:layers
- append!(gates, layer_N)
+ append!(gates, layer_N)
end
for _ in 1:ndelete
- deleteat!(gates, rand(eachindex(gates)))
+ deleteat!(gates, rand(eachindex(gates)))
end
U, s̃ = circuit_network(gates, s)
@@ -26,7 +26,7 @@ U, s̃ = circuit_network(gates, s)
ψ̃ = prod(MPS(s̃))
tn = [ψ, U..., ψ̃]
-edge_labels = (; plevs=true)
+edge_labels = (; plevs = true)
layout(g) = layered_layout(solve_positions(Zarate(), g))
@visualize fig tn arrow_show = true edge_labels = edge_labels layout = layout
diff --git a/examples/ex_visualize_3d.jl b/examples/ex_visualize_3d.jl
index de61049..e2e5573 100644
--- a/examples/ex_visualize_3d.jl
+++ b/examples/ex_visualize_3d.jl
@@ -1,9 +1,9 @@
-using ITensors
-using ITensorVisualizationBase
using Graphs
+using ITensorVisualizationBase
+using ITensors
tn = itensornetwork(grid((3, 3, 3)))
-edge_labels = (; dims=false)
+edge_labels = (; dims = false)
@visualize fig tn ndims = 3 edge_labels = edge_labels vertex_size = 400
fig
diff --git a/src/ITensorVisualizationBase.jl b/src/ITensorVisualizationBase.jl
index 46c5325..2f9403c 100644
--- a/src/ITensorVisualizationBase.jl
+++ b/src/ITensorVisualizationBase.jl
@@ -1,49 +1,31 @@
module ITensorVisualizationBase
+import ITensors.ITensorVisualizationCore: visualize, visualize!, visualize_sequence
using AbstractTrees
using Compat
using GeometryBasics
using Graphs
+using Graphs: Graphs, AbstractEdge, AbstractGraph, SimpleDiGraph, SimpleGraph, add_edge!,
+ add_vertex!, all_neighbors, dst, edges, ne, neighbors, nv, src, vertices
using ITensors
using ITensors.ITensorVisualizationCore
+using ITensors: QNIndex, data
using LinearAlgebra
using MetaGraphs
using NetworkLayout
using SparseArrays
using Statistics
-# Avoid conflict between `Graphs.contract` and `ITensors.contract`
-using Graphs:
- Graphs,
- AbstractEdge,
- AbstractGraph,
- SimpleGraph,
- SimpleDiGraph,
- add_edge!,
- add_vertex!,
- all_neighbors,
- dst,
- edges,
- ne,
- neighbors,
- nv,
- src,
- vertices
-
-using ITensors: data, QNIndex
-
-import ITensors.ITensorVisualizationCore: visualize, visualize!, visualize_sequence
-
export @visualize,
- @visualize!,
- @visualize_noeval,
- @visualize_noeval!,
- @visualize_sequence,
- @visualize_sequence_noeval,
- circuit_network,
- itensornetwork,
- layered_layout,
- IndexLabels
+ @visualize!,
+ @visualize_noeval,
+ @visualize_noeval!,
+ @visualize_sequence,
+ @visualize_sequence_noeval,
+ circuit_network,
+ itensornetwork,
+ layered_layout,
+ IndexLabels
# Some general graph functionality
include("graphs.jl")
diff --git a/src/backends_interface.jl b/src/backends_interface.jl
index 9d2476d..8e5d83e 100644
--- a/src/backends_interface.jl
+++ b/src/backends_interface.jl
@@ -8,35 +8,35 @@ backend(::Backend{N}) where {N} = N
Backend() = Backend{Symbol()}()
macro Backend_str(s)
- return Backend{Symbol(s)}
+ return Backend{Symbol(s)}
end
-const current_backend = Ref{Union{Nothing,Backend}}(nothing)
+const current_backend = Ref{Union{Nothing, Backend}}(nothing)
visualize(::Backend{nothing}, args...; kwargs...) = nothing
set_backend!(::Nothing) = (current_backend[] = nothing)
function set_backend!(backend::Backend)
- original_backend = current_backend[]
- current_backend[] = backend
- return original_backend
+ original_backend = current_backend[]
+ current_backend[] = backend
+ return original_backend
end
-set_backend!(backend::Union{Symbol,String}) = set_backend!(Backend(backend))
+set_backend!(backend::Union{Symbol, String}) = set_backend!(Backend(backend))
get_backend() = isnothing(current_backend[]) ? default_backend() : current_backend[]
function plot(::Backend{T}, args...; kwargs...) where {T}
- return error("plot not implemented for backend type $T.")
+ return error("plot not implemented for backend type $T.")
end
function draw_edge!(::Backend{T}, args...; kwargs...) where {T}
- return error("draw_edge! not implemented for backend type $T.")
+ return error("draw_edge! not implemented for backend type $T.")
end
function annotate!(::Backend{T}, args...; kwargs...) where {T}
- return error("annotate! not implemented for backend type $T.")
+ return error("annotate! not implemented for backend type $T.")
end
function translate_color(::Backend{T}, color) where {T}
- return error("translate_color not implemented for backend type $T and color $color")
+ return error("translate_color not implemented for backend type $T and color $color")
end
point_to_line(v1, v2) = ([v1[1], v2[1]], [v1[2], v2[2]])
diff --git a/src/defaults.jl b/src/defaults.jl
index a43d72b..9e309cb 100644
--- a/src/defaults.jl
+++ b/src/defaults.jl
@@ -9,25 +9,25 @@ default_backend() = Backend(nothing)
#
function subscript_char(n::Integer)
- @assert 0 ≤ n ≤ 9
- return Char(0x2080 + n)
+ @assert 0 ≤ n ≤ 9
+ return Char(0x2080 + n)
end
function subscript(n::Integer)
- ss = prod(Iterators.reverse((subscript_char(d) for d in digits(abs(n)))))
- if n < 0
- ss = "₋" * ss
- end
- return ss
+ ss = prod(Iterators.reverse((subscript_char(d) for d in digits(abs(n)))))
+ if n < 0
+ ss = "₋" * ss
+ end
+ return ss
end
subscript(n) = string(n)
default_vertex_labels_prefix(b::Backend, g) = "T"
function default_vertex_labels(
- b::Backend, g::AbstractGraph, vertex_labels_prefix=default_vertex_labels_prefix(b)
-)
- return [string(vertex_labels_prefix, subscript(v)) for v in vertices(g)]
+ b::Backend, g::AbstractGraph, vertex_labels_prefix = default_vertex_labels_prefix(b)
+ )
+ return [string(vertex_labels_prefix, subscript(v)) for v in vertices(g)]
end
default_vertex_size(b::Backend, g) = 60
@@ -44,11 +44,11 @@ default_vertex_textsize(b::Backend, g) = 20
default_edge_textsize(b::Backend) = 30
function default_edge_labels(b::Backend, g::AbstractGraph)
- return fill("", ne(g))
+ return fill("", ne(g))
end
function default_edge_labels(b::Backend, g::AbstractMetaGraph)
- return IndexLabels(b)
+ return IndexLabels(b)
end
default_dims(b::Backend) = true
@@ -63,59 +63,59 @@ abstract type AbstractEdgeLabels end
(l::AbstractEdgeLabels)(g::AbstractGraph) = edge_labels(l, g)
struct IndexLabels <: AbstractEdgeLabels
- dims::Bool
- tags::Bool
- ids::Bool
- plevs::Bool
- qns::Bool
- newlines::Bool
+ dims::Bool
+ tags::Bool
+ ids::Bool
+ plevs::Bool
+ qns::Bool
+ newlines::Bool
end
IndexLabels(; kwargs...) = IndexLabels(Backend(); kwargs...)
IndexLabels(backend; kwargs...) = IndexLabels(Backend(backend); kwargs...)
function IndexLabels(
- b::Backend;
- dims=default_dims(b),
- tags=default_tags(b),
- ids=default_ids(b),
- plevs=default_plevs(b),
- qns=default_qns(b),
- newlines=default_newlines(b),
-)
- return IndexLabels(dims, tags, ids, plevs, qns, newlines)
+ b::Backend;
+ dims = default_dims(b),
+ tags = default_tags(b),
+ ids = default_ids(b),
+ plevs = default_plevs(b),
+ qns = default_qns(b),
+ newlines = default_newlines(b)
+ )
+ return IndexLabels(dims, tags, ids, plevs, qns, newlines)
end
edge_labels(b::Backend, l::Vector{String}, g::AbstractGraph) = l
function edge_labels(b::Backend, l::IndexLabels, g::AbstractGraph)
- return edge_labels(l, g)
+ return edge_labels(l, g)
end
function edge_labels(l::IndexLabels, g::AbstractGraph)
- return String[edge_label(l, g, e) for e in edges(g)]
+ return String[edge_label(l, g, e) for e in edges(g)]
end
function edge_labels(b::Backend, params::NamedTuple, g::AbstractGraph)
- return IndexLabels(b; params...)(g)
+ return IndexLabels(b; params...)(g)
end
function edge_label(l::IndexLabels, g::AbstractMetaGraph, e)
- indsₑ = get_prop(g, e, :inds)
- return label_string(
- indsₑ;
- is_self_loop=is_self_loop(e),
- dims=l.dims,
- tags=l.tags,
- ids=l.ids,
- plevs=l.plevs,
- qns=l.qns,
- newlines=l.newlines,
- )
+ indsₑ = get_prop(g, e, :inds)
+ return label_string(
+ indsₑ;
+ is_self_loop = is_self_loop(e),
+ dims = l.dims,
+ tags = l.tags,
+ ids = l.ids,
+ plevs = l.plevs,
+ qns = l.qns,
+ newlines = l.newlines
+ )
end
function _edge_label(l, g::AbstractGraph, e)
- return string(e)
+ return string(e)
end
edge_label(l::IndexLabels, g::AbstractGraph, e) = _edge_label(l, g, e)
@@ -130,68 +130,75 @@ idstring(i::Index) = string(id(i) % 1000)
tagsstring(i::Index) = string(tags(i))
qnstring(i::Index) = ""
function qnstring(i::QNIndex)
- str = "["
- for (n, qnblock) in pairs(space(i))
- str *= "$qnblock"
- if n ≠ lastindex(space(i))
- str *= ", "
+ str = "["
+ for (n, qnblock) in pairs(space(i))
+ str *= "$qnblock"
+ if n ≠ lastindex(space(i))
+ str *= ", "
+ end
+ end
+ str *= "]"
+ if dir(i) == ITensors.In
+ str *= "†"
end
- end
- str *= "]"
- if dir(i) == ITensors.In
- str *= "†"
- end
- return str
+ return str
end
function label_string(i::Index; dims, tags, plevs, ids, qns)
- showing_plev = plevs && (plev(i) > 0)
-
- str = ""
- if any((tags, showing_plev, ids, qns))
- str *= "("
- end
- if dims
- str *= string(dim(i))
- end
- if ids
+ showing_plev = plevs && (plev(i) > 0)
+
+ str = ""
+ if any((tags, showing_plev, ids, qns))
+ str *= "("
+ end
if dims
- str *= "|"
+ str *= string(dim(i))
+ end
+ if ids
+ if dims
+ str *= "|"
+ end
+ str *= idstring(i)
+ end
+ if tags
+ if any((dims, ids))
+ str *= "|"
+ end
+ str *= tagsstring(i)
+ end
+ if any((tags, showing_plev, ids, qns))
+ str *= ")"
+ end
+ if plevs
+ str *= plevstring(i)
end
- str *= idstring(i)
- end
- if tags
- if any((dims, ids))
- str *= "|"
+ if qns
+ str *= qnstring(i)
end
- str *= tagsstring(i)
- end
- if any((tags, showing_plev, ids, qns))
- str *= ")"
- end
- if plevs
- str *= plevstring(i)
- end
- if qns
- str *= qnstring(i)
- end
- return str
-end
-
-function label_string(is; is_self_loop=false, dims, tags, plevs, ids, qns, newlines)
- str = ""
- for n in eachindex(is)
- str *= label_string(is[n]; dims=dims, tags=tags, plevs=plevs, ids=ids, qns=qns)
- if n ≠ lastindex(is)
- if any((dims, tags, ids, qns))
- str *= "⊗"
- end
- if newlines && any((tags, ids, qns))
- str *= "\n"
- end
+ return str
+end
+
+function label_string(is; is_self_loop = false, dims, tags, plevs, ids, qns, newlines)
+ str = ""
+ for n in eachindex(is)
+ str *= label_string(
+ is[n];
+ dims = dims,
+ tags = tags,
+ plevs = plevs,
+ ids = ids,
+ qns = qns
+ )
+ if n ≠ lastindex(is)
+ if any((dims, tags, ids, qns))
+ str *= "⊗"
+ end
+ if newlines && any((tags, ids, qns))
+ str *= "\n"
+ end
+ end
end
- end
- return str
+ return str
end
#############################################################################
@@ -199,15 +206,15 @@ end
#
function width(inds)
- return log2(dim(inds)) + 1
+ return log2(dim(inds)) + 1
end
function default_edge_widths(b::Backend, g::AbstractMetaGraph)
- return Float64[width(get_prop(g, e, :inds)) for e in edges(g)]
+ return Float64[width(get_prop(g, e, :inds)) for e in edges(g)]
end
function default_edge_widths(b::Backend, g::AbstractGraph)
- return fill(one(Float64), ne(g))
+ return fill(one(Float64), ne(g))
end
#############################################################################
@@ -219,14 +226,14 @@ default_arrow_size(b::Backend, g) = 30
_hasqns(tn::Vector{ITensor}) = any(hasqns, tn)
function _hasqns(g::AbstractMetaGraph)
- if iszero(ne(g))
- if has_prop(g, first(vertices(g)), :inds)
- return hasqns(get_prop(g, first(vertices(g)), :inds))
- else
- return hasqns(())
+ if iszero(ne(g))
+ if has_prop(g, first(vertices(g)), :inds)
+ return hasqns(get_prop(g, first(vertices(g)), :inds))
+ else
+ return hasqns(())
+ end
end
- end
- return hasqns(get_prop(g, first(edges(g)), :inds))
+ return hasqns(get_prop(g, first(edges(g)), :inds))
end
_hasqns(g::AbstractGraph) = false
diff --git a/src/experimental/spanning_trees/mst.jl b/src/experimental/spanning_trees/mst.jl
index fa3e278..4d1858d 100644
--- a/src/experimental/spanning_trees/mst.jl
+++ b/src/experimental/spanning_trees/mst.jl
@@ -1,12 +1,14 @@
-using Graphs, SimpleWeightedGraphs
-using GraphRecipes, Plots
+using GraphRecipes
+using Graphs
+using Plots
+using SimpleWeightedGraphs
#spanning_tree_method = "mst"
spanning_tree_method = "bfs"
nx, ny = 7, 7
n = nx * ny
-g = Graphs.grid((nx, ny); periodic=false)
+g = Graphs.grid((nx, ny); periodic = false)
nx_middle = nx ÷ 2 + 1
ny_middle = ny ÷ 2 + 1
@@ -20,52 +22,52 @@ names = dist
wg = SimpleWeightedGraph(nv(g))
for e in edges(g)
- dw = mean([dist[src(e)], dist[dst(e)]])
- w = 1 / dw^2 + eps() * randn()
- add_edge!(wg, src(e), dst(e), w)
+ dw = mean([dist[src(e)], dist[dst(e)]])
+ w = 1 / dw^2 + eps() * randn()
+ add_edge!(wg, src(e), dst(e), w)
end
g_st = if spanning_tree_method == "mst"
- # mst_function = boruvka_mst
- mst_function = kruskal_mst
- mst_weight = mst_function(wg; minimize=false)
- mst = mst_function == boruvka_mst ? mst_weight.mst : mst_weight
- g_mst = SimpleWeightedGraph(nv(wg))
- for ew in mst
- add_edge!(g_mst, src(ew), dst(ew), weight(ew))
- end
- g_mst
+ # mst_function = boruvka_mst
+ mst_function = kruskal_mst
+ mst_weight = mst_function(wg; minimize = false)
+ mst = mst_function == boruvka_mst ? mst_weight.mst : mst_weight
+ g_mst = SimpleWeightedGraph(nv(wg))
+ for ew in mst
+ add_edge!(g_mst, src(ew), dst(ew), weight(ew))
+ end
+ g_mst
elseif spanning_tree_method == "bfs"
- # Weights are set to 1
- SimpleWeightedGraph(dfs_tree(wg, n_middle))
+ # Weights are set to 1
+ SimpleWeightedGraph(dfs_tree(wg, n_middle))
end
-edgelabel_dict = Dict{Tuple{Int,Int},String}()
+edgelabel_dict = Dict{Tuple{Int, Int}, String}()
for ew in edges(wg)
- edgelabel_dict[(src(ew), dst(ew))] = string(round(weight(ew); digits=2))
+ edgelabel_dict[(src(ew), dst(ew))] = string(round(weight(ew); digits = 2))
end
edgecolor_dict = Dict()
for ew in edges(wg)
- color = ew ∈ edges(g_st) ? :black : :red
- edgecolor_dict[(src(ew), dst(ew))] = color
+ color = ew ∈ edges(g_st) ? :black : :red
+ edgecolor_dict[(src(ew), dst(ew))] = color
end
edgelabel_dict_mst = Dict()
for i in vertices(g_st), j in vertices(g_st)
- edgelabel_dict_mst[(i, j)] = string(round(get_weight(g_st, i, j); digits=2))
+ edgelabel_dict_mst[(i, j)] = string(round(get_weight(g_st, i, j); digits = 2))
end
plt = graphplot(
- wg;
- markersize=0.3,
- names=names,
- edgelabel=edgelabel_dict,
- curves=false,
- edgecolor=edgecolor_dict,
- linewidth=20,
- fontsize=20,
- size=(3000, 3000),
+ wg;
+ markersize = 0.3,
+ names = names,
+ edgelabel = edgelabel_dict,
+ curves = false,
+ edgecolor = edgecolor_dict,
+ linewidth = 20,
+ fontsize = 20,
+ size = (3000, 3000)
)
plt
diff --git a/src/experimental/spanning_trees/shortest_path_tree.jl b/src/experimental/spanning_trees/shortest_path_tree.jl
index 0cfb3a7..802aade 100644
--- a/src/experimental/spanning_trees/shortest_path_tree.jl
+++ b/src/experimental/spanning_trees/shortest_path_tree.jl
@@ -4,18 +4,18 @@ using Random
Random.seed!(1234)
function dijkstra_spt(g, v_src_initial)
- out = dijkstra_shortest_paths(g, [v_src_initial]; allpaths=true, trackvertices=true)
- paths = out.predecessors
- edges = Edge{Int}[]
- for v_dst_final in eachindex(paths)
- v_src = v_src_initial
- p = paths[v_dst_final]
- @show v_src_initial, p, v_dst_final
- for v_src in p
- push!(edges, Edge(v_src => v_dst_final))
+ out = dijkstra_shortest_paths(g, [v_src_initial]; allpaths = true, trackvertices = true)
+ paths = out.predecessors
+ edges = Edge{Int}[]
+ for v_dst_final in eachindex(paths)
+ v_src = v_src_initial
+ p = paths[v_dst_final]
+ @show v_src_initial, p, v_dst_final
+ for v_src in p
+ push!(edges, Edge(v_src => v_dst_final))
+ end
end
- end
- return edges
+ return edges
end
g = Graph(6, 10)
diff --git a/src/experimental/spanning_trees/spanning_tree.jl b/src/experimental/spanning_trees/spanning_tree.jl
index 1efc971..cae42b0 100644
--- a/src/experimental/spanning_trees/spanning_tree.jl
+++ b/src/experimental/spanning_trees/spanning_tree.jl
@@ -1,12 +1,14 @@
-using Graphs, SimpleWeightedGraphs
-using GraphRecipes, Plots
+using GraphRecipes
+using Graphs
+using Plots
+using SimpleWeightedGraphs
#spanning_tree_method = "mst"
spanning_tree_method = "bfs"
nx, ny = 7, 7
n = nx * ny
-g = Graphs.grid((nx, ny); periodic=false)
+g = Graphs.grid((nx, ny); periodic = false)
nx_middle = 1 #nx ÷ 2 + 1
ny_middle = 1 #ny ÷ 2 + 1
@@ -20,52 +22,52 @@ names = dist
wg = SimpleWeightedGraph(nv(g))
for e in edges(g)
- dw = mean([dist[src(e)], dist[dst(e)]])
- w = 1 / dw^2 + eps() * randn()
- add_edge!(wg, src(e), dst(e), w)
+ dw = mean([dist[src(e)], dist[dst(e)]])
+ w = 1 / dw^2 + eps() * randn()
+ add_edge!(wg, src(e), dst(e), w)
end
g_st = if spanning_tree_method == "mst"
- # mst_function = boruvka_mst
- mst_function = kruskal_mst
- mst_weight = mst_function(wg; minimize=false)
- mst = mst_function == boruvka_mst ? mst_weight.mst : mst_weight
- g_mst = SimpleWeightedGraph(nv(wg))
- for ew in mst
- add_edge!(g_mst, src(ew), dst(ew), weight(ew))
- end
- g_mst
+ # mst_function = boruvka_mst
+ mst_function = kruskal_mst
+ mst_weight = mst_function(wg; minimize = false)
+ mst = mst_function == boruvka_mst ? mst_weight.mst : mst_weight
+ g_mst = SimpleWeightedGraph(nv(wg))
+ for ew in mst
+ add_edge!(g_mst, src(ew), dst(ew), weight(ew))
+ end
+ g_mst
elseif spanning_tree_method == "bfs"
- # Weights are set to 1
- SimpleWeightedGraph(bfs_tree(wg, n_middle))
+ # Weights are set to 1
+ SimpleWeightedGraph(bfs_tree(wg, n_middle))
end
-edgelabel_dict = Dict{Tuple{Int,Int},String}()
+edgelabel_dict = Dict{Tuple{Int, Int}, String}()
for ew in edges(wg)
- edgelabel_dict[(src(ew), dst(ew))] = string(round(weight(ew); digits=2))
+ edgelabel_dict[(src(ew), dst(ew))] = string(round(weight(ew); digits = 2))
end
edgecolor_dict = Dict()
for ew in edges(wg)
- color = ew ∈ edges(g_st) ? :black : :red
- edgecolor_dict[(src(ew), dst(ew))] = color
+ color = ew ∈ edges(g_st) ? :black : :red
+ edgecolor_dict[(src(ew), dst(ew))] = color
end
edgelabel_dict_mst = Dict()
for i in vertices(g_st), j in vertices(g_st)
- edgelabel_dict_mst[(i, j)] = string(round(get_weight(g_st, i, j); digits=2))
+ edgelabel_dict_mst[(i, j)] = string(round(get_weight(g_st, i, j); digits = 2))
end
plt = graphplot(
- wg;
- markersize=0.3,
- names=names,
- edgelabel=edgelabel_dict,
- curves=false,
- edgecolor=edgecolor_dict,
- linewidth=20,
- fontsize=20,
- size=(3000, 3000),
+ wg;
+ markersize = 0.3,
+ names = names,
+ edgelabel = edgelabel_dict,
+ curves = false,
+ edgecolor = edgecolor_dict,
+ linewidth = 20,
+ fontsize = 20,
+ size = (3000, 3000)
)
plt
diff --git a/src/itensor_graph.jl b/src/itensor_graph.jl
index e23fd0d..8ad2aeb 100644
--- a/src/itensor_graph.jl
+++ b/src/itensor_graph.jl
@@ -7,55 +7,55 @@ using ITensors.SiteTypes: op
hasuniqueinds(args...; kwargs...) = !isempty(uniqueinds(args...; kwargs...))
function graph_dir(inds)
- dirs = dir.(inds)
- if length(dirs) == 1
- return only(dirs)
- end
- if all(==(dirs[1]), dirs)
- return dirs[1]
- end
- return ITensors.Out
+ dirs = dir.(inds)
+ if length(dirs) == 1
+ return only(dirs)
+ end
+ if all(==(dirs[1]), dirs)
+ return dirs[1]
+ end
+ return ITensors.Out
end
# TODO: rename graph, dispatch on QNs to DiGraph
function Graphs.SimpleDiGraph(tn::Vector{ITensor})
- nv = length(tn)
- g = SimpleDiGraph(nv)
- for v1 in 1:nv, v2 in (v1 + 1):nv
- indsᵛ¹ᵛ² = commoninds(tn[v1], tn[v2])
- if !isempty(commoninds(tn[v1], tn[v2]))
- e = v1 => v2
- if graph_dir(indsᵛ¹ᵛ²) == ITensors.In
- e = reverse(e)
- end
- add_edge!(g, e)
+ nv = length(tn)
+ g = SimpleDiGraph(nv)
+ for v1 in 1:nv, v2 in (v1 + 1):nv
+ indsᵛ¹ᵛ² = commoninds(tn[v1], tn[v2])
+ if !isempty(commoninds(tn[v1], tn[v2]))
+ e = v1 => v2
+ if graph_dir(indsᵛ¹ᵛ²) == ITensors.In
+ e = reverse(e)
+ end
+ add_edge!(g, e)
+ end
end
- end
- for v in vertices(g)
- if hasuniqueinds(tn[v], tn[all_neighbors(g, v)]...)
- # Add a self-loop
- add_edge!(g, v => v)
+ for v in vertices(g)
+ if hasuniqueinds(tn[v], tn[all_neighbors(g, v)]...)
+ # Add a self-loop
+ add_edge!(g, v => v)
+ end
end
- end
- return g
+ return g
end
# TODO: rename indsgraph, dispatch on QNs to DiGraph
function MetaGraphs.MetaDiGraph(tn::Vector{ITensor})
- sg = SimpleDiGraph(tn)
- mg = MetaDiGraph(sg)
- for e in edges(mg)
- indsₑ = if is_self_loop(e)
- v = src(e)
- # For self edges, the vertex itself is included as
- # a neighbor so we must exclude it.
- uniqueinds(tn[v], tn[setdiff(all_neighbors(mg, v), v)]...)
- else
- commoninds(tn[src(e)], tn[dst(e)])
+ sg = SimpleDiGraph(tn)
+ mg = MetaDiGraph(sg)
+ for e in edges(mg)
+ indsₑ = if is_self_loop(e)
+ v = src(e)
+ # For self edges, the vertex itself is included as
+ # a neighbor so we must exclude it.
+ uniqueinds(tn[v], tn[setdiff(all_neighbors(mg, v), v)]...)
+ else
+ commoninds(tn[src(e)], tn[dst(e)])
+ end
+ set_prop!(mg, e, :inds, indsₑ)
end
- set_prop!(mg, e, :inds, indsₑ)
- end
- return mg
+ return mg
end
default_linkspaces() = 1
@@ -65,51 +65,51 @@ default(x, x_default) = x
default(x::Nothing, x_default) = x_default
function itensornetwork(
- g::AbstractGraph; linkspaces=default_linkspaces(), sitespaces=nothing
-)
- N = nv(g)
- if !isnothing(sitespaces) && !any_self_loops(g)
- g = copy(g)
- for v in vertices(g)
- add_edge!(g, v => v)
+ g::AbstractGraph; linkspaces = default_linkspaces(), sitespaces = nothing
+ )
+ N = nv(g)
+ if !isnothing(sitespaces) && !any_self_loops(g)
+ g = copy(g)
+ for v in vertices(g)
+ add_edge!(g, v => v)
+ end
+ end
+ sitespaces = default(sitespaces, default_sitespaces())
+ # TODO: Specialize to Index{typeof(linkspaces)}
+ inds_network = [Index[] for _ in 1:N]
+ for e in edges(g)
+ if !is_self_loop(e)
+ lₑ = Index(linkspaces; tags = "l=$(src(e))↔$(dst(e))")
+ push!(inds_network[src(e)], lₑ)
+ push!(inds_network[dst(e)], dag(lₑ))
+ else
+ sₑ = Index(sitespaces; tags = "s=$(src(e))")
+ push!(inds_network[src(e)], sₑ)
+ end
end
- end
- sitespaces = default(sitespaces, default_sitespaces())
- # TODO: Specialize to Index{typeof(linkspaces)}
- inds_network = [Index[] for _ in 1:N]
- for e in edges(g)
- if !is_self_loop(e)
- lₑ = Index(linkspaces; tags="l=$(src(e))↔$(dst(e))")
- push!(inds_network[src(e)], lₑ)
- push!(inds_network[dst(e)], dag(lₑ))
- else
- sₑ = Index(sitespaces; tags="s=$(src(e))")
- push!(inds_network[src(e)], sₑ)
+ tn = Vector{ITensor}(undef, N)
+ for n in 1:N
+ tn[n] = ITensor(inds_network[n])
end
- end
- tn = Vector{ITensor}(undef, N)
- for n in 1:N
- tn[n] = ITensor(inds_network[n])
- end
- return tn
+ return tn
end
-sites(g::Tuple{String,<:Tuple}) = g[2]
-sites(g::Tuple{String,<:Tuple,<:NamedTuple}) = g[2]
-sites(g::Tuple{String,Int}) = g[2]
-sites(g::Tuple{String,Vararg{Int}}) = Base.tail(g)
-sites(g::Tuple{String,Int,<:NamedTuple}) = g[2]
+sites(g::Tuple{String, <:Tuple}) = g[2]
+sites(g::Tuple{String, <:Tuple, <:NamedTuple}) = g[2]
+sites(g::Tuple{String, Int}) = g[2]
+sites(g::Tuple{String, Vararg{Int}}) = Base.tail(g)
+sites(g::Tuple{String, Int, <:NamedTuple}) = g[2]
# Functionality for turning a list of gates into an ITensor
# network.
function circuit_network(gates, s::Vector{<:Index})
- s = copy(s)
- U = ITensor[]
- for g in gates
- push!(U, op(g, s))
- for n in sites(g)
- s[n] = s[n]'
+ s = copy(s)
+ U = ITensor[]
+ for g in gates
+ push!(U, op(g, s))
+ for n in sites(g)
+ s[n] = s[n]'
+ end
end
- end
- return U, s
+ return U, s
end
diff --git a/src/layered_layout.jl b/src/layered_layout.jl
index 05bb134..6f85fbe 100644
--- a/src/layered_layout.jl
+++ b/src/layered_layout.jl
@@ -4,6 +4,6 @@
# layout(g) = layered_layout(solve_positions(Zarate(), g))
#
function layered_layout(pos)
- xs, ys, _ = pos
- return Point.(zip(xs, ys))
+ xs, ys, _ = pos
+ return Point.(zip(xs, ys))
end
diff --git a/src/visualize.jl b/src/visualize.jl
index fd41ef4..74edc53 100644
--- a/src/visualize.jl
+++ b/src/visualize.jl
@@ -6,57 +6,57 @@ using ITensorMPS: MPS
# Tools for contracting a network with a sequence
function _contract(label1::String, label2::String)
- return string("(", label1, "*", label2, ")")
+ return string("(", label1, "*", label2, ")")
end
function _contract(tensor1::ITensor, tensor2::ITensor)
- indsR = noncommoninds(tensor1, tensor2)
- return isempty(indsR) ? ITensor() : ITensor(indsR)
+ indsR = noncommoninds(tensor1, tensor2)
+ return isempty(indsR) ? ITensor() : ITensor(indsR)
end
sequence_traversal(sequence) = reverse(collect(StatelessBFS(sequence)))
-function contract_dict(tensors, sequence, traversal=sequence_traversal(sequence))
- net_tensors = Dict()
- traversal = reverse(collect(StatelessBFS(sequence)))
- for net in traversal
- if net isa Int
- net_tensors[net] = tensors[net]
- else # net isa Vector
- net_tensors[net] = _contract(net_tensors[net[1]], net_tensors[net[2]])
+function contract_dict(tensors, sequence, traversal = sequence_traversal(sequence))
+ net_tensors = Dict()
+ traversal = reverse(collect(StatelessBFS(sequence)))
+ for net in traversal
+ if net isa Int
+ net_tensors[net] = tensors[net]
+ else # net isa Vector
+ net_tensors[net] = _contract(net_tensors[net[1]], net_tensors[net[2]])
+ end
end
- end
- return net_tensors
+ return net_tensors
end
# Return all of the contractions involved in the sequence.
function contraction_sequence(
- tensors,
- sequence,
- traversal=sequence_traversal(sequence),
- contract_dict=contract_dict(tensors, sequence, traversal),
-)
- all_tensors = Any[]
- tensors_1 = Vector{Union{Nothing,eltype(tensors)}}(tensors)
- net_position = Dict()
- N = length(tensors)
- n = N + 1
- for net in traversal
- if net isa Int
- net_position[net] = net
- else
- net_position[net] = n
- n += 1
+ tensors,
+ sequence,
+ traversal = sequence_traversal(sequence),
+ contract_dict = contract_dict(tensors, sequence, traversal)
+ )
+ all_tensors = Any[]
+ tensors_1 = Vector{Union{Nothing, eltype(tensors)}}(tensors)
+ net_position = Dict()
+ N = length(tensors)
+ n = N + 1
+ for net in traversal
+ if net isa Int
+ net_position[net] = net
+ else
+ net_position[net] = n
+ n += 1
+ end
+ if !isa(net, Int)
+ for n in net
+ tensors_1[net_position[n]] = nothing
+ end
+ push!(tensors_1, contract_dict[net])
+ push!(all_tensors, copy(tensors_1))
+ end
end
- if !isa(net, Int)
- for n in net
- tensors_1[net_position[n]] = nothing
- end
- push!(tensors_1, contract_dict[net])
- push!(all_tensors, copy(tensors_1))
- end
- end
- return convert.(Vector{eltype(tensors)}, filter.(!isnothing, all_tensors))
+ return convert.(Vector{eltype(tensors)}, filter.(!isnothing, all_tensors))
end
#
@@ -64,184 +64,195 @@ end
#
struct Tree
- x::Any
+ x::Any
end
function Base.getindex(tree::Tree, indices)
- node = tree.x
- for idx in indices
- node = children(node)[idx]
- end
- return node
+ node = tree.x
+ for idx in indices
+ node = children(node)[idx]
+ end
+ return node
end
tree_to_graph(tr) = tree_to_graph(Tree(tr))
function tree_to_graph(tr::Tree)
- g = SimpleDiGraph()
- labels = Any[]
- walk_tree!(g, labels, tr)
- return (g, labels)
+ g = SimpleDiGraph()
+ labels = Any[]
+ walk_tree!(g, labels, tr)
+ return (g, labels)
end
function walk_tree!(g, labels, tr::Tree)
- add_vertex!(g)
- top_vertex = vertices(g)[end]
- push!(labels, tr.x)
- for i in 1:length(tr.x)
- if isa(tr[i], Vector)
- child = walk_tree!(g, labels, Tree(tr[i]))
- add_edge!(g, child, top_vertex)
- else
- add_vertex!(g)
- n = vertices(g)[end]
- add_edge!(g, n, top_vertex)
- push!(labels, tr[i])
+ add_vertex!(g)
+ top_vertex = vertices(g)[end]
+ push!(labels, tr.x)
+ for i in 1:length(tr.x)
+ if isa(tr[i], Vector)
+ child = walk_tree!(g, labels, Tree(tr[i]))
+ add_edge!(g, child, top_vertex)
+ else
+ add_vertex!(g)
+ n = vertices(g)[end]
+ add_edge!(g, n, top_vertex)
+ push!(labels, tr[i])
+ end
end
- end
- return top_vertex
+ return top_vertex
end
# Visualization function interface. Ultimately calls a beckend.
-function visualize(g::AbstractGraph, sequence=nothing; backend=get_backend(), kwargs...)
- # TODO: do something with the sequence (show sequence, add labels indicating sequence, etc.)
- return visualize(Backend(backend), g; kwargs...)
+function visualize(g::AbstractGraph, sequence = nothing; backend = get_backend(), kwargs...)
+ # TODO: do something with the sequence (show sequence, add labels indicating sequence, etc.)
+ return visualize(Backend(backend), g; kwargs...)
end
-function visualize(tn::Vector{ITensor}, sequence=nothing; kwargs...)
- return visualize(MetaDiGraph(tn), sequence; kwargs...)
+function visualize(tn::Vector{ITensor}, sequence = nothing; kwargs...)
+ return visualize(MetaDiGraph(tn), sequence; kwargs...)
end
function visualize(tn::Tuple{Vector{ITensor}}, args...; kwargs...)
- return visualize(only(tn), args...; kwargs...)
+ return visualize(only(tn), args...; kwargs...)
end
visualize(ψ::MPS, args...; kwargs...) = visualize(data(ψ), args...; kwargs...)
-function visualize(tn::Tuple{ITensor,Vararg{ITensor}}, args...; kwargs...)
- return visualize(collect(tn), args...; kwargs...)
+function visualize(tn::Tuple{ITensor, Vararg{ITensor}}, args...; kwargs...)
+ return visualize(collect(tn), args...; kwargs...)
end
function visualize(t1::ITensor, tn_tail::ITensor...; kwargs...)
- return visualize([t1, tn_tail...]; kwargs...)
+ return visualize([t1, tn_tail...]; kwargs...)
end
# Special case single ITensor
-function visualize(t::ITensor, sequence=nothing; vertex_labels_prefix, kwargs...)
- tn = [t]
- vertex_labels = [vertex_labels_prefix]
- return visualize(MetaDiGraph(tn), sequence; vertex_labels=vertex_labels, kwargs...)
+function visualize(t::ITensor, sequence = nothing; vertex_labels_prefix, kwargs...)
+ tn = [t]
+ vertex_labels = [vertex_labels_prefix]
+ return visualize(MetaDiGraph(tn), sequence; vertex_labels = vertex_labels, kwargs...)
end
# Special case single ITensor
function visualize(tn::Tuple{ITensor}, args...; kwargs...)
- return visualize(only(tn), args...; kwargs...)
+ return visualize(only(tn), args...; kwargs...)
end
-function visualize!(fig, g::AbstractGraph; backend=get_backend(), kwargs...)
- return visualize!(Backend(backend), fig, g; kwargs...)
+function visualize!(fig, g::AbstractGraph; backend = get_backend(), kwargs...)
+ return visualize!(Backend(backend), fig, g; kwargs...)
end
-function visualize!(fig, tn::Vector{ITensor}, sequence=nothing; kwargs...)
- return visualize!(fig, MetaDiGraph(tn); kwargs...)
+function visualize!(fig, tn::Vector{ITensor}, sequence = nothing; kwargs...)
+ return visualize!(fig, MetaDiGraph(tn); kwargs...)
end
-visualize!(fig, ψ::MPS, sequence=nothing; kwargs...) = visualize!(fig, data(ψ); kwargs...)
-function visualize!(fig, tn::Tuple{Vararg{ITensor}}, sequence=nothing; kwargs...)
- return visualize!(fig, collect(tn); kwargs...)
+visualize!(fig, ψ::MPS, sequence = nothing; kwargs...) = visualize!(fig, data(ψ); kwargs...)
+function visualize!(fig, tn::Tuple{Vararg{ITensor}}, sequence = nothing; kwargs...)
+ return visualize!(fig, collect(tn); kwargs...)
end
visualize!(fig, tn::ITensor...; kwargs...) = visualize!(fig, collect(tn); kwargs...)
-function visualize!(fig, tn::Tuple{Vector{ITensor}}, sequence=nothing; kwargs...)
- return visualize!(fig, tn[1], sequence; kwargs...)
+function visualize!(fig, tn::Tuple{Vector{ITensor}}, sequence = nothing; kwargs...)
+ return visualize!(fig, tn[1], sequence; kwargs...)
end
function visualize!(
- fig, f::Function, tn::Tuple{Vararg{ITensor}}, sequence=nothing; kwargs...
-)
- return visualize!(fig, tn, sequence; kwargs...)
+ fig, f::Function, tn::Tuple{Vararg{ITensor}}, sequence = nothing; kwargs...
+ )
+ return visualize!(fig, tn, sequence; kwargs...)
end
# Macro outputs a 1-tuple of the function arguments
-function visualize(f::Union{Function,Type}, tn::Tuple{T}, sequence; kwargs...) where {T}
- # TODO: specialize on the function type. Also accept a general collection.
- return visualize(only(tn), sequence; kwargs...)
+function visualize(f::Union{Function, Type}, tn::Tuple{T}, sequence; kwargs...) where {T}
+ # TODO: specialize on the function type. Also accept a general collection.
+ return visualize(only(tn), sequence; kwargs...)
end
# Macro outputs a tuple of ITensors to visualize
-function visualize(f::Union{Function,Type}, tn::Tuple{Vararg{ITensor}}, sequence; kwargs...)
- # TODO: specialize on the function type. Also accept a general collection.
- return visualize(tn, sequence; kwargs...)
+function visualize(
+ f::Union{Function, Type},
+ tn::Tuple{Vararg{ITensor}},
+ sequence;
+ kwargs...
+ )
+ # TODO: specialize on the function type. Also accept a general collection.
+ return visualize(tn, sequence; kwargs...)
end
-function visualize!(fig, f::Union{Function,Type}, As...; kwargs...)
- # TODO: specialize of the function type. Also accept a general collection.
- return visualize!(fig, As...; kwargs...)
+function visualize!(fig, f::Union{Function, Type}, As...; kwargs...)
+ # TODO: specialize of the function type. Also accept a general collection.
+ return visualize!(fig, As...; kwargs...)
end
function _visualize_sequence!(fig, tn, sequence, n; kwargs...)
- return error("Not implemented")
+ return error("Not implemented")
end
function sequence_labels(sequence, all_sequences, vertex_labels)
- traversal = sequence_traversal(sequence)
- labels_dict = contract_dict(vertex_labels, sequence, traversal)
- all_labels = [labels_dict[s] for s in all_sequences]
- return all_labels
+ traversal = sequence_traversal(sequence)
+ labels_dict = contract_dict(vertex_labels, sequence, traversal)
+ all_labels = [labels_dict[s] for s in all_sequences]
+ return all_labels
end
function _graphplot(backend::Backend, graph; all_labels)
- return error("Not implemented for backend $backend.")
+ return error("Not implemented for backend $backend.")
end
function visualize_sequence(sequence, vertex_labels)
- graph, all_sequences = tree_to_graph(sequence)
- all_labels = sequence_labels(sequence, all_sequences, vertex_labels)
- fig = _graphplot(Backend"Makie"(), graph; all_labels=all_labels)
- return fig
+ graph, all_sequences = tree_to_graph(sequence)
+ all_labels = sequence_labels(sequence, all_sequences, vertex_labels)
+ fig = _graphplot(Backend"Makie"(), graph; all_labels = all_labels)
+ return fig
end
function default_sequence(tn::Vector{ITensor})
- N = length(tn)
- return foldl((x, y) -> [x, y], 1:N)
+ N = length(tn)
+ return foldl((x, y) -> [x, y], 1:N)
end
function visualize_sequence(
- f::Union{Function,Type}, tn::Vector{ITensor}, sequence::Nothing; kwargs...
-)
- return visualize_sequence(f, tn, default_sequence(tn); kwargs...)
+ f::Union{Function, Type}, tn::Vector{ITensor}, sequence::Nothing; kwargs...
+ )
+ return visualize_sequence(f, tn, default_sequence(tn); kwargs...)
end
function visualize_sequence(
- f::Union{Function,Type}, tn::Vector{ITensor}, sequence=default_sequence(tn); kwargs...
-)
- N = length(tn)
-
- # TODO: clean this up a bit
- vertex_labels_prefix = get(
- kwargs,
- :vertex_labels_prefix,
- default_vertex_labels_prefix(Backend("Makie"), MetaDiGraph(tn)),
- )
- vertex_labels = get(
- kwargs,
- :vertex_labels,
- default_vertex_labels(Backend(""), MetaDiGraph(tn), vertex_labels_prefix),
- )
-
- fig = visualize_sequence(sequence, vertex_labels)
-
- visualize!(fig[1, 2], tn; vertex_labels=vertex_labels, kwargs...)
-
- traversal = sequence_traversal(sequence)
- labels_sequence = contraction_sequence(vertex_labels, sequence, traversal)
-
- tn_sequence = contraction_sequence(tn, sequence, traversal)
-
- for n in 1:length(tn_sequence)
- visualize!(fig[1, n + 2], tn_sequence[n]; vertex_labels=labels_sequence[n], kwargs...)
- end
+ f::Union{Function, Type}, tn::Vector{ITensor}, sequence = default_sequence(tn);
+ kwargs...
+ )
+ N = length(tn)
+
+ # TODO: clean this up a bit
+ vertex_labels_prefix = get(
+ kwargs,
+ :vertex_labels_prefix,
+ default_vertex_labels_prefix(Backend("Makie"), MetaDiGraph(tn))
+ )
+ vertex_labels = get(
+ kwargs,
+ :vertex_labels,
+ default_vertex_labels(Backend(""), MetaDiGraph(tn), vertex_labels_prefix)
+ )
+
+ fig = visualize_sequence(sequence, vertex_labels)
+
+ visualize!(fig[1, 2], tn; vertex_labels = vertex_labels, kwargs...)
+
+ traversal = sequence_traversal(sequence)
+ labels_sequence = contraction_sequence(vertex_labels, sequence, traversal)
+
+ tn_sequence = contraction_sequence(tn, sequence, traversal)
+
+ for n in 1:length(tn_sequence)
+ visualize!(
+ fig[1, n + 2],
+ tn_sequence[n];
+ vertex_labels = labels_sequence[n],
+ kwargs...
+ )
+ end
- return fig
+ return fig
end
function visualize_sequence(
- f::Union{Function,Type}, tn::Tuple{Vector{ITensor}}, sequence; kwargs...
-)
- return visualize_sequence(f, tn[1], sequence; kwargs...)
+ f::Union{Function, Type}, tn::Tuple{Vector{ITensor}}, sequence; kwargs...
+ )
+ return visualize_sequence(f, tn[1], sequence; kwargs...)
end
diff --git a/test/Project.toml b/test/Project.toml
index cfb0965..d4a5312 100644
--- a/test/Project.toml
+++ b/test/Project.toml
@@ -1,7 +1,9 @@
[deps]
+Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
ITensorMPS = "0d1a4710-d33b-49a5-8f18-73bdf49b47e2"
+ITensorPkgSkeleton = "3d388ab1-018a-49f4-ae50-18094d5f71ea"
ITensorVisualizationBase = "cd2553d2-8bef-4d93-8a38-c62f17d5ad23"
ITensors = "9136182c-28ba-11e9-034c-db9fb085ebd5"
LayeredLayouts = "f4a74d36-062a-4d48-97cd-1356bad1de4e"
@@ -12,10 +14,13 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
path = ".."
[compat]
+Aqua = "0.8.9"
GeometryBasics = "0.4.1, 0.5"
Graphs = "1.4.1"
ITensorMPS = "0.3"
+ITensorPkgSkeleton = "0.3.42"
ITensorVisualizationBase = "0.1"
ITensors = "0.7, 0.8, 0.9"
LayeredLayouts = "0.2"
NetworkLayout = "0.4.3"
+Test = "1.10"
diff --git a/test/runtests.jl b/test/runtests.jl
index 715d7ac..05baac8 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -1,14 +1,3 @@
-using ITensors
-using ITensorVisualizationBase
-using Test
+using ITensorPkgSkeleton: ITensorPkgSkeleton
-starts_and_ends_with(file, st, en) = startswith(file, st) && endswith(file, en)
-starts_and_ends_with(st, en) = file -> starts_and_ends_with(file, st, en)
-
-test_path = joinpath(@__DIR__)
-test_files = filter(starts_and_ends_with("test_", ".jl"), readdir(test_path))
-@testset "ITensorVisualizationBase.jl" for file in test_files
- file_path = joinpath(test_path, file)
- println("Running test $(file_path)")
- include(file_path)
-end
+ITensorPkgSkeleton.runtests(; testdir = @__DIR__)
diff --git a/test/test_aqua.jl b/test/test_aqua.jl
new file mode 100644
index 0000000..159517c
--- /dev/null
+++ b/test/test_aqua.jl
@@ -0,0 +1,8 @@
+using Aqua: Aqua
+using ITensorVisualizationBase: ITensorVisualizationBase
+using Test: @testset
+
+@testset "Code quality (Aqua.jl)" begin
+ # ITensorVisualizationBase extends APIs from external packages by design.
+ Aqua.test_all(ITensorVisualizationBase; piracies = false)
+end
diff --git a/test/test_basics.jl b/test/test_basics.jl
index 70b9b79..fb4907e 100644
--- a/test/test_basics.jl
+++ b/test/test_basics.jl
@@ -1,51 +1,51 @@
-using ITensors
using ITensorVisualizationBase
+using ITensors
using Test
@testset "Basic tests without any backend" begin
- N = 10
- s(n) = Index([QN("Sz", 0) => 1, QN("Sz", 1) => 1]; tags="S=1/2,Site,n=$n")
- l(n) = Index([QN("Sz", 0) => 10, QN("Sz", 1) => 10]; tags="Link,l=$n")
- h(n) = Index([QN("Sz", 0) => 5, QN("Sz", 1) => 5]; tags="ham,Link,l=$n")
- s⃗ = [s(n) for n in 1:N]
- l⃗ = [l(n) for n in 1:(N - 1)]
- h⃗ = [h(n) for n in 1:(N - 1)]
-
- # Add some more indices between two of the tensors
- x = Index([QN("Sz", 0) => 2]; tags="X")
- y = Index([QN("Sz", 0) => 2]; tags="Y")
-
- n = 2
- ψn1n2 = random_itensor(l⃗[n - 1], s⃗[n], s⃗[n + 1], l⃗[n + 1], dag(x), dag(y))
- hn1 = random_itensor(dag(h⃗[n - 1]), s⃗[n]', dag(s⃗[n]), h⃗[n], x, y)
- hn2 = random_itensor(dag(h⃗[n]), s⃗[n + 1]', dag(s⃗[n + 1]), h⃗[n + 1])
- ELn0 = random_itensor(l⃗[n - 1]', h⃗[n - 1], dag(l⃗[n - 1]))
- ERn2 = random_itensor(l⃗[n + 1]', dag(h⃗[n + 1]), dag(l⃗[n + 1]))
-
- tn = [ELn0, ψn1n2, hn1, hn2, ERn2]
-
- R = @visualize ELn0 * ψn1n2 * hn1 * hn2 * ERn2
- R1 = @visualize ELn0 * ψn1n2 * hn1
- R2 = @visualize R1 * hn2 * ERn2 vertex_labels = ["T1", "T2", "T3"]
- tn2 = @visualize tn
- T = @visualize ELn0
-
- @test R ≈ ELn0 * ψn1n2 * hn1 * hn2 * ERn2
- @test R1 ≈ ELn0 * ψn1n2 * hn1
- @test R2 ≈ ELn0 * ψn1n2 * hn1 * hn2 * ERn2
- @test all(tn .== tn2)
- @test T == ELn0
-
- R = @visualize figR ELn0 * ψn1n2 * hn1 * hn2 * ERn2
- R1 = @visualize figR1 ELn0 * ψn1n2 * hn1
- R2 = @visualize figR2 R1 * hn2 * ERn2 vertex_labels = ["T1", "T2", "T3"]
- T = @visualize figT T
-
- fig_tn = @visualize_noeval tn
-
- @test isnothing(figR)
- @test isnothing(figR1)
- @test isnothing(figR2)
- @test isnothing(fig_tn)
- @test isnothing(figT)
+ N = 10
+ s(n) = Index([QN("Sz", 0) => 1, QN("Sz", 1) => 1]; tags = "S=1/2,Site,n=$n")
+ l(n) = Index([QN("Sz", 0) => 10, QN("Sz", 1) => 10]; tags = "Link,l=$n")
+ h(n) = Index([QN("Sz", 0) => 5, QN("Sz", 1) => 5]; tags = "ham,Link,l=$n")
+ s⃗ = [s(n) for n in 1:N]
+ l⃗ = [l(n) for n in 1:(N - 1)]
+ h⃗ = [h(n) for n in 1:(N - 1)]
+
+ # Add some more indices between two of the tensors
+ x = Index([QN("Sz", 0) => 2]; tags = "X")
+ y = Index([QN("Sz", 0) => 2]; tags = "Y")
+
+ n = 2
+ ψn1n2 = random_itensor(l⃗[n - 1], s⃗[n], s⃗[n + 1], l⃗[n + 1], dag(x), dag(y))
+ hn1 = random_itensor(dag(h⃗[n - 1]), s⃗[n]', dag(s⃗[n]), h⃗[n], x, y)
+ hn2 = random_itensor(dag(h⃗[n]), s⃗[n + 1]', dag(s⃗[n + 1]), h⃗[n + 1])
+ ELn0 = random_itensor(l⃗[n - 1]', h⃗[n - 1], dag(l⃗[n - 1]))
+ ERn2 = random_itensor(l⃗[n + 1]', dag(h⃗[n + 1]), dag(l⃗[n + 1]))
+
+ tn = [ELn0, ψn1n2, hn1, hn2, ERn2]
+
+ R = @visualize ELn0 * ψn1n2 * hn1 * hn2 * ERn2
+ R1 = @visualize ELn0 * ψn1n2 * hn1
+ R2 = @visualize R1 * hn2 * ERn2 vertex_labels = ["T1", "T2", "T3"]
+ tn2 = @visualize tn
+ T = @visualize ELn0
+
+ @test R ≈ ELn0 * ψn1n2 * hn1 * hn2 * ERn2
+ @test R1 ≈ ELn0 * ψn1n2 * hn1
+ @test R2 ≈ ELn0 * ψn1n2 * hn1 * hn2 * ERn2
+ @test all(tn .== tn2)
+ @test T == ELn0
+
+ R = @visualize figR ELn0 * ψn1n2 * hn1 * hn2 * ERn2
+ R1 = @visualize figR1 ELn0 * ψn1n2 * hn1
+ R2 = @visualize figR2 R1 * hn2 * ERn2 vertex_labels = ["T1", "T2", "T3"]
+ T = @visualize figT T
+
+ fig_tn = @visualize_noeval tn
+
+ @test isnothing(figR)
+ @test isnothing(figR1)
+ @test isnothing(figR2)
+ @test isnothing(fig_tn)
+ @test isnothing(figT)
end
diff --git a/test/test_examples.jl b/test/test_examples.jl
index a406959..8ac41d9 100644
--- a/test/test_examples.jl
+++ b/test/test_examples.jl
@@ -1,15 +1,18 @@
using Test
+starts_and_ends_with(file, st, en) = startswith(file, st) && endswith(file, en)
+starts_and_ends_with(st, en) = file -> starts_and_ends_with(file, st, en)
+
@testset "Examples" begin
- examples_path = joinpath(@__DIR__, "..", "examples")
- example_files = filter(starts_and_ends_with("ex_", ".jl"), readdir(examples_path))
- for file in example_files
- file_path = joinpath(examples_path, file)
- println("Testing file $(file_path)")
- empty!(ARGS)
- push!(ARGS, "false")
- res = include(file_path)
- @test isnothing(res) || all(isnothing, res)
- empty!(ARGS)
- end
+ examples_path = joinpath(@__DIR__, "..", "examples")
+ example_files = filter(starts_and_ends_with("ex_", ".jl"), readdir(examples_path))
+ for file in example_files
+ file_path = joinpath(examples_path, file)
+ println("Testing file $(file_path)")
+ empty!(ARGS)
+ push!(ARGS, "false")
+ res = include(file_path)
+ @test isnothing(res) || all(isnothing, res)
+ empty!(ARGS)
+ end
end