Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress towards a version 1 #135

Merged
merged 14 commits into from
Jul 18, 2024
Merged
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, isqrtdim, 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(isqrtdim, (I,))
lkdvos marked this conversation as resolved.
Show resolved Hide resolved
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