Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion src/TensorKit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export infimum, supremum, isisomorphic, ismonomorphic, isepimorphic
export sectortype, sectors, hassector
export unit, rightunit, leftunit, allunits, isunit, otimes, deligneproduct, timereversed
export Nsymbol, Fsymbol, Rsymbol, Bsymbol, frobenius_schur_phase, frobenius_schur_indicator, twist, fusiontensor
export sectorscalartype, fusionscalartype, braidingscalartype
export sectorscalartype, fusionscalartype, braidingscalartype, dimscalartype

# Export methods for fusion trees
export fusiontrees, braid, permute, transpose
Expand Down
79 changes: 64 additions & 15 deletions src/auxiliary/dicts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,12 @@ end
Base.empty(::SortedVectorDict, ::Type{K}, ::Type{V}) where {K, V} = SortedVectorDict{K, V}()
Base.empty!(d::SortedVectorDict) = (empty!(d.keys); empty!(d.values); return d)

# _searchsortedfirst(v::Vector, k) = searchsortedfirst(v, k)
function _searchsortedfirst(v::Vector, k)
i = 1
@inbounds while i <= length(v) && isless(v[i], k)
i += 1
end
return i
end

function Base.delete!(d::SortedVectorDict{K}, k) where {K}
key = convert(K, k)
if !isequal(k, key)
return d
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
if i <= length(d) && isequal(d.keys[i], key)
deleteat!(d.keys, i)
deleteat!(d.values, i)
Expand All @@ -118,15 +109,15 @@ function Base.haskey(d::SortedVectorDict{K}, k) where {K}
if !isequal(k, key)
return false
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
return (i <= length(d) && isequal(d.keys[i], key))
end
function Base.getindex(d::SortedVectorDict{K}, k) where {K}
key = convert(K, k)
if !isequal(k, key)
throw(KeyError(k))
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
@inbounds if (i <= length(d) && isequal(d.keys[i], key))
return d.values[i]
else
Expand All @@ -138,7 +129,7 @@ function Base.setindex!(d::SortedVectorDict{K}, v, k) where {K}
if !isequal(k, key)
throw(ArgumentError("$k is not a valid key for type $K"))
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
if i <= length(d) && isequal(d.keys[i], key)
d.values[i] = v
else
Expand All @@ -153,7 +144,7 @@ function Base.get(d::SortedVectorDict{K}, k, default) where {K}
if !isequal(k, key)
return default
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
@inbounds begin
return (i <= length(d) && isequal(d.keys[i], key)) ? d.values[i] : default
end
Expand All @@ -163,7 +154,7 @@ function Base.get(f::Union{Function, Type}, d::SortedVectorDict{K}, k) where {K}
if !isequal(k, key)
return f()
end
i = _searchsortedfirst(d.keys, key)
i = searchsortedfirst(d.keys, key)
@inbounds begin
return (i <= length(d) && isequal(d.keys[i], key)) ? d.values[i] : f()
end
Expand All @@ -186,6 +177,64 @@ function Base.:(==)(d1::SortedVectorDict, d2::SortedVectorDict)
return true
end

# merge over two SectorDicts
# the intersect case for infimum is kind of tricky, so there's an extra bool
# to indicate keeping keys that are only present in one of the two dicts
# zero results are dropped, matching how GradedSpace never stores an explicit zero dimension
function _sortedmerge(
combine, ::Val{keepunique}, d1::SortedVectorDict{K, V}, d2::SortedVectorDict{K, V}
) where {keepunique, K, V}
k1, v1 = d1.keys, d1.values
k2, v2 = d2.keys, d2.values
n1, n2 = length(k1), length(k2)
ks, vs = Vector{K}(), Vector{V}()
sizehint!(ks, keepunique ? n1 + n2 : min(n1, n2))
sizehint!(vs, keepunique ? n1 + n2 : min(n1, n2))
i, j = 1, 1
@inbounds while i <= n1 && j <= n2
if k1[i] == k2[j]
d = combine(v1[i], v2[j])
if !iszero(d)
push!(ks, k1[i])
push!(vs, d)
end
i += 1
j += 1
elseif k1[i] < k2[j]
if keepunique
push!(ks, k1[i])
push!(vs, v1[i])
end
i += 1
else
if keepunique
push!(ks, k2[j])
push!(vs, v2[j])
end
j += 1
end
end
if keepunique
@inbounds while i <= n1
push!(ks, k1[i])
push!(vs, v1[i])
i += 1
end
@inbounds while j <= n2
push!(ks, k2[j])
push!(vs, v2[j])
j += 1
end
end
return SortedVectorDict{K, V}(ks, vs)
end

Base.mergewith(combine, d1::SortedVectorDict{K, V}, d2::SortedVectorDict{K, V}) where {K, V} =
_sortedmerge(combine, Val(true), d1, d2)

_sortedintersect(combine, d1::SortedVectorDict{K, V}, d2::SortedVectorDict{K, V}) where {K, V} =
_sortedmerge(combine, Val(false), d1, d2)

"""
Hashed(value, hashfunction = Base.hash, isequal = Base.isequal)

Expand Down
4 changes: 2 additions & 2 deletions src/factorizations/factorizations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ module Factorizations
export copy_oftype, factorisation_scalartype, one!, truncspace

using ..TensorKit
using ..TensorKit: AdjointTensorMap, SectorDict, SectorVector,
using ..TensorKit: AdjointTensorMap, SectorDict, SectorVector, findindex,
blocktype, foreachblock, one!,
similar_diagonal, similarstoragetype
similar_diagonal, similarstoragetype, sectorstoragetype

using LinearAlgebra: LinearAlgebra, BlasFloat, Diagonal,
svdvals, svdvals!, eigen, eigen!,
Expand Down
12 changes: 9 additions & 3 deletions src/factorizations/pullbacks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ for pullback! in (:qr_null_pullback!, :lq_null_pullback!)
return Δt
end
end
_notrunc_ind(t) = SectorDict(c => Colon() for c in blocksectors(t))
function _notrunc_ind(t)
I = sectortype(t)
return _builddensemap(sectorstoragetype(I), I, blocks(t), Colon) do _, _
Colon()
end
end

for pullback! in (:svd_pullback!, :eig_pullback!, :eigh_pullback!)
@eval function MAK.$pullback!(
Δt::AbstractTensorMap, t::AbstractTensorMap, F, ΔF, inds = _notrunc_ind(t);
kwargs...
)
Isec = sectortype(t)
foreachblock(Δt, t) do c, (Δb, b)
haskey(inds, c) || return nothing
ind = inds[c]
ind = _denseget(inds, Isec, c)
isnothing(ind) && return nothing
Fc = block.(F, Ref(c))
ΔFc = block.(ΔF, Ref(c))
MAK.$pullback!(Δb, b, Fc, ΔFc, ind; kwargs...)
Expand Down
Loading
Loading