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
24 changes: 12 additions & 12 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "FusionTensors"
uuid = "e16ca583-1f51-4df0-8e12-57d32947d33e"
authors = ["ITensor developers <[email protected]> and contributors"]
version = "0.3.2"
version = "0.4.0"

[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Expand All @@ -18,16 +18,16 @@ TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138"
WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b"

[compat]
Accessors = "0.1.39"
BlockArrays = "1.2.0"
BlockSparseArrays = "0.4.0"
GradedArrays = "0.2.1"
HalfIntegers = "1.6.0"
LRUCache = "1.6.1"
LinearAlgebra = "1.10.0"
Strided = "2.2.0"
TensorAlgebra = "0.2.4"
TensorProducts = "0.1.3"
TypeParameterAccessors = "0.3.0"
Accessors = "0.1.42"
BlockArrays = "1.6"
BlockSparseArrays = "0.7.4"
GradedArrays = "0.4.7"
HalfIntegers = "1.6"
LRUCache = "1.6"
LinearAlgebra = "1.10"
Strided = "2.3"
TensorAlgebra = "0.3.8"
TensorProducts = "0.1.7"
TypeParameterAccessors = "0.4"
WignerSymbols = "2.0.0"
julia = "1.10"
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"

[compat]
Documenter = "1.10.0"
FusionTensors = "0.3.0"
FusionTensors = "0.4"
Literate = "2.20.1"
9 changes: 5 additions & 4 deletions src/fusion_trees/clebsch_gordan_tensors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
using HalfIntegers: half
using WignerSymbols: clebschgordan

using GradedArrays: dual
using GradedArrays.SymmetrySectors:
using GradedArrays:
AbelianStyle,
AbstractSector,
NotAbelianStyle,
SymmetryStyle,
O2,
SU,
SymmetryStyle,
dual,
istrivial,
quantum_dimension,
sector_label,
sectors,
trivial,
zero_odd
using TensorAlgebra: contract
Expand Down Expand Up @@ -66,7 +67,7 @@ function clebsch_gordan_tensor(s1::O2, s2::O2, s3::O2)
d2 = quantum_dimension(s2)
d3 = quantum_dimension(s3)
cgt = zeros((d1, d2, d3))
s3 ∉ blocklabels(s1 ⊗ s2) && return cgt
s3 ∉ sectors(s1 ⊗ s2) && return cgt

# adapted from TensorKit
l1 = sector_label(s1)
Expand Down
29 changes: 18 additions & 11 deletions src/fusion_trees/fusiontree.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
# TBD
# compatibility with TensorKit conventions?

using GradedArrays: GradedArrays, AbstractGradedUnitRange, flip, isdual, sector_type
using GradedArrays.SymmetrySectors:
using GradedArrays:
GradedArrays,
×,
AbstractGradedUnitRange,
AbstractSector,
SectorProduct,
SymmetrySectors,
arguments,
flip,
flip_dual,
isdual,
nsymbol,
sector_multiplicities,
sector_type,
sectors,
to_gradedrange,
trivial
using TensorAlgebra: flatten_tuples
Expand Down Expand Up @@ -41,7 +47,7 @@ using TensorProducts: ⊗
#
#
# The interface uses AbstractGradedArrays as input for interface simplicity
# however only blocklabels are used and blocklengths are never read.
# however only sectors are used and blocklengths are never read.

struct SectorFusionTree{S,N,M}
leaves::NTuple{N,S} # TBD rename outer_sectors or leave_sectors?
Expand Down Expand Up @@ -98,8 +104,7 @@ function GradedArrays.flip(f::SectorFusionTree)
)
end

# SymmetrySectors interface
function SymmetrySectors.:×(f1::SectorFusionTree, f2::SectorFusionTree)
function GradedArrays.:×(f1::SectorFusionTree, f2::SectorFusionTree)
@assert arrows(f1) == arrows(f2)
product_leaves = .×(leaves(f1), leaves(f2))
product_root_sector = root_sector(f1) × root_sector(f2)
Expand All @@ -120,7 +125,7 @@ function SymmetrySectors.:×(f1::SectorFusionTree, f2::SectorFusionTree)
)
end

function SymmetrySectors.arguments(f::SectorFusionTree{<:SectorProduct})
function GradedArrays.arguments(f::SectorFusionTree{<:SectorProduct})
transposed_indices = outer_multiplicity_split.(
Base.tail(leaves(f)),
branch_sectors(f),
Expand All @@ -144,11 +149,11 @@ function SymmetrySectors.arguments(f::SectorFusionTree{<:SectorProduct})
)
end

function SymmetrySectors.arguments(f::SectorFusionTree{<:SectorProduct,0})
function GradedArrays.arguments(f::SectorFusionTree{<:SectorProduct,0})
return map(arg -> SectorFusionTree((), (), arg, (), ()), arguments(root_sector(f)))
end

function SymmetrySectors.arguments(f::SectorFusionTree{<:SectorProduct,1})
function GradedArrays.arguments(f::SectorFusionTree{<:SectorProduct,1})
arguments_root = arguments(root_sector(f))
arguments_leave = arguments(only(leaves(f)))
# use map(keys) to stay agnostic with respect to SectorProduct implementation
Expand All @@ -164,7 +169,7 @@ fusiontree_eltype(::Type{<:AbstractSector}) = Float64
function build_trees(legs::Vararg{AbstractGradedUnitRange})
# construct all authorized trees for each outer block in legs
tree_arrows = isdual.(legs)
return mapreduce(vcat, Iterators.product(blocklabels.(legs)...)) do it
return mapreduce(vcat, Iterators.product(sectors.(flip_dual.(legs))...)) do it
return build_trees(it, tree_arrows)
end
end
Expand Down Expand Up @@ -240,7 +245,9 @@ function fuse_next_sector(
parent_tree::SectorFusionTree, branch_sector::AbstractSector, level_arrow::Bool
)
new_space = to_gradedrange(root_sector(parent_tree) ⊗ branch_sector)
return mapreduce(vcat, zip(blocklabels(new_space), blocklengths(new_space))) do (la, n)
return mapreduce(
vcat, zip(sectors(new_space), sector_multiplicities(new_space))
) do (la, n)
return [
append_tree_leave(parent_tree, branch_sector, level_arrow, la, outer_mult) for
outer_mult in 1:n
Expand Down
13 changes: 7 additions & 6 deletions src/fusiontensor/array_cast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
using BlockArrays: AbstractBlockArray, BlockedArray, blockedrange, blocklengths, findblock

using BlockSparseArrays: BlockSparseArrays, BlockSparseArray
using GradedArrays: AbstractGradedUnitRange, blocklabels
using GradedArrays.SymmetrySectors: block_dimensions, quantum_dimension
using GradedArrays: AbstractGradedUnitRange, quantum_dimension
using TensorAlgebra: contract

# ================================= High level interface =================================
Expand All @@ -20,11 +19,13 @@ end
function to_fusiontensor(
array::AbstractArray,
codomain_legs::Tuple{Vararg{AbstractGradedUnitRange}},
domain_legs::Tuple{Vararg{AbstractGradedUnitRange}},
domain_legs::Tuple{Vararg{AbstractGradedUnitRange}};
atol::Real=0,
rtol::Real=rtoldefault(array),
)
bounds = block_dimensions.((codomain_legs..., domain_legs...))
bounds = blocklengths.((codomain_legs..., domain_legs...))
blockarray = BlockedArray(array, bounds...)
return to_fusiontensor(blockarray, codomain_legs, domain_legs)
return to_fusiontensor(blockarray, codomain_legs, domain_legs; atol, rtol)
end

rtoldefault(a::AbstractArray) = rtoldefault(eltype(a))
Expand Down Expand Up @@ -72,7 +73,7 @@ function to_fusiontensor_no_checknorm(
end

function to_array(ft::FusionTensor)
bounds = block_dimensions.((codomain_axes(ft)..., domain_axes(ft)...))
bounds = blocklengths.((codomain_axes(ft)..., domain_axes(ft)...))
bsa = BlockSparseArray{eltype(ft)}(undef, blockedrange.(bounds))
for (f1, f2) in keys(trees_block_mapping(ft))
b = findblock(ft, f1, f2)
Expand Down
27 changes: 11 additions & 16 deletions src/fusiontensor/base_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ function Base.:*(left::FusionTensor, right::FusionTensor)
return FusionTensor(new_data_matrix, codomain_axes(left), domain_axes(right))
end

Base.:+(ft::FusionTensor) = ft

# tensor addition is a block data_matrix add.
function Base.:+(left::FusionTensor, right::FusionTensor)
checkaxes(axes(left), axes(right))
Expand Down Expand Up @@ -89,37 +87,34 @@ function Base.similar(ft::FusionTensor, T::Type)

# some fusion trees have Float64 eltype: need compatible type
@assert promote_type(T, fusiontree_eltype(sector_type(ft))) === T
mat = similar(data_matrix(ft), T)
initialize_allowed_sectors!(mat)
mat = initialize_data_matrix(T, codomain_axis(ft), domain_axis(ft))
return FusionTensor(mat, axes(ft), trees_block_mapping(ft))
end

# trigger explicit error in TensorAlgebra.contract
# TBD impose some convention? Remove?
function Base.similar(
ft::FusionTensor,
T::Type,
new_axes::Tuple{AbstractGradedUnitRange,Vararg{AbstractGradedUnitRange}},
::FusionTensor, ::Type, t::Tuple{AbstractGradedUnitRange,Vararg{AbstractGradedUnitRange}}
)
throw(DimensionMismatch("Need bituple of axes"))
throw(MethodError(similar, (typeof(t),)))
end
function Base.similar(ft::FusionTensor, T::Type, new_axes::Tuple{})
throw(DimensionMismatch("Need bituple of axes"))
function Base.similar(::FusionTensor, ::Type, ::Tuple{})
throw(MethodError(similar, (Tuple{},)))
end

function Base.similar(ft::FusionTensor, T::Type, new_axes::Tuple{<:Tuple,<:Tuple})
function Base.similar(
ft::FusionTensor, ::Type{T}, new_axes::Tuple{<:Tuple,<:Tuple}
) where {T}
return similar(ft, T, tuplemortar(new_axes))
end
function Base.similar(::FusionTensor, T::Type, new_axes::BlockedTuple{2})
function Base.similar(::FusionTensor, ::Type{T}, new_axes::BlockedTuple{2}) where {T}
return FusionTensor(T, new_axes)
end

Base.show(io::IO, ft::FusionTensor) = print(io, "$(ndims(ft))-dim FusionTensor")

function Base.show(io::IO, ::MIME"text/plain", ft::FusionTensor)
println(io, "$(ndims(ft))-dim FusionTensor with axes:")
print(io, "$(ndims(ft))-dim FusionTensor with axes:")
for ax in axes(ft)
println(io, ax)
print(io, "\n", ax)
end
return nothing
end
Expand Down
Loading
Loading