@@ -6,6 +6,10 @@ OneToOne() = OneToOne{Bool}()
66Base. first (a:: OneToOne ) = one (eltype (a))
77Base. last (a:: OneToOne ) = one (eltype (a))
88
9+ gradedisequal (:: AbstractUnitRange , :: OneToOne ) = false
10+ gradedisequal (:: OneToOne , :: AbstractUnitRange ) = false
11+ gradedisequal (:: OneToOne , :: OneToOne ) = true
12+
913# https://github.com/ITensor/ITensors.jl/blob/v0.3.57/NDTensors/src/lib/GradedAxes/src/tensor_product.jl
1014# https://en.wikipedia.org/wiki/Tensor_product
1115# https://github.com/KeitaNakamura/Tensorial.jl
@@ -18,7 +22,7 @@ function tensor_product(
1822 return foldl (tensor_product, (a1, a2, a3, a_rest... ))
1923end
2024
21- function tensor_product (a1 :: AbstractUnitRange , a2 :: AbstractUnitRange )
25+ function tensor_product (:: AbstractUnitRange , :: AbstractUnitRange )
2226 return error (" Not implemented yet." )
2327end
2428
@@ -34,7 +38,7 @@ function tensor_product(a1::AbstractBlockedUnitRange, ::OneToOne)
3438 return a1
3539end
3640
37- function tensor_product (a1 :: OneToOne , a2 :: OneToOne )
41+ function tensor_product (:: OneToOne , :: OneToOne )
3842 return OneToOne ()
3943end
4044
@@ -66,18 +70,20 @@ function fuse_blocklengths(x::LabelledInteger, y::LabelledInteger)
6670 return labelled (unlabel (x) * unlabel (y), fuse_labels (label (x), label (y)))
6771end
6872
73+ flatten_maybe_nested (v:: Vector{<:Integer} ) = v
74+ flatten_maybe_nested (v:: Vector{<:AbstractGradedUnitRange} ) = reduce (vcat, blocklengths .(v))
75+
6976using BlockArrays: blockedrange, blocks
7077function tensor_product (a1:: AbstractBlockedUnitRange , a2:: AbstractBlockedUnitRange )
71- blocklengths = map (vec (collect (Iterators. product (blocks (a1), blocks (a2))))) do x
72- return mapreduce (length, fuse_blocklengths, x)
73- end
78+ maybe_nested = map (
79+ it -> mapreduce (length, fuse_blocklengths, it),
80+ Iterators. flatten ((Iterators. product (blocks (a1), blocks (a2)),)),
81+ )
82+ blocklengths = flatten_maybe_nested (maybe_nested)
7483 return blockedrange (blocklengths)
7584end
7685
7786function blocksortperm (a:: AbstractBlockedUnitRange )
78- # TODO : Figure out how to deal with dual sectors.
79- # TODO : `rev=isdual(a)` may not be correct for symmetries beyond `U(1)`.
80- # # return Block.(sortperm(nondual_sectors(a); rev=isdual(a)))
8187 return Block .(sortperm (blocklabels (a)))
8288end
8389
101107# Get the permutation for sorting, then group by common elements.
102108# groupsortperm([2, 1, 2, 3]) == [[2], [1, 3], [4]]
103109function blockmergesortperm (a:: AbstractBlockedUnitRange )
104- # If it is dual, reverse the sorting so the sectors
105- # end up sorted in the same way whether or not the space
106- # is dual.
107- # TODO : Figure out how to deal with dual sectors.
108- # TODO : `rev=isdual(a)` may not be correct for symmetries beyond `U(1)`.
109- # # return Block.(groupsortperm(nondual_sectors(a); rev=isdual(a)))
110110 return Block .(groupsortperm (blocklabels (a)))
111111end
112112
0 commit comments