Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BlockTensorKit"
uuid = "5f87ffc2-9cf1-4a46-8172-465d160bd8cd"
authors = ["Lukas Devos <[email protected]> and contributors"]
version = "0.3.0"
version = "0.3.1"

[deps]
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
Expand All @@ -25,7 +25,7 @@ MatrixAlgebraKit = "0.5"
Random = "1"
SafeTestsets = "0.1"
Strided = "2"
TensorKit = "0.15"
TensorKit = "0.15.2"
TensorOperations = "5"
Test = "1"
TestExtras = "0.2, 0.3"
Expand Down
8 changes: 8 additions & 0 deletions src/tensors/abstractblocktensor/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ end
setindex!(parent(t), v, args...); t
)

# ambiguity fix
function Base.setindex!(::AbstractBlockTensorMap, ::AbstractTensorMap, sectors::Tuple{I, Vararg{I}}) where {I <: Sector}
error("invalid indexing for blocktensormap")
end
function Base.setindex!(::AbstractBlockTensorMap, ::AbstractTensorMap, ::FusionTree, ::FusionTree)
error("invalid indexing for blocktensormap")
end

# setindex verifies structure is correct
@inline function Base.setindex!(
t::AbstractBlockTensorMap, v::AbstractTensorMap, indices::Vararg{SliceIndex}
Expand Down
18 changes: 9 additions & 9 deletions src/tensors/abstractblocktensor/abstracttensormap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ end

eachspace(t::AbstractBlockTensorMap) = SumSpaceIndices(space(t))

# TODO: delete this method
@inline function Base.getindex(t::AbstractBlockTensorMap, ::Nothing, ::Nothing)
sectortype(t) === Trivial || throw(SectorMismatch())
return mortar(map(x -> x[nothing, nothing], parent(t)))
end
@inline function Base.getindex(
t::AbstractBlockTensorMap{E, S, N₁, N₂}, f₁::FusionTree{I, N₁}, f₂::FusionTree{I, N₂}
) where {E, S, I, N₁, N₂}
sectortype(S) === I || throw(SectorMismatch())
@inline function TensorKit.subblock(
t::AbstractBlockTensorMap, (f₁, f₂)::Tuple{FusionTree, FusionTree}
)
sectortype(t) === sectortype(f₁) === sectortype(f₂) ||
throw(SectorMismatch("Not a valid sectortype for this tensor"))
numout(t) == length(f₁) && numin(t) == length(f₂) ||
throw(DimensionMismatch("Invalid number of fusiontree legs for this tensor"))

subblocks = map(eachspace(t), parent(t)) do V, x
sz = (dims(codomain(V), f₁.uncoupled)..., dims(domain(V), f₂.uncoupled)...)
if prod(sz) == 0
Expand All @@ -28,6 +27,7 @@ end
return x[f₁, f₂]
end
end

return mortar(subblocks)
end
@inline function Base.setindex!(
Expand Down
29 changes: 17 additions & 12 deletions src/tensors/abstractblocktensor/show.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
# Show
# ----
function Base.show(io::IO, t::AbstractBlockTensorMap)
summary(io, t)
get(io, :compact, false) && return nothing
println(io, ":")
for (c, b) in TensorKit.blocks(t)
println(io, "* Block for sector $c:")
show(io, b)
end
function Base.summary(io::IO, t::AbstractBlockTensorMap)
V = space(t)
sz = size(t)
print(io, Base.dims2string(sz), "-blocked ", Base.dims2string(V), " ")
Base.showarg(io, t, true)
return nothing
end

function Base.show(io::IO, ::MIME"text/plain", t::AbstractBlockTensorMap)
# header:
summary(io, t)
nnz = nonzero_length(t)
println(
io, " with ", nnz, " stored entr", isone(nnz) ? "y" : "ies", iszero(nnz) ? "" : ":"
)
if issparse(t)
println(
io, " with ", nnz, " stored entr", isone(nnz) ? "y" : "ies", iszero(nnz) ? "" : ":"
)
end
println(io, ":")
println(io, " codomain: ", codomain(t))
println(io, " domain: ", domain(t))

# body:
compact = get(io, :compact, false)::Bool
Expand All @@ -44,7 +46,10 @@ function show_elements(io::IO, x::AbstractBlockTensorMap)
nz_pairs = sort(vec(collect(nonzero_pairs(x))); by = first)
for (k, (ind, val)) in enumerate(nz_pairs)
if k < half_screen_rows || k > length(nzind) - half_screen_rows
println(io, " ", '[', Base.join(lpad.(Tuple(ind), pads), ","), "] = ", val)
print(io, " ", '[', Base.join(lpad.(Tuple(ind), pads), ","), "] = ")
show(io, MIME"text/plain"(), val)
println(io)

elseif k == half_screen_rows
println(io, " ", Base.join(" " .^ pads, " "), " \u22ee")
end
Expand Down
20 changes: 8 additions & 12 deletions src/tensors/blocktensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -175,22 +175,18 @@ Base.delete!(t::BlockTensorMap, I...) = (zerovector!(getindex(t, I...)); t)

# Show
# ----
function Base.summary(io::IO, t::BlockTensorMap)
szstring = Base.dims2string(size(t))
TT = eltype(t)
typeinfo = get(io, :typeinfo, Any)
if typeinfo <: typeof(t) || typeinfo <: TT
typestring = ""
else
typestring = "{$TT}"
end
V = space(t)
return print(io, "$szstring BlockTensorMap$typestring($V)")
function Base.showarg(io::IO, t::BlockTensorMap, toplevel::Bool)
!toplevel && print(io, "::")
print(io, TK.type_repr(typeof(t)))
return nothing
end

function TK.type_repr(::Type{BlockTensorMap{T, E, S, N₁, N₂, N}}) where {T, E, S, N₁, N₂, N}
return "BlockTensorMap{" * TK.type_repr(T) * ", …}"
end

# Converters
# ----------

function Base.promote_rule(
::Type{<:BlockTensorMap{TT₁}}, ::Type{<:BlockTensorMap{TT₂}}
) where {TT₁, TT₂}
Expand Down
19 changes: 8 additions & 11 deletions src/tensors/sparseblocktensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,12 @@ end

# Show
# ----
function Base.summary(io::IO, t::SparseBlockTensorMap)
szstring = Base.dims2string(size(t))
TT = eltype(t)
typeinfo = get(io, :typeinfo, Any)
if typeinfo <: typeof(t) || typeinfo <: TT
typestring = ""
else
typestring = "{$TT}"
end
V = space(t)
return print(io, "$szstring SparseBlockTensorMap$typestring($V)")
function Base.showarg(io::IO, t::SparseBlockTensorMap, toplevel::Bool)
!toplevel && print(io, "::")
print(io, TK.type_repr(typeof(t)))
return nothing
end

function TK.type_repr(::Type{SparseBlockTensorMap{T, E, S, N₁, N₂, N}}) where {T, E, S, N₁, N₂, N}
return "SparseBlockTensorMap{" * join((TK.type_repr(T), E, TK.type_repr(S), N₁, N₂, N), ", ") * "}"
end
34 changes: 27 additions & 7 deletions src/vectorspaces/sumspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,15 @@ TensorKit.infimum(V::S, W::S) where {S <: SumSpace} = infimum(⊕(V), ⊕(W))
TensorKit.supremum(V::S, W::S) where {S <: SumSpace} = supremum(⊕(V), ⊕(W))
TensorKit.ominus(V::S, W::S) where {S <: SumSpace} = ominus(⊕(V), ⊕(W))

TensorKit.oplus(V::SumSpace{S}) where {S} = reduce(⊕, V.spaces; init = isdual(V) ? zero(S)' : zero(S))
TensorKit.oplus(V::SumSpace{S}) where {S} = reduce(⊕, V.spaces; init = isdual(V) ? zerospace(S)' : zerospace(S))
TensorKit.oplus(V1::SumSpace{S}, V2::SumSpace{S}...) where {S} = mapreduce(⊕, ⊕, (V1, V2...))

function TensorKit.fuse(V1::S, V2::S) where {S <: SumSpace}
return SumSpace(vec([fuse(v1, v2) for (v1, v2) in Base.product(V1.spaces, V2.spaces)]))
end

Base.oneunit(S::Type{<:SumSpace}) = SumSpace(oneunit(eltype(S)))
Base.zero(V::SumSpace{S}) where {S} = SumSpace{S}(; dual = isdual(V))
Base.zero(::Type{SumSpace{S}}) where {S} = SumSpace{S}()
TensorKit.unitspace(S::Type{<:SumSpace}) = SumSpace(TensorKit.unitspace(eltype(S)))
TensorKit.zerospace(::Type{SumSpace{S}}) where {S} = SumSpace{S}()

# Promotion and conversion
# ------------------------
Expand Down Expand Up @@ -228,19 +227,40 @@ function Base.show(io::IO, V::SumSpace)
end

limited = get(io, :limited, true)
ioc = IOContext(io, :compact => true)
if limited && length(V) > SUMSPACE_SHOW_LIMIT[]
ax = axes(V.spaces, 1)
f, l = first(ax), last(ax)
h = SUMSPACE_SHOW_LIMIT[] ÷ 2
Base.show_delim_array(io, V.spaces, "(", " ⊞", "", false, f, f + h)
Base.show_delim_array(ioc, V.spaces, "(", " ⊞", "", false, f, f + h)
print(io, " ⊞ ⋯ ⊞ ")
Base.show_delim_array(io, V.spaces, "", " ⊞", ")", false, l - h, l)
Base.show_delim_array(ioc, V.spaces, "", " ⊞", ")", false, l - h, l)
else
Base.show_delim_array(io, V.spaces, "(", " ⊞", ")", false)
Base.show_delim_array(ioc, V.spaces, "(", " ⊞", ")", false)
end
return nothing
end

function Base.show(io::IO, ::MIME"text/plain", V::SumSpace)
# print small summary, e.g.: l-element SumSpace(Vect[I](…)) of dim d
l = length(V.spaces)
d = dim(V)
print(io, l, "-element ⊞(::", TK.type_repr(eltype(V)), "…)")
isdual(V) && print(io, "'")
print(io, " of dim ", d)

compact = get(io, :compact, false)::Bool
(iszero(d) || compact) && return nothing

# print detailed space information - hijack Base.Vector printing
print(io, ":\n")
print_data = V.spaces
ioc = IOContext(io, :typeinfo => eltype(print_data))
Base.print_matrix(ioc, print_data)

return nothing
end

# TensorMapSumSpace
# -----------------
# function TensorKit.fusionblockstructure(
Expand Down
2 changes: 1 addition & 1 deletion test/abstracttensor/blocktensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ end
@test i1 * i2 == @constinferred(id(storagetype(t), V1 ⊗ V2))
@test i2 * i1 == @constinferred(id(storagetype(t), V2 ⊗ V1))

w = @constinferred(isometry(storagetype(t), V1 ⊗ (oneunit(V1) ⊕ oneunit(V1)), V1))
w = @constinferred(isometry(storagetype(t), V1 ⊗ (unitspace(V1) ⊕ unitspace(V1)), V1))
@test dim(w) == 2 * dim(V1 ← V1)
@test w' * w == id(storagetype(t), V1)
@test w * w' == (w * w')^2
Expand Down
2 changes: 1 addition & 1 deletion test/abstracttensor/sparseblocktensor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ end
@test i1 * i2 == @constinferred(id(storagetype(t), V1 ⊗ V2))
@test i2 * i1 == @constinferred(id(storagetype(t), V2 ⊗ V1))

w = @constinferred(isometry(storagetype(t), V1 ⊗ (oneunit(V1) ⊞ oneunit(V1)), V1))
w = @constinferred(isometry(storagetype(t), V1 ⊗ (unitspace(V1) ⊞ unitspace(V1)), V1))
@test dim(w) == 2 * dim(V1 ← V1)
@test w' * w == id(storagetype(t), V1)
@test w * w' == (w * w')^2
Expand Down
12 changes: 6 additions & 6 deletions test/vectorspaces/sumspace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ using TensorKit, BlockTensorKit
@test (sectors(typeof(V)())...,) == ()
@test @constinferred(axes(V)) == Base.OneTo(d)
W = @constinferred SumSpace(ℝ^1)
@test @constinferred(oneunit(V)) == W == oneunit(typeof(V))
@test @constinferred(unitspace(V)) == W == unitspace(typeof(V))
@test @constinferred(⊞(V, V)) == SumSpace(vcat(V.spaces, V.spaces))
@test @constinferred(⊞(V, oneunit(V))) == SumSpace(vcat(V.spaces, ℝ^1))
@test @constinferred(⊞(V, unitspace(V))) == SumSpace(vcat(V.spaces, ℝ^1))
@test @constinferred(⊞(V, V, V, V)) == SumSpace(repeat(V.spaces, 4))
@test @constinferred(fuse(V, V)) ≅ SumSpace(ℝ^(d^2))
@test @constinferred(fuse(V, V', V, V')) ≅ SumSpace(ℝ^(d^4))
Expand Down Expand Up @@ -87,9 +87,9 @@ end
@test (sectors(typeof(V)())...,) == ()
@test @constinferred(axes(V)) == Base.OneTo(d)
W = @constinferred SumSpace(ℂ^1)
@test @constinferred(oneunit(V)) == W == oneunit(typeof(V))
@test @constinferred(unitspace(V)) == W == unitspace(typeof(V))
@test @constinferred(⊞(V, V)) == SumSpace(vcat(V.spaces, V.spaces))
@test @constinferred(⊞(V, oneunit(V))) == SumSpace(vcat(V.spaces, ℂ^1))
@test @constinferred(⊞(V, unitspace(V))) == SumSpace(vcat(V.spaces, ℂ^1))
@test @constinferred(⊞(V, V, V, V)) == SumSpace(repeat(V.spaces, 4))
@test @constinferred(fuse(V, V)) ≅ SumSpace(ℂ^(d^2))
@test @constinferred(fuse(V, V', V, V')) ≅ SumSpace(ℂ^(d^4))
Expand Down Expand Up @@ -139,9 +139,9 @@ end
@test (sectors(typeof(V)())...,) == ()
@test @constinferred(axes(V)) == Base.OneTo(d)
W = @constinferred SumSpace(U1Space(0 => 1))
@test @constinferred(oneunit(V)) == W == @constinferred(oneunit(typeof(V)))
@test @constinferred(unitspace(V)) == W == @constinferred(unitspace(typeof(V)))
@test @constinferred(⊞(V, V)) == SumSpace(vcat(V.spaces, V.spaces))
@test @constinferred(⊞(V, oneunit(V))) == SumSpace(vcat(V.spaces, oneunit(V1)))
@test @constinferred(⊞(V, unitspace(V))) == SumSpace(vcat(V.spaces, unitspace(V1)))
@test @constinferred(⊞(V, V, V, V)) == SumSpace(repeat(V.spaces, 4))
@test @constinferred(fuse(V, V)) ≅ SumSpace(U1Space(0 => 9, 1 => 24, 2 => 16))
@test @constinferred(fuse(V, V', V, V')) ≅
Expand Down