Skip to content

Commit

Permalink
Merge branch 'master' into test-rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
lkdvos committed Oct 5, 2023
2 parents 97ab153 + ec40cea commit e2e2984
Show file tree
Hide file tree
Showing 19 changed files with 226 additions and 255 deletions.
36 changes: 0 additions & 36 deletions .appveyor.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
os:
- ubuntu-latest
- macOS-latest
# - windows-latest # run on AppVeyor instead
- windows-latest
arch:
- x64
- x86
Expand Down
3 changes: 2 additions & 1 deletion src/TensorKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export ZNSpace, Z2Space, Z3Space, Z4Space, U1Space, CU1Space, SU2Space
export Vect, Rep # space constructors
export CompositeSpace, ProductSpace # composite spaces
export FusionTree
export IndexSpace, TensorSpace, AbstractTensorMap, AbstractTensor, TensorMap, Tensor # tensors and tensor properties
export IndexSpace, TensorSpace, TensorMapSpace
export AbstractTensorMap, AbstractTensor, TensorMap, Tensor, TrivialTensorMap # tensors and tensor properties
export TruncationScheme
export SpaceMismatch, SectorMismatch, IndexError # error types

Expand Down
4 changes: 1 addition & 3 deletions src/auxiliary/deprecate.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import Base: eltype, transpose
@deprecate eltype(T::Type{<:AbstractTensorMap}) scalartype(T)
@deprecate eltype(t::AbstractTensorMap) scalartype(t)
import Base: transpose

#! format: off
@deprecate permute(t::AbstractTensorMap, p1::IndexTuple, p2::IndexTuple; copy::Bool=false) permute(t, (p1, p2); copy=copy)
Expand Down
16 changes: 7 additions & 9 deletions src/fusiontrees/manipulations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,12 @@ function bendright(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}) where {I<
isdual2 = (f₂.isdual..., !(f₁.isdual[N₁]))
inner2 = N₂ > 1 ? (f₂.innerlines..., c) : ()

coeff₀ = sqrtdim(c) * isqrtdim(a)
if f₁.isdual[N₁]
coeff₀ *= conj(frobeniusschur(dual(b)))
end
if FusionStyle(I) isa MultiplicityFreeFusion
coeff = sqrtdim(c) * isqrtdim(a) * Bsymbol(a, b, c)
if f₁.isdual[N₁]
coeff *= conj(frobeniusschur(dual(b)))
end
coeff = coeff₀ * Bsymbol(a, b, c)
vertices2 = N₂ > 0 ? (f₂.vertices..., nothing) : ()
f₂′ = FusionTree(uncoupled2, a, isdual2, inner2, vertices2)
return SingletonDict((f₁′, f₂′) => coeff)
Expand All @@ -266,11 +267,8 @@ function bendright(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}) where {I<
Bmat = Bsymbol(a, b, c)
μ = N₁ > 1 ? f₁.vertices[end] : 1
for ν in 1:size(Bmat, 2)
coeff = sqrtdim(c) * isqrtdim(a) * Bmat[μ, ν]
coeff = coeff₀ * Bmat[μ, ν]
iszero(coeff) && continue
if f₁.isdual[N₁]
coeff *= conj(frobeniusschur(dual(b)))
end
vertices2 = N₂ > 0 ? (f₂.vertices..., ν) : ()
f₂′ = FusionTree(uncoupled2, a, isdual2, inner2, vertices2)
if @isdefined newtrees
Expand Down Expand Up @@ -332,7 +330,7 @@ function foldright(f₁::FusionTree{I,N₁}, f₂::FusionTree{I,N₂}) where {I<
vertices = N₁ <= 2 ? () : Base.tail(Base.tail(fl′.vertices))
fl = FusionTree{I}(uncoupled, coupled, isdual, inner, vertices)
for (fr, coeff2) in insertat(fc, 2, f₂)
coeff = factor * coeff1 * coeff2
coeff = factor * coeff1 * conj(coeff2)
if (@isdefined newtrees)
newtrees[(fl, fr)] = get(newtrees, (fl, fr), zero(coeff)) +
coeff
Expand Down
6 changes: 4 additions & 2 deletions src/spaces/cartesianspace.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""
struct CartesianSpace <: ElementarySpace{ℝ}
struct CartesianSpace <: ElementarySpace
A real Euclidean space `ℝ^d`, which is therefore self-dual. `CartesianSpace` has no
additonal structure and is completely characterised by its dimension `d`. This is the
vector space that is implicitly assumed in most of matrix algebra.
"""
struct CartesianSpace <: ElementarySpace{ℝ}
struct CartesianSpace <: ElementarySpace
d::Int
end
CartesianSpace(d::Integer=0; dual=false) = CartesianSpace(Int(d))
Expand All @@ -28,8 +28,10 @@ function CartesianSpace(dims::AbstractDict; kwargs...)
end
end

field(::Type{CartesianSpace}) =
InnerProductStyle(::Type{CartesianSpace}) = EuclideanProduct()

Base.conj(V::CartesianSpace) = V
isdual(V::CartesianSpace) = false

# convenience constructor
Expand Down
5 changes: 3 additions & 2 deletions src/spaces/complexspace.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""
struct ComplexSpace <: ElementarySpace{ℂ}
struct ComplexSpace <: ElementarySpace
A standard complex vector space ℂ^d with Euclidean inner product and no additional
structure. It is completely characterised by its dimension and whether its the normal space
or its dual (which is canonically isomorphic to the conjugate space).
"""
struct ComplexSpace <: ElementarySpace{ℂ}
struct ComplexSpace <: ElementarySpace
d::Int
dual::Bool
end
Expand All @@ -29,6 +29,7 @@ function ComplexSpace(dims::AbstractDict; kwargs...)
end
end

field(::Type{ComplexSpace}) =
InnerProductStyle(::Type{ComplexSpace}) = EuclideanProduct()

# convenience constructor
Expand Down
34 changes: 24 additions & 10 deletions src/spaces/deligne.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,66 @@ The Deligne tensor product also works in the type domain and for sectors and ten
group representations, we have `Rep[G₁] ⊠ Rep[G₂] == Rep[G₁ × G₂]`, i.e. these are the
natural representation spaces of the direct product of two groups.
"""
(V₁::VectorSpace, V₂::VectorSpace) = (V₁ one(V₂)) (one(V₁) V₂)
function (V₁::VectorSpace, V₂::VectorSpace)
field(V₁) == field(V₂) || throw_incompatible_fields(V₁, V₂)
return (V₁ one(V₂)) (one(V₁) V₂)
end

# define deligne products with empty tensor product: just add a trivial sector of the type of the empty space to each of the sectors in the non-empty space
function (V::GradedSpace, P₀::ProductSpace{<:ElementarySpace{ℂ},0})
# define deligne products with empty tensor product: just add a trivial sector of the type
# of the empty space to each of the sectors in the non-empty space
function (V::GradedSpace, P₀::ProductSpace{<:ElementarySpace,0})
field(V) == field(P₀) || throw_incompatible_fields(V, P₀)
I₁ = sectortype(V)
I₂ = sectortype(P₀)
return Vect[I₁ I₂](ifelse(isdual(V), dual(c), c) one(I₂) => dim(V, c)
for c in sectors(V); dual=isdual(V))
end

function (P₀::ProductSpace{<:ElementarySpace{ℂ},0}, V::GradedSpace)
function (P₀::ProductSpace{<:ElementarySpace,0}, V::GradedSpace)
field(P₀) == field(V) || throw_incompatible_fields(P₀, V)
I₁ = sectortype(P₀)
I₂ = sectortype(V)
return Vect[I₁ I₂](one(I₁) ifelse(isdual(V), dual(c), c) => dim(V, c)
for c in sectors(V); dual=isdual(V))
end

function (V::ComplexSpace, P₀::ProductSpace{<:ElementarySpace{ℂ},0})
function (V::ComplexSpace, P₀::ProductSpace{<:ElementarySpace,0})
field(V) == field(P₀) || throw_incompatible_fields(V, P₀)
I₂ = sectortype(P₀)
return Vect[I₂](one(I₂) => dim(V); dual=isdual(V))
end

function (P₀::ProductSpace{<:ElementarySpace{ℂ},0}, V::ComplexSpace)
function (P₀::ProductSpace{<:ElementarySpace,0}, V::ComplexSpace)
field(P₀) == field(V) || throw_incompatible_fields(P₀, V)
I₁ = sectortype(P₀)
return Vect[I₁](one(I₁) => dim(V); dual=isdual(V))
end

function (P::ProductSpace{<:ElementarySpace{ℂ},0},
P₀::ProductSpace{<:ElementarySpace{ℂ},0})
function (P::ProductSpace{<:ElementarySpace,0}, P₀::ProductSpace{<:ElementarySpace,0})
field(P) == field(P₀) || throw_incompatible_fields(P, P₀)
I₁ = sectortype(P)
I₂ = sectortype(P₀)
return one(Vect[I₁ I₂])
end

function (P::ProductSpace{<:ElementarySpace{ℂ}}, P₀::ProductSpace{<:ElementarySpace{ℂ},0})
function (P::ProductSpace{<:ElementarySpace}, P₀::ProductSpace{<:ElementarySpace,0})
field(P) == field(P₀) || throw_incompatible_fields(P, P₀)
I₁ = sectortype(P)
I₂ = sectortype(P₀)
S = Vect[I₁ I₂]
N = length(P)
return ProductSpace{S,N}(map(V -> V P₀, tuple(P...)))
end

function (P₀::ProductSpace{<:ElementarySpace{ℂ},0}, P::ProductSpace{<:ElementarySpace{ℂ}})
function (P₀::ProductSpace{<:ElementarySpace,0}, P::ProductSpace{<:ElementarySpace})
field(P₀) == field(P) || throw_incompatible_fields(P₀, P)
I₁ = sectortype(P₀)
I₂ = sectortype(P)
S = Vect[I₁ I₂]
N = length(P)
return ProductSpace{S,N}(map(V -> P₀ V, tuple(P...)))
end

@noinline function throw_incompatible_fields(P₁, P₂)
throw(ArgumentError("Deligne products require spaces over the same field: $(field(P₁))$(field(P₂))"))
end
5 changes: 3 additions & 2 deletions src/spaces/generalspace.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""
struct GeneralSpace{𝕜} <: ElementarySpace{𝕜}
struct GeneralSpace{𝕜} <: ElementarySpace
A finite-dimensional space over an arbitrary field `𝕜` without additional structure.
It is thus characterized by its dimension, and whether or not it is the dual and/or
conjugate space. For a real field `𝕜`, the space and its conjugate are the same.
"""
struct GeneralSpace{𝕜} <: ElementarySpace{𝕜}
struct GeneralSpace{𝕜} <: ElementarySpace
d::Int
dual::Bool
conj::Bool
Expand All @@ -29,6 +29,7 @@ isconj(V::GeneralSpace) = V.conj

Base.axes(V::GeneralSpace) = Base.OneTo(dim(V))

field(::Type{GeneralSpace{𝕜}}) where {𝕜} = 𝕜
InnerProductStyle(::Type{<:GeneralSpace}) = NoInnerProduct()

dual(V::GeneralSpace{𝕜}) where {𝕜} = GeneralSpace{𝕜}(dim(V), !isdual(V), isconj(V))
Expand Down
5 changes: 3 additions & 2 deletions src/spaces/gradedspace.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
struct GradedSpace{I<:Sector, D} <: ElementarySpace{ℂ}
struct GradedSpace{I<:Sector, D} <: ElementarySpace
dims::D
dual::Bool
end
Expand All @@ -24,7 +24,7 @@ and should typically be of no concern.
The concrete type `GradedSpace{I,D}` with correct `D` can be obtained as `Vect[I]`, or if
`I == Irrep[G]` for some `G<:Group`, as `Rep[G]`.
"""
struct GradedSpace{I<:Sector,D} <: ElementarySpace{ℂ}
struct GradedSpace{I<:Sector,D} <: ElementarySpace
dims::D
dual::Bool
end
Expand Down Expand Up @@ -84,6 +84,7 @@ Base.hash(V::GradedSpace, h::UInt) = hash(V.dual, hash(V.dims, h))

# Corresponding methods:
# properties
field(::Type{<:GradedSpace}) =
InnerProductStyle(::Type{<:GradedSpace}) = EuclideanProduct()
function dim(V::GradedSpace)
return reduce(+, dim(V, c) * dim(c) for c in sectors(V);
Expand Down
9 changes: 5 additions & 4 deletions src/spaces/homspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ function Base.getindex(W::TensorMapSpace{<:IndexSpace,N₁,N₂}, i) where {N₁
return i <= N₁ ? codomain(W)[i] : dual(domain(W)[i - N₁])
end

function (dom::TensorSpace{S}, codom::TensorSpace{S}) where {S<:ElementarySpace}
return HomSpace(ProductSpace(codom), ProductSpace(dom))
function (codom::ProductSpace{S}, dom::ProductSpace{S}) where {S<:ElementarySpace}
return HomSpace(codom, dom)
end

function (codom::TensorSpace{S}, dom::TensorSpace{S}) where {S<:ElementarySpace}
function (codom::S, dom::S) where {S<:ElementarySpace}
return HomSpace(ProductSpace(codom), ProductSpace(dom))
end
(codom::VectorSpace, dom::VectorSpace) = (promote(codom, dom)...)
(dom::VectorSpace, codom::VectorSpace) = (codom, dom)

function Base.show(io::IO, W::HomSpace)
if length(W.codomain) == 1
Expand Down
35 changes: 19 additions & 16 deletions src/spaces/productspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -177,21 +177,11 @@ Base.hash(P::ProductSpace, h::UInt) = hash(P.spaces, h)

# Default construction from product of spaces
#---------------------------------------------
(V₁::S, V₂::S) where {S<:ElementarySpace} = ProductSpace((V₁, V₂))
function (P1::ProductSpace{S}, V₂::S) where {S<:ElementarySpace}
return ProductSpace(tuple(P1.spaces..., V₂))
end
function (V₁::S, P2::ProductSpace{S}) where {S<:ElementarySpace}
return ProductSpace(tuple(V₁, P2.spaces...))
end
(V::Vararg{S}) where {S<:ElementarySpace} = ProductSpace(V)
(P::ProductSpace) = P
function (P1::ProductSpace{S}, P2::ProductSpace{S}) where {S<:ElementarySpace}
return ProductSpace(tuple(P1.spaces..., P2.spaces...))
return ProductSpace{S}(tuple(P1.spaces..., P2.spaces...))
end
(P::ProductSpace{S,0}, ::ProductSpace{S,0}) where {S<:ElementarySpace} = P
(P::ProductSpace{S}, ::ProductSpace{S,0}) where {S<:ElementarySpace} = P
(::ProductSpace{S,0}, P::ProductSpace{S}) where {S<:ElementarySpace} = P
(V::ElementarySpace) = ProductSpace((V,))
(P::ProductSpace) = P

# unit element with respect to the monoidal structure of taking tensor products
"""
Expand All @@ -205,14 +195,12 @@ Base.one(V::VectorSpace) = one(typeof(V))
Base.one(::Type{<:ProductSpace{S}}) where {S<:ElementarySpace} = ProductSpace{S,0}(())
Base.one(::Type{S}) where {S<:ElementarySpace} = ProductSpace{S,0}(())

Base.convert(::Type{<:ProductSpace}, V::ElementarySpace) = ProductSpace((V,))
Base.:^(V::ElementarySpace, N::Int) = ProductSpace{typeof(V),N}(ntuple(n -> V, N))
Base.:^(V::ProductSpace, N::Int) = (ntuple(n -> V, N)...)
function Base.literal_pow(::typeof(^), V::ElementarySpace, p::Val{N}) where {N}
return ProductSpace{typeof(V),N}(ntuple(n -> V, p))
end
Base.convert(::Type{S}, P::ProductSpace{S,0}) where {S<:ElementarySpace} = oneunit(S)
Base.convert(::Type{S}, P::ProductSpace{S}) where {S<:ElementarySpace} = fuse(P.spaces...)

fuse(P::ProductSpace{S,0}) where {S<:ElementarySpace} = oneunit(S)
fuse(P::ProductSpace{S}) where {S<:ElementarySpace} = fuse(P.spaces...)

Expand Down Expand Up @@ -255,3 +243,18 @@ Base.eltype(P::ProductSpace) = eltype(typeof(P))

Base.IteratorEltype(::Type{<:ProductSpace}) = Base.HasEltype()
Base.IteratorSize(::Type{<:ProductSpace}) = Base.HasLength()

Base.reverse(P::ProductSpace) = ProductSpace(reverse(P.spaces))

# Promotion and conversion
# ------------------------
function Base.promote_rule(::Type{S}, ::Type{<:ProductSpace{S}}) where {S<:ElementarySpace}
return ProductSpace{S}
end

# ProductSpace to ElementarySpace
Base.convert(::Type{S}, P::ProductSpace{S,0}) where {S<:ElementarySpace} = oneunit(S)
Base.convert(::Type{S}, P::ProductSpace{S}) where {S<:ElementarySpace} = fuse(P.spaces...)

# ElementarySpace to ProductSpace
Base.convert(::Type{<:ProductSpace}, V::S) where {S<:ElementarySpace} = (V)
Loading

0 comments on commit e2e2984

Please sign in to comment.