Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First draft of FusionTensor #5

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3dd5ff2
split project
ogauthe Dec 4, 2024
11a5d88
write intersect_sectors
ogauthe Dec 5, 2024
afed27a
define tree_to_block_mapping
ogauthe Dec 5, 2024
5ed5b8e
define getindex
ogauthe Dec 5, 2024
d66540c
array cast with FusionTree
ogauthe Dec 9, 2024
a9dc29f
clean Base
ogauthe Dec 10, 2024
d7edb71
reuse tree_block_mapping in Base operations
ogauthe Dec 11, 2024
4a8f9ba
working permutedims
ogauthe Dec 11, 2024
e75d783
fix contract
ogauthe Dec 11, 2024
705b7aa
put imports on top of files
ogauthe Dec 11, 2024
deaf6b1
move check_sanity to tests
ogauthe Dec 11, 2024
8ab786e
rewrite test FusionTree
ogauthe Dec 11, 2024
563bae1
cleaning
ogauthe Dec 11, 2024
b35757b
cache unitary coeff
ogauthe Dec 13, 2024
0299e4b
fix tests
ogauthe Dec 13, 2024
4647030
simplify cast_to_array
ogauthe Dec 13, 2024
e53bffd
update to BlockSparseArrays 0.2.0
ogauthe Dec 17, 2024
2794d60
use map_blocklabels
ogauthe Dec 18, 2024
a23939c
fix signatures for fusiontensor_permutedims
ogauthe Dec 18, 2024
f9b0daa
define unsafe_cast_from_array
ogauthe Dec 18, 2024
d816193
use @strided
ogauthe Dec 18, 2024
899bed8
rename FusionTree SectorFusionTree
ogauthe Dec 18, 2024
3ef076d
use @view!
ogauthe Dec 18, 2024
cdd3a2f
use fusiontensor when data_matrix is provided
ogauthe Dec 18, 2024
9ed1f1a
Merge branch 'main' into dev
ogauthe Dec 19, 2024
4f746b8
move tests
ogauthe Dec 19, 2024
6528b63
check matrix axes in fusiontensor
ogauthe Dec 19, 2024
cc9c7dc
remove unused variable
ogauthe Dec 19, 2024
067403b
fix tests
ogauthe Dec 19, 2024
ee06e3f
Loosen LinearAlgebra compat
mtfishman Dec 19, 2024
837e151
fix names in array_cast
ogauthe Dec 19, 2024
423b275
Bump TypeParameterAccessors to v0.2
mtfishman Dec 22, 2024
7decaa4
remove getindex(::Tuple)
ogauthe Dec 20, 2024
3eb6a8e
remove ndims
ogauthe Dec 20, 2024
62e09ef
simplify similar
ogauthe Dec 20, 2024
4057fe8
rewrite linear_algebra
ogauthe Dec 20, 2024
f663d05
use do block
ogauthe Jan 6, 2025
03080e3
use Accessors
ogauthe Jan 6, 2025
9247074
use AbstractArray similar(::FusionTensor)
ogauthe Jan 6, 2025
22c5e51
replace matching_axes with checkaxes
ogauthe Jan 6, 2025
ab9a76a
rename to_array
ogauthe Jan 6, 2025
aaac06a
define atol and rtol for array_cast
ogauthe Jan 6, 2025
591bcbc
fix sector_type
ogauthe Jan 6, 2025
192fe47
use sector_type(FusionTree)
ogauthe Jan 6, 2025
5f2452d
remove to_tuple
ogauthe Jan 6, 2025
4e94367
define fusiontree_eltype
ogauthe Jan 6, 2025
20a3119
avoid code dupplication
ogauthe Jan 7, 2025
260760f
remove FusedAxes
ogauthe Jan 7, 2025
7342477
better names
ogauthe Jan 7, 2025
cb15d63
replace FusionTensor with to_fusiontensor
ogauthe Jan 8, 2025
b751f9e
fix to_fusiontensor name
ogauthe Jan 8, 2025
1dc72ae
use do block
ogauthe Jan 8, 2025
d3b624e
inline return
ogauthe Jan 8, 2025
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
32 changes: 31 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
name = "FusionTensors"
uuid = "e16ca583-1f51-4df0-8e12-57d32947d33e"
authors = ["ITensor developers <[email protected]> and contributors"]
version = "0.1.0"
version = "0.2.0"

[deps]
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
BlockSparseArrays = "2c9a651f-6452-4ace-a6ac-809f4280fbb4"
BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2"
GradedUnitRanges = "e2de450a-8a67-46c7-b59c-01d5a3d041c5"
HalfIntegers = "f0d1745a-41c9-11e9-1dd9-e5d34d218721"
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
LabelledNumbers = "f856a3a6-4152-4ec4-b2a7-02c1a55d7993"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
SparseArraysBase = "0d5efcca-f356-4864-8770-e1ed8d78f208"
Strided = "5e0ebb24-38b0-5f93-81fe-25c709ecae67"
SymmetrySectors = "f8a8ad64-adbc-4fce-92f7-ffe2bb36a86e"
TensorAlgebra = "68bd88dc-f39d-4e12-b2ca-f046b68fcc6a"
TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138"
WignerSymbols = "9f57e263-0b3d-5e2e-b1be-24f2bb48858b"

[compat]
BlockArrays = "1.2.0"
BlockSparseArrays = "0.2.0"
BroadcastMapConversion = "0.1.0"
GradedUnitRanges = "0.1.1"
HalfIntegers = "1.6.0"
LRUCache = "1.6.1"
LabelledNumbers = "0.1.0"
LinearAlgebra = "1.11.0"
mtfishman marked this conversation as resolved.
Show resolved Hide resolved
SparseArraysBase = "0.2.0"
Strided = "2.2.0"
SymmetrySectors = "0.1.1"
TensorAlgebra = "0.1.0"
TypeParameterAccessors = "0.1.0"
WignerSymbols = "2.0.0"
julia = "1.10"
11 changes: 10 additions & 1 deletion src/FusionTensors.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
module FusionTensors

# Write your package code here.
include("fusion_trees/fusiontree.jl")
include("fusion_trees/clebsch_gordan_tensors.jl")
include("fusiontensor/fusedaxes.jl")
include("fusiontensor/fusiontensor.jl")
include("fusiontensor/base_interface.jl")
include("fusiontensor/array_cast.jl")
include("fusiontensor/linear_algebra_interface.jl")
include("fusiontensor/tensor_algebra_interface.jl")
include("permutedims/unitaries.jl")
include("permutedims/permutedims.jl")

end
136 changes: 136 additions & 0 deletions src/fusion_trees/clebsch_gordan_tensors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# This file defines Clebsch-Gordan tensors
# one tensor is defined from 3 simple objects s1, s2 and s3
# and contains the coefficients fusing s1 ⊗ s2 -> s3

using HalfIntegers: half
using WignerSymbols: clebschgordan

using GradedUnitRanges: dual, fusion_product
using SymmetrySectors:
⊗,
AbelianStyle,
AbstractSector,
NotAbelianStyle,
SymmetryStyle,
O2,
SU,
istrivial,
quantum_dimension,
sector_label,
trivial,
zero_odd
using TensorAlgebra: contract

function symbol_1j(s::AbstractSector)
cgt = clebsch_gordan_tensor(s, dual(s), trivial(s), 1)
return sqrt(quantum_dimension(s)) * cgt[:, :, 1]
end

function clebsch_gordan_tensor(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use symbol_1j, it might be more internally consistent to then also use the symbol_3j and symbol_6j notations instead of clebsch_gordan_tensor? In general, clebsch gordan seems to be very often related specifically to SU(N) anyways.

Copy link
Collaborator Author

@ogauthe ogauthe Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not have a strong opinion here. We can have both symbol_1/3/6j and flipper, clebsch_gordan and f_symbol interface, with one implementation and one converter.

s1::AbstractSector,
s2::AbstractSector,
s3::AbstractSector,
arrow1::Bool,
arrow2::Bool,
inner_mult_index::Int,
)
cgt = clebsch_gordan_tensor(s1, s2, s3, inner_mult_index)
if arrow1
flip1 = symbol_1j(s1)
cgt = contract((1, 2, 3), flip1, (4, 1), cgt, (4, 2, 3))
end
if arrow2
flip2 = symbol_1j(s2)
cgt = contract((1, 2, 3), flip2, (4, 2), cgt, (1, 4, 3))
end
return cgt
end

function clebsch_gordan_tensor(s1::S, s2::S, s3::S, outer_mult_index::Int) where {S}
return clebsch_gordan_tensor(SymmetryStyle(S), s1, s2, s3, outer_mult_index)
end

function clebsch_gordan_tensor(
::AbelianStyle, s1::S, s2::S, s3::S, outer_mult_index::Int
) where {S}
@assert outer_mult_index == 1
return s1 ⊗ s2 == s3 ? ones((1, 1, 1)) : zeros((1, 1, 1))
end

function clebsch_gordan_tensor(::NotAbelianStyle, s1::O2, s2::O2, s3::O2, ::Int)
return clebsch_gordan_tensor(s1, s2, s3) # no outer multiplicity
end

function clebsch_gordan_tensor(s1::O2, s2::O2, s3::O2)
d1 = quantum_dimension(s1)
d2 = quantum_dimension(s2)
d3 = quantum_dimension(s3)
cgt = zeros((d1, d2, d3))
s3 ∉ blocklabels(fusion_product(s1, s2)) && return cgt

# adapted from TensorKit
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this is adapted from TensorKit anyways, how would you feel about:

function clebsch_gordan_tensor(s1, s2, s3)
    s1_tk, s2_tk, s3_tk = convert.(TensorKitSectors.Sector, (s1, s2, s3))
    cgt = TensorKitSectors.fusiontensor(s1_tk, s2_tk, s3_tk)
    return reshape(cgt, size(cgt, 1), size(cgt, 2), size(cgt, 3)) # discard trailing singleton dimension
end   

I don't think there is a lot of value in having the implementation copied here, it's definitely more maintenance and error-prone, so it would be cool if we could immediately share this.
(This is a registered light-weight package that only contains the symmetry data, so the dependency is quite light, and this automatically inherits many of the symmetries)
https://github.com/QuantumKitHub/TensorKitSectors.jl

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds reasonable to me.

l1 = sector_label(s1)
l2 = sector_label(s2)
l3 = sector_label(s3)
if l3 <= 0 # 0even or 0odd
if l1 <= 0 && l2 <= 0
cgt[1, 1, 1, 1] = 1.0
else
if istrivial(s3)
cgt[1, 2, 1, 1] = 1.0 / sqrt(2)
cgt[2, 1, 1, 1] = 1.0 / sqrt(2)
else
cgt[1, 2, 1, 1] = 1.0 / sqrt(2)
cgt[2, 1, 1, 1] = -1.0 / sqrt(2)
end
end
elseif l1 <= 0 # 0even or 0odd
cgt[1, 1, 1, 1] = 1.0
cgt[1, 2, 2, 1] = s1 == zero_odd(O2) ? -1.0 : 1.0
elseif l2 == 0
cgt[1, 1, 1, 1] = 1.0
cgt[2, 1, 2, 1] = s2 == zero_odd(O2) ? -1.0 : 1.0
elseif l3 == l1 + l2
cgt[1, 1, 1, 1] = 1.0
cgt[2, 2, 2, 1] = 1.0
elseif l3 == l1 - l2
cgt[1, 2, 1, 1] = 1.0
cgt[2, 1, 2, 1] = 1.0
elseif l3 == l2 - l1
cgt[2, 1, 1, 1] = 1.0
cgt[1, 2, 2, 1] = 1.0
end
return cgt
end

function clebsch_gordan_tensor(::NotAbelianStyle, s1::SU{2}, s2::SU{2}, s3::SU{2}, ::Int)
return clebsch_gordan_tensor(s1, s2, s3) # no outer multiplicity
end

function clebsch_gordan_tensor(s1::SU{2}, s2::SU{2}, s3::SU{2})
d1 = quantum_dimension(s1)
d2 = quantum_dimension(s2)
d3 = quantum_dimension(s3)
j1 = half(d1 - 1)
j2 = half(d2 - 1)
j3 = half(d3 - 1)
cgtensor = Array{Float64,3}(undef, (d1, d2, d3))
for (i, j, k) in Iterators.product(1:d1, 1:d2, 1:d3)
m1 = j1 - i + 1
m2 = j2 - j + 1
m3 = j3 - k + 1
cgtensor[i, j, k] = clebschgordan(j1, m1, j2, m2, j3, m3)
end
return cgtensor
end

function clebsch_gordan_tensor(
::NotAbelianStyle, s1::SU{3}, s2::SU{3}, s3::SU{3}, outer_mult_index::Int
)
d1 = quantum_dimension(s1)
d2 = quantum_dimension(s2)
d3 = quantum_dimension(s3)
cgtensor = zeros(d1, d2, d3)
# dummy
return cgtensor
end
Loading
Loading