diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..abbe2e06 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,36 @@ +# Documentation: https://github.com/JuliaCI/Appveyor.jl +environment: + matrix: + - julia_version: 1.6 + - julia_version: 1.9 + - julia_version: nightly +platform: + - x64 + - x86 +cache: + - '%USERPROFILE%\.julia\artifacts' +matrix: + allow_failures: + - julia_version: nightly +branches: + only: + - main + - master + - /release-.*/ +notifications: + - provider: Email + on_build_success: false + on_build_failure: false + on_build_status_changed: false +install: + - ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1")) +build_script: + - echo "%JL_BUILD_SCRIPT%" + - C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%" +test_script: + - echo "%JL_TEST_SCRIPT%" + - set JULIA_NUM_THREADS=2 + - C:\julia\bin\julia -e "%JL_TEST_SCRIPT%" +on_success: + - echo "%JL_CODECOV_SCRIPT%" + - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..ff6499d6 --- /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" \ No newline at end of file diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 00000000..9b007ee7 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,76 @@ +name: CI +on: + push: + branches: + - 'master' + - 'main' + - 'release-' + tags: '*' + pull_request: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - '1.6' # LTS version + - '1' # automatically expands to the latest stable 1.x release of Julia + os: + - ubuntu-latest + - macOS-latest + # - windows-latest # run on AppVeyor instead + arch: + - x64 + - x86 + exclude: + - os: macOS-latest + arch: x86 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v1 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + env: + JULIA_NUM_THREADS: 4 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v3 + with: + file: lcov.info + test-nightly: + needs: test + name: Julia nightly - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + version: + - 'nightly' + os: + - ubuntu-latest + - macOS-latest + - windows-latest + arch: + - x64 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v1 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v1 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest + env: + JULIA_NUM_THREADS: 4 diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 00000000..187a2933 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,18 @@ +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/docs.yml b/.github/workflows/Documentation.yml similarity index 60% rename from .github/workflows/docs.yml rename to .github/workflows/Documentation.yml index 7f0b3f3e..72f40322 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/Documentation.yml @@ -1,18 +1,31 @@ name: Documentation + on: push: branches: - - master + - 'master' + - 'main' + - 'release-' tags: '*' pull_request: + jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + version: + - '1' # automatically expands to the latest stable 1.x release of Julia + os: + - ubuntu-latest + arch: + - x64 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@latest with: - version: '1' + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} - name: Install dependencies run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()' - name: Build and deploy diff --git a/.github/workflows/format_check.yml b/.github/workflows/FormatCheck.yml similarity index 74% rename from .github/workflows/format_check.yml rename to .github/workflows/FormatCheck.yml index eb7d11d6..c3ed1200 100644 --- a/.github/workflows/format_check.yml +++ b/.github/workflows/FormatCheck.yml @@ -1,8 +1,9 @@ -name: format-check +name: FormatCheck on: push: branches: + - 'main' - 'master' - 'release-' tags: '*' @@ -13,15 +14,19 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - julia-version: [1] - julia-arch: [x86] - os: [ubuntu-latest] + version: + - '1' # automatically expands to the latest stable 1.x release of Julia + os: + - ubuntu-latest + arch: + - x64 steps: - uses: julia-actions/setup-julia@latest with: - version: ${{ matrix.julia-version }} + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Install JuliaFormatter and format # This will use the latest version by default but you can set the version like so: # @@ -39,4 +44,4 @@ jobs: @error "Some files have not been formatted !!!" write(stdout, out) exit(1) - end' \ No newline at end of file + end' diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index f49313b6..ec69bc9d 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,9 +1,28 @@ 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' diff --git a/.github/workflows/ci-julia-nightly.yml b/.github/workflows/ci-julia-nightly.yml deleted file mode 100644 index fe980d3d..00000000 --- a/.github/workflows/ci-julia-nightly.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: CI (Julia nightly) -on: - - push - - pull_request -jobs: - test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - version: - - 'nightly' - os: - - ubuntu-latest - - macOS-latest - - windows-latest - arch: - - x64 - steps: - - uses: actions/checkout@v3 - - uses: julia-actions/setup-julia@v1 - with: - version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/cache@v1 - - uses: julia-actions/julia-buildpkg@latest - - uses: julia-actions/julia-runtest@latest - # env: - # JULIA_NUM_THREADS: 2 - - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v3 - with: - file: lcov.info diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index afa09d8b..00000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: CI -on: - - push - - pull_request -jobs: - test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - version: - - '1.6' - - '1' - os: - - ubuntu-latest - - macOS-latest - - windows-latest - arch: - - x64 - steps: - - uses: actions/checkout@v3 - - uses: julia-actions/setup-julia@v1 - with: - version: ${{ matrix.version }} - arch: ${{ matrix.arch }} - - uses: julia-actions/cache@v1 - - uses: julia-actions/julia-buildpkg@latest - - uses: julia-actions/julia-runtest@latest - # env: - # JULIA_NUM_THREADS: 2 - - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v3 - with: - file: lcov.info diff --git a/LICENSE.md b/LICENSE.md index e43f902a..f640436b 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,22 +1,21 @@ -The TensKit.jl package is licensed under the MIT "Expat" License: +MIT License -> Copyright (c) 2019: Jutho Haegeman. -> -> 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. +Copyright (c) 2023 Jutho Haegeman and contributors + +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 9d983906..789abda8 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "TensorKit" uuid = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec" authors = ["Jutho Haegeman"] -version = "0.11.1" +version = "0.11.2" [deps] HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721" @@ -24,7 +24,7 @@ TensorKitChainRulesCoreExt = "ChainRulesCore" HalfIntegers = "1" LRUCache = "1.0.2" Strided = "2" -TensorOperations = "4.0.2" +TensorOperations = "4.0.5" TupleTools = "1.1" VectorInterface = "0.4" WignerSymbols = "1,2" diff --git a/README.md b/README.md index 04e2643b..e8c6055b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ A Julia package for large-scale tensor computations, with a hint of category the | **Build Status** | **Coverage** | **Quality assurance** | **Downloads** | |:----------------:|:------------:|:---------------------:|:--------------| -| [![CI][ci-img]][ci-url] [![CI (Julia nightly)][ci-julia-nightly-img]][ci-julia-nightly-url] | [![Codecov][codecov-img]][codecov-url] | [![Aqua QA][aqua-img]][aqua-url] | [![TensorKit Downloads][genie-img]][genie-url] | +| [![CI][ci-img]][ci-url] | [![Codecov][codecov-img]][codecov-url] | [![Aqua QA][aqua-img]][aqua-url] | [![TensorKit Downloads][genie-img]][genie-url] | [github-img]: https://github.com/Jutho/TensorKit.jl/workflows/CI/badge.svg [github-url]: https://github.com/Jutho/TensorKit.jl/actions?query=workflow%3ACI @@ -17,11 +17,6 @@ A Julia package for large-scale tensor computations, with a hint of category the [ci-img]: https://github.com/Jutho/TensorKit.jl/workflows/CI/badge.svg [ci-url]: https://github.com/Jutho/TensorKit.jl/actions?query=workflow%3ACI -[ci-julia-nightly-img]: - https://github.com/Jutho/TensorKit.jl/workflows/CI%20(Julia%20nightly)/badge.svg -[ci-julia-nightly-url]: - https://github.com/Jutho/TensorKit.jl/actions?query=workflow%3A%22CI+%28Julia+nightly%29%22 - [codecov-img]: https://codecov.io/gh/Jutho/TensorKit.jl/branch/master/graph/badge.svg [codecov-url]: https://codecov.io/gh/Jutho/TensorKit.jl diff --git a/src/auxiliary/deprecate.jl b/src/auxiliary/deprecate.jl index b9c5246d..7e282c64 100644 --- a/src/auxiliary/deprecate.jl +++ b/src/auxiliary/deprecate.jl @@ -6,4 +6,28 @@ import Base: eltype, transpose @deprecate permute(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; copy::Bool=false) permute(t, (p1, p2); copy=copy) @deprecate transpose(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; copy::Bool=false) transpose(t, (p1, p2); copy=copy) @deprecate braid(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple, levels; copy::Bool=false) braid(t, (p1, p2), levels; copy=copy) + + +Base.@deprecate(svd(t::AbstractTensorMap, leftind::IndexTuple, rightind::IndexTuple; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t, (leftind, rightind); trunc=trunc, p=p, alg=alg)) +Base.@deprecate(svd(t::AbstractTensorMap; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t; trunc=trunc, p=p, alg=alg)) +Base.@deprecate(svd!(t::AbstractTensorMap; + trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), + tsvd(t; trunc=trunc, p=p, alg=alg)) + + +# TODO: deprecate + +tsvd(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = tsvd(t, (p₁, p₂); kwargs...) +leftorth(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = leftorth(t, (p₁, p₂); kwargs...) +rightorth(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = rightorth(t, (p₁, p₂); kwargs...) +leftnull(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = leftnull(t, (p₁, p₂); kwargs...) +rightnull(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = rightnull(t, (p₁, p₂); kwargs...) +LinearAlgebra.eigen(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = LinearAlgebra.eigen(t, (p₁, p₂); kwargs...) +eig(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = eig(t, (p₁, p₂); kwargs...) +eigh(t::AbstractTensorMap, p₁::IndexTuple, p₂::IndexTuple; kwargs...) = eigh(t, (p₁, p₂); kwargs...) + #! format: on diff --git a/src/tensors/factorizations.jl b/src/tensors/factorizations.jl index 0c7a9009..15084cab 100644 --- a/src/tensors/factorizations.jl +++ b/src/tensors/factorizations.jl @@ -5,18 +5,8 @@ const OFA = OrthogonalFactorizationAlgorithm import LinearAlgebra: svd!, svd const SVDAlg = Union{SVD,SDD} -Base.@deprecate(svd(t::AbstractTensorMap, leftind::IndexTuple, rightind::IndexTuple; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t, leftind, rightind; trunc=trunc, p=p, alg=alg)) -Base.@deprecate(svd(t::AbstractTensorMap; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t; trunc=trunc, p=p, alg=alg)) -Base.@deprecate(svd!(t::AbstractTensorMap; - trunc::TruncationScheme=notrunc(), p::Real=2, alg::SVDAlg=SDD()), - tsvd(t; trunc=trunc, p=p, alg=alg)) - """ - tsvd(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + tsvd(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; trunc::TruncationScheme = notrunc(), p::Real = 2, alg::Union{SVD, SDD} = SDD()) -> U, S, V, ϵ @@ -47,12 +37,12 @@ algorithm that computes the decomposition (`_gesvd` or `_gesdd`). Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `tsvd(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function tsvd(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return tsvd!(permute(t, (p1, p2); copy=true); kwargs...) +function tsvd(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return tsvd!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - leftorth(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + leftorth(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = QRpos()) -> Q, R Create orthonormal basis `Q` for indices in `leftind`, and remainder `R` such that @@ -73,12 +63,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `leftorth(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function leftorth(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return leftorth!(permute(t, (p1, p2); copy=true); kwargs...) +function leftorth(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return leftorth!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - rightorth(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple; + rightorth(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = LQpos()) -> L, Q Create orthonormal basis `Q` for indices in `rightind`, and remainder `L` such that @@ -101,12 +91,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `rightorth(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function rightorth(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return rightorth!(permute(t, (p1, p2); copy=true); kwargs...) +function rightorth(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return rightorth!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - leftnull(t::AbstractTensor, leftind::Tuple, rightind::Tuple; + leftnull(t::AbstractTensor, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = QRpos()) -> N Create orthonormal basis for the orthogonal complement of the support of the indices in @@ -127,12 +117,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `leftnull(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function leftnull(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return leftnull!(permute(t, (p1, p2); copy=true); kwargs...) +function leftnull(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return leftnull!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - rightnull(t::AbstractTensor, leftind::Tuple, rightind::Tuple; + rightnull(t::AbstractTensor, (leftind, rightind)::Index2Tuple; alg::OrthogonalFactorizationAlgorithm = LQ(), atol::Real = 0.0, rtol::Real = eps(real(float(one(scalartype(t)))))*iszero(atol)) -> N @@ -155,12 +145,12 @@ Orthogonality requires `InnerProductStyle(t) <: HasInnerProduct`, and `rightnull(!)` is currently only implemented for `InnerProductStyle(t) === EuclideanProduct()`. """ -function rightnull(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return rightnull!(permute(t, (p1, p2); copy=true); kwargs...) +function rightnull(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return rightnull!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eigen(t::AbstractTensor, leftind::Tuple, rightind::Tuple; kwargs...) -> D, V + eigen(t::AbstractTensor, (leftind, rightind)::Index2Tuple; kwargs...) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. @@ -178,13 +168,13 @@ matrices. See the corresponding documentation for more information. See also `eig` and `eigh` """ -function LinearAlgebra.eigen(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; +function LinearAlgebra.eigen(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) - return eigen!(permute(t, (p1, p2); copy=true); kwargs...) + return eigen!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eig(t::AbstractTensor, leftind::Tuple, rightind::Tuple; kwargs...) -> D, V + eig(t::AbstractTensor, (leftind, rightind)::Index2Tuple; kwargs...) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. The function `eig` assumes that the linear map is not hermitian and returns type stable @@ -204,12 +194,12 @@ Accepts the same keyword arguments `scale`, `permute` and `sortby` as `eigen` of See also `eigen` and `eigh`. """ -function eig(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; kwargs...) - return eig!(permute(t, (p1, p2); copy=true); kwargs...) +function eig(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple; kwargs...) + return eig!(permute(t, (p₁, p₂); copy=true); kwargs...) end """ - eigh(t::AbstractTensorMap, leftind::Tuple, rightind::Tuple) -> D, V + eigh(t::AbstractTensorMap, (leftind, rightind)::Index2Tuple) -> D, V Compute eigenvalue factorization of tensor `t` as linear map from `rightind` to `leftind`. The function `eigh` assumes that the linear map is hermitian and `D` and `V` tensors with @@ -228,12 +218,12 @@ permute(t, (leftind, rightind)) * V = V * D See also `eigen` and `eig`. """ -function eigh(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple) - return eigh!(permute(t, (p1, p2); copy=true)) +function eigh(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple) + return eigh!(permute(t, (p₁, p₂); copy=true)) end """ - isposdef(t::AbstractTensor, leftind::Tuple, rightind::Tuple) -> ::Bool + isposdef(t::AbstractTensor, (leftind, rightind)::Index2Tuple) -> ::Bool Test whether a tensor `t` is positive definite as linear map from `rightind` to `leftind`. @@ -241,13 +231,10 @@ If `leftind` and `rightind` are not specified, the current partition of left and indices of `t` is used. In that case, less memory is allocated if one allows the data in `t` to be destroyed/overwritten, by using `isposdef!(t)`. Note that the permuted tensor on which `isposdef!` is called should have equal domain and codomain, as otherwise it is -meaningless - -Accepts the same keyword arguments `scale`, `permute` and `sortby` as `eigen` of dense -matrices. See the corresponding documentation for more information. +meaningless. """ -function LinearAlgebra.isposdef(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple) - return isposdef!(permute(t, (p1, p2); copy=true)) +function LinearAlgebra.isposdef(t::AbstractTensorMap, (p₁, p₂)::Index2Tuple) + return isposdef!(permute(t, (p₁, p₂); copy=true)) end function tsvd(t::AbstractTensorMap; trunc::TruncationScheme=NoTruncation(), diff --git a/src/tensors/indexmanipulations.jl b/src/tensors/indexmanipulations.jl index 6b91145b..9dea8d58 100644 --- a/src/tensors/indexmanipulations.jl +++ b/src/tensors/indexmanipulations.jl @@ -340,20 +340,6 @@ function _add_general_kernel!(tdst, tsrc, p, fusiontreetransform, α, β, backen end end end - - # if Threads.nthreads() > 1 - # Threads.@sync for s₁ in sectors(codomain(tsrc)), s₂ in sectors(domain(tsrc)) - # _add_sectors!(tdst, tsrc, fusiontreemap, s₁, s₂, α, β, backend...) - # end - # else - # for (f₁, f₂) in fusiontrees(tsrc) - # for ((f₁′, f₂′), coeff) in fusiontreetransform(f₁, f₂) - # TO.tensoradd!(tdst[f₁′, f₂′], p, tsrc[f₁, f₂], :N, α * coeff, true, - # backend...) - # end - # end - # end - return nothing end diff --git a/src/tensors/linalg.jl b/src/tensors/linalg.jl index 757363f8..c66be7e4 100644 --- a/src/tensors/linalg.jl +++ b/src/tensors/linalg.jl @@ -390,8 +390,8 @@ end function catdomain(t1::AbstractTensorMap{S,N₁,1}, t2::AbstractTensorMap{S,N₁,1}) where {S,N₁} codomain(t1) == codomain(t2) || - throw(SpaceMismatch("codomains of tensors to concatenate must match:\n\ - $(codomain(t1)) ≠ $(codomain(t2))")) + throw(SpaceMismatch("codomains of tensors to concatenate must match:\n" * + "$(codomain(t1)) ≠ $(codomain(t2))")) V1, = domain(t1) V2, = domain(t2) isdual(V1) == isdual(V2) || @@ -408,9 +408,8 @@ end function catcodomain(t1::AbstractTensorMap{S,1,N₂}, t2::AbstractTensorMap{S,1,N₂}) where {S,N₂} domain(t1) == domain(t2) || - throw(SpaceMismatch("domains of tensors to concatenate must match:\n\ - $(domain(t1)) ≠ $(domain(t2))")) - + throw(SpaceMismatch("domains of tensors to concatenate must match:\n" * + "$(domain(t1)) ≠ $(domain(t2))")) V1, = codomain(t1) V2, = codomain(t2) isdual(V1) == isdual(V2) || diff --git a/src/tensors/tensoroperations.jl b/src/tensors/tensoroperations.jl index 1e3dfd42..bc89bbd8 100644 --- a/src/tensors/tensoroperations.jl +++ b/src/tensors/tensoroperations.jl @@ -188,7 +188,7 @@ function trace_permute!(tdst::AbstractTensorMap{S,N₁,N₂}, cod = codomain(tsrc) dom = domain(tsrc) n = length(cod) - VectorInterface.scale!(tdst, β) + scale!(tdst, β) r₁ = (p₁..., q₁...) r₂ = (p₂..., q₂...) for (f₁, f₂) in fusiontrees(tsrc) diff --git a/test/tensors.jl b/test/tensors.jl index 0a1d8edf..b6d7b6db 100644 --- a/test/tensors.jl +++ b/test/tensors.jl @@ -347,7 +347,7 @@ for V in spacelist TensorKit.QL(), TensorKit.QLpos(), TensorKit.Polar(), TensorKit.SVD(), TensorKit.SDD()) - Q, R = @constinferred leftorth(t, (3, 4, 2), (1, 5); alg=alg) + Q, R = @constinferred leftorth(t, ((3, 4, 2), (1, 5)); alg=alg) QdQ = Q' * Q @test QdQ ≈ one(QdQ) @test Q * R ≈ permute(t, ((3, 4, 2), (1, 5))) @@ -359,7 +359,7 @@ for V in spacelist @testset "leftnull with $alg" for alg in (TensorKit.QR(), TensorKit.SVD(), TensorKit.SDD()) - N = @constinferred leftnull(t, (3, 4, 2), (1, 5); alg=alg) + N = @constinferred leftnull(t, ((3, 4, 2), (1, 5)); alg=alg) NdN = N' * N @test NdN ≈ one(NdN) @test norm(N' * permute(t, ((3, 4, 2), (1, 5)))) < @@ -370,7 +370,7 @@ for V in spacelist TensorKit.LQ(), TensorKit.LQpos(), TensorKit.Polar(), TensorKit.SVD(), TensorKit.SDD()) - L, Q = @constinferred rightorth(t, (3, 4), (2, 1, 5); alg=alg) + L, Q = @constinferred rightorth(t, ((3, 4), (2, 1, 5)); alg=alg) QQd = Q * Q' @test QQd ≈ one(QQd) @test L * Q ≈ permute(t, ((3, 4), (2, 1, 5))) @@ -382,14 +382,14 @@ for V in spacelist @testset "rightnull with $alg" for alg in (TensorKit.LQ(), TensorKit.SVD(), TensorKit.SDD()) - M = @constinferred rightnull(t, (3, 4), (2, 1, 5); alg=alg) + M = @constinferred rightnull(t, ((3, 4), (2, 1, 5)); alg=alg) MMd = M * M' @test MMd ≈ one(MMd) @test norm(permute(t, ((3, 4), (2, 1, 5))) * M') < 100 * eps(norm(t)) end @testset "tsvd with $alg" for alg in (TensorKit.SVD(), TensorKit.SDD()) - U, S, V = @constinferred tsvd(t, (3, 4, 2), (1, 5); alg=alg) + U, S, V = @constinferred tsvd(t, ((3, 4, 2), (1, 5)); alg=alg) UdU = U' * U @test UdU ≈ one(UdU) VVd = V * V' @@ -440,8 +440,8 @@ for V in spacelist t = Tensor(rand, T, V1 ⊗ V1' ⊗ V2 ⊗ V2') @testset "eig and isposdef" begin - D, V = eigen(t, (1, 3), (2, 4)) - D̃, Ṽ = @constinferred eig(t, (1, 3), (2, 4)) + D, V = eigen(t, ((1, 3), (2, 4))) + D̃, Ṽ = @constinferred eig(t, ((1, 3), (2, 4))) @test D ≈ D̃ @test V ≈ Ṽ VdV = V' * V