Skip to content

Commit

Permalink
Progress towards a version 1 (#135)
Browse files Browse the repository at this point in the history
* Add .vscode to gitignore

* Add changelog.md

* Change type signature: `AbstractTensorMap{<:Number,<:IndexSpace,N1,N2}` (#1)

* Add scalartype parameter to `AbstractTensorMap`

* Add scalartype in definition of TensorMap

* Add scalartype to AdjointTensorMap

* Add scalartype to BraidingTensor

* Implement changes for indexmanipulations

* Implement scalartype for linalg

* implement changes for tensoroperations

* implement changes for planaroperations

* implement changes for ChainRules

* small fixes

* Fix typo

* Fix missing change

* Formatter

* Apply scalartype changes to tests

* Fix some ambiguities

* De-specialize `trace_permute`

* Despecialize `_contract!`

* Remove unused type-parameter

* Despecialize `planaradd!` and `planartrace!`

* Small fixes

* Change braidingtensor syntax to resolve ambiguities

* despecialize some linalg methods

* formatter

* Add changelog entry

* Fix ambiguity on Julia1.6

* Update Changelog.md

* Change `copy(BraidingTensor)` to return a `BraidingTensor` (#2)

This changes the behaviour of copy as an instantiator for creating a TensorMap from a BraidingTensor.
The rationale is that while this does sometimes happen in Julia Base, this is always in the context of lazy wrapper types, for which it makes sense to not copy the parent and then create a new wrapper. BraidingTensor does not wrap anything, so this definition makes less sense.

* Move sectors to separate module (#3)

* Split Sectors module

* convert submodule into its own module

* Organize tests

* Add precompile statements

* Add non-unicode alternative `fusionproduct` for `⊗`

* Add `directproduct` for `×`

* split "trivial.jl"

* Formatter

* Change unicode alternatives to `otimes` and `times`

Incorporate changes from #aada0b2

* Update some testset descriptions

* Resolve method ambiguities

* Change some formatting

* Import local version of `TensorKitSectors`

* Enable TensorKitSectors github action

* Switch to local include for CI

* Remove `NewSU2Sector` tests from main package

* Refactor sectors to group Fsymbol and Rsymbol operations

* Update CI Sectors to only trigger when files are changed in that path

* fix and improve copy(::BraidingTensor) (#5)

* copy entire template and stop using copy(b.V1), copy(b.V2) as they do not work

* formatting

* Refactor TensorMap constructors (#6)

- Refactored `TensorMap` constructors to be in line with `Array` counterparts:
```julia
TensorMap{E}(undef, codomain, domain) # + some variants
```
- Added support for `zeros`, `ones`, `rand`, and `randn`.
- Streamlined the interface for these functions, along with `isomorphism`, `unitary` and `isometry` into the form:
```julia
function([T], codomain, domain) # + some variants
```

* Update TensorOperations v5 compatibility (#7)

* Update TensorOperations v5 compatibility

* Manually add unreleased TensorOperations version

* Update CI.yml

* Revert tensoroperations v5 attempts

* Changes to incorporate v5

* Remove manual installation of TensorOperations in docs CI

[no ci]

* Update changelog [no ci]

* Address review comments

* Rename `isqrtdim` -> `invsqrtdim`

* `T` is scalartype, `TT` is tensortype

---------

Co-authored-by: Jutho <[email protected]>
Co-authored-by: Victor Vanthilt <[email protected]>
  • Loading branch information
3 people committed Jul 18, 2024
1 parent 86fd357 commit 62597cb
Show file tree
Hide file tree
Showing 46 changed files with 1,747 additions and 1,244 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/CI-Sectors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: CI - TensorKitSectors
on:
push:
branches:
- 'master'
- 'main'
- 'release-'
paths:
- TensorKitSectors/
tags: '*'
pull_request:
paths:
- TensorKitSectors/
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: TensorKitSectors - ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- '1' # automatically expands to the latest stable 1.x release of Julia
os:
- ubuntu-latest
arch:
- x64
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v1
- uses: julia-actions/julia-buildpkg@latest
with:
project: TensorKitSectors
- uses: julia-actions/julia-runtest@latest
with:
project: TensorKitSectors
env:
JULIA_NUM_THREADS: 4
- uses: julia-actions/julia-processcoverage@v1
- uses: codecov/codecov-action@v4
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
file: lcov.info
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6' # LTS version
- '1.8' # LTS version
- '1' # automatically expands to the latest stable 1.x release of Julia
os:
- ubuntu-latest
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
*-old
__pycache__
.ipynb*
Manifest.toml
Manifest.toml
.vscode
44 changes: 44 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Planned changes for v1.0

Features that are planned to be implemented before the release of v1.0.0, in no particular order.

- [x] Separate `Sectors` module
- [ ] Make `TrivialTensorMap` and `TensorMap` be the same
- [ ] Simplify `TensorMap` type to hide `rowr` and `colr`
- [ ] Change block order in `rowr` / `colr` to speed up particular contractions
- [ ] Make `AdjointTensorMap` generic
- [ ] Rewrite planar operations in order to be AD-compatible
- [x] Fix rrules for fermionic tensors
- [ ] Fix GPU support
- [ ] Proper threading support
- [ ] Rewrite documentation

# Changelog

### `AbstractTensorMap{E,S,N₁,N₂}`

This adds the scalar type as a parameter to the `AbstractTensorMap` type. This is useful in
the contexts where different types of tensors are used (`AdjointTensor`, `BraidingTensor`,
...), which still have the same scalartype. Additionally, this removes many specializations
for methods in order to reduce ambiguity errors.

### `copy(BraidingTensor)`

This PR changes the behaviour of `copy` as an instantiator for creating a `TensorMap` from a
`BraidingTensor`. The rationale is that while this does sometimes happen in Julia `Base`,
this is always in the context of lazy wrapper types, for which it makes sense to not copy
the parent and then create a new wrapper. `BraidingTensor` does not wrap anything, so this
definition makes less sense.

### Refactor tensormap constructors

This PR refactors the constructors for `TensorMap` to be more in line with `Array`
constructors in Julia. In particular, this means that the default way to create
uninitialized tensors is now `TensorMap{E}(undef, codomain ← domain)`, reminiscent of
`Array{E}(undef, dims)`. Several convenience constructors are also added: `ones`, `zeros`,
`rand` and `randn` construct tensors when `dims` is replaced by `domain ← codomain`.

### TensorOperations v5

This PR bumps the compatibility of `TensorOperations` to v5. This is a breaking change
as there are some changes in the API.
8 changes: 4 additions & 4 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
name = "TensorKit"
uuid = "07d1fe3e-3e46-537d-9eac-e9e13d0d4cec"
authors = ["Jutho Haegeman"]
version = "0.12.5"
version = "1.0.0-DEV"

[deps]
HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721"
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PackageExtensionCompat = "65ce6f38-6b18-4e1d-a461-8949797d7930"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Strided = "5e0ebb24-38b0-5f93-81fe-25c709ecae67"
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6"
Expand All @@ -34,7 +35,7 @@ LinearAlgebra = "1"
PackageExtensionCompat = "1"
Random = "1"
Strided = "2"
TensorOperations = "4.1"
TensorOperations = "5"
Test = "1"
TestExtras = "0.2"
TupleTools = "1.1"
Expand All @@ -50,11 +51,10 @@ Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestExtras = "5ed8adda-3752-4e41-b88a-e8b09835ee3a"
WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b"

[targets]
test = ["Aqua", "Combinatorics", "HalfIntegers", "LinearAlgebra", "Random", "TensorOperations", "Test", "TestExtras", "WignerSymbols", "ChainRulesCore", "ChainRulesTestUtils", "FiniteDifferences"]
test = ["Aqua", "Combinatorics", "HalfIntegers", "LinearAlgebra", "TensorOperations", "Test", "TestExtras", "WignerSymbols", "ChainRulesCore", "ChainRulesTestUtils", "FiniteDifferences"]
21 changes: 21 additions & 0 deletions TensorKitSectors/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name = "TensorKitSectors"
uuid = "7ea117e4-0799-4282-ac6e-748b4bc2d0f5"
authors = ["Jutho Haegeman", "Lukas Devos"]
version = "0.1.0"

[deps]
HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b"

[extras]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
TensorOperations = "6aa20fa7-93e2-5fca-9bc0-fbd0db3c71a2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestExtras = "5ed8adda-3752-4e41-b88a-e8b09835ee3a"
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"

[targets]
test = ["Test", "TestExtras", "TestItemRunner", "TensorOperations", "Random", "Reexport"]
68 changes: 68 additions & 0 deletions TensorKitSectors/src/TensorKitSectors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Superselection sectors (quantum numbers):
# for defining graded vector spaces and invariant subspaces of tensor products
#==========================================================================================#

module TensorKitSectors

# exports
# -------
export Sector, Group, AbstractIrrep
export Irrep

export Nsymbol, Fsymbol, Rsymbol, Asymbol, Bsymbol
export dim, sqrtdim, invsqrtdim, frobeniusschur, twist, fusiontensor, dual
export otimes, deligneproduct, times
export FusionStyle, UniqueFusion, MultipleFusion, SimpleFusion, GenericFusion,
MultiplicityFreeFusion
export BraidingStyle, NoBraiding, SymmetricBraiding, Bosonic, Fermionic, Anyonic
export SectorSet, SectorValues, findindex, vertex_ind2label, vertex_labeltype

export pentagon_equation, hexagon_equation

export Trivial, Z2Irrep, Z3Irrep, Z4Irrep, ZNIrrep, U1Irrep, SU2Irrep, CU1Irrep
export ProductSector
export FermionParity, FermionNumber, FermionSpin
export PlanarTrivial, FibonacciAnyon, IsingAnyon

# unicode exports
# ---------------
export , , ×
export ℤ, ℤ₂, ℤ₃, ℤ₄, U₁, SU, SU₂, CU₁
export fℤ₂, fU₁, fSU₂

# imports
# -------
using Base: SizeUnknown, HasLength, IsInfinite
using Base: HasEltype, EltypeUnknown
using Base.Iterators: product, filter
using Base: tuple_type_head, tuple_type_tail

using LinearAlgebra: tr
using TensorOperations
using HalfIntegers
using WignerSymbols

# includes
# --------
include("auxiliary.jl")
include("sectors.jl")
include("trivial.jl")
include("groups.jl")
include("irreps.jl") # irreps of symmetry groups, with bosonic braiding
include("product.jl") # direct product of different sectors
include("fermions.jl") # irreps with defined fermionparity and fermionic braiding
include("anyons.jl") # non-group sectors

# precompile
# ----------
include("precompile.jl")

function __precompile__()
for I in (Trivial, Z2Irrep, Z3Irrep, Z4Irrep, ZNIrrep, U1Irrep, SU2Irrep, CU1Irrep,
FermionParity, FermionNumber, FermionSpin, PlanarTrivial, FibonacciAnyon,
IsingAnyon)
precompile_sector(I)
end
end

end # module TensorKitSectors
File renamed without changes.
15 changes: 15 additions & 0 deletions TensorKitSectors/src/auxiliary.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# kronecker product with arbitrary number of dimensions
_kron(A, B, C, D...) = _kron(_kron(A, B), C, D...)
function _kron(A, B)
sA = size(A)
sB = size(B)
s = map(*, sA, sB)
C = similar(A, promote_type(eltype(A), eltype(B)), s)
for IA in eachindex(IndexCartesian(), A)
for IB in eachindex(IndexCartesian(), B)
I = CartesianIndex(IB.I .+ (IA.I .- 1) .* sB)
C[I] = A[IA] * B[IB]
end
end
return C
end
File renamed without changes.
10 changes: 10 additions & 0 deletions src/sectors/groups.jl → TensorKitSectors/src/groups.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,21 @@ type_repr(::Type{ℤ₂}) = "ℤ₂"
type_repr(::Type{ℤ₃}) = "ℤ₃"
type_repr(::Type{ℤ₄}) = "ℤ₄"
type_repr(::Type{SU₂}) = "SU₂"
type_repr(T::Type) = repr(T)

const GroupTuple = Tuple{Vararg{Group}}

abstract type ProductGroup{T<:GroupTuple} <: Group end

"""
×(G::Vararg{Type{<:Group}}) -> ProductGroup{Tuple{G...}}
times(G::Vararg{Type{<:Group}}) -> ProductGroup{Tuple{G...}}
Construct the direct product of a (list of) groups.
"""
function ×(::Vararg{Type{<:Group}}) end
const times = ×

×(a::Type{<:Group}, b::Type{<:Group}, c::Type{<:Group}...) = ×(×(a, b), c...)
×(G::Type{<:Group}) = ProductGroup{Tuple{G}}
×(G1::Type{ProductGroup{Tuple{}}},
Expand Down
File renamed without changes.
32 changes: 32 additions & 0 deletions TensorKitSectors/src/precompile.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""
precompile_sector(I::Type{<:Sector})
Precompile common methods for the given sector type.
"""
function precompile_sector(::Type{I}) where {I<:Sector}
precompile(Nsymbol, (I, I, I))
precompile(Fsymbol, (I, I, I, I, I, I))
precompile(Rsymbol, (I, I, I))
precompile(Asymbol, (I, I, I))
precompile(Bsymbol, (I, I, I))

precompile(, (I,))
precompile(, (I, I))
precompile(, (I, I, I))
precompile(, (I, I, I, I))

precompile(FusionStyle, (I,))
precompile(BraidingStyle, (I,))

precompile(dim, (I,))
precompile(sqrtdim, (I,))
precompile(invsqrtdim, (I,))
precompile(dual, (I,))
precompile(twist, (I,))
precompile(frobeniusschur, (I,))

try
precompile(fusiontensor, (I, I, I))
catch
end
end
3 changes: 1 addition & 2 deletions src/sectors/product.jl → TensorKitSectors/src/product.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function Nsymbol(a::P, b::P, c::P) where {P<:ProductSector}
end

_firstsector(x::ProductSector) = x.sectors[1]
_tailsector(x::ProductSector) = ProductSector(tail(x.sectors))
_tailsector(x::ProductSector) = ProductSector(Base.tail(x.sectors))

function Fsymbol(a::P, b::P, c::P, d::P, e::P, f::P) where {P<:ProductSector}
heads = map(_firstsector, (a, b, c, d, e, f))
Expand Down Expand Up @@ -196,7 +196,6 @@ group representations, we have `Irrep[G₁] ⊠ Irrep[G₂] == Irrep[G₁ × G
(s1::Sector, p2::ProductSector) = ProductSector(tuple(s1, p2.sectors...))
(p1::ProductSector, p2::ProductSector) = ProductSector(tuple(p1.sectors..., p2.sectors...))

# grow types from the left using Base.tuple_type_cons
(I1::Type{Trivial}, I2::Type{Trivial}) = Trivial
(I1::Type{Trivial}, I2::Type{<:ProductSector}) = I2
(I1::Type{Trivial}, I2::Type{<:Sector}) = I2
Expand Down
Loading

0 comments on commit 62597cb

Please sign in to comment.