-
Notifications
You must be signed in to change notification settings - Fork 1
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
base: main
Are you sure you want to change the base?
Changes from all commits
3dd5ff2
11a5d88
afed27a
5ed5b8e
d66540c
a9dc29f
d7edb71
4a8f9ba
e75d783
705b7aa
deaf6b1
8ab786e
563bae1
b35757b
0299e4b
4647030
e53bffd
2794d60
a23939c
f9b0daa
d816193
899bed8
3ef076d
cdd3a2f
9ed1f1a
4f746b8
6528b63
cc9c7dc
067403b
ee06e3f
837e151
423b275
7decaa4
3eb6a8e
62e09ef
4057fe8
f663d05
03080e3
9247074
22c5e51
ab9a76a
aaac06a
591bcbc
192fe47
5f2452d
4e94367
20a3119
260760f
7342477
cb15d63
b751f9e
1dc72ae
d3b624e
f6ae180
20d5ff5
98294e7
7ecea43
c754d35
7aad297
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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] | ||
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" | ||
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" | ||
BlockSparseArrays = "2c9a651f-6452-4ace-a6ac-809f4280fbb4" | ||
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] | ||
Accessors = "0.1.39" | ||
BlockArrays = "1.2.0" | ||
BlockSparseArrays = "0.2.0" | ||
GradedUnitRanges = "0.1.1" | ||
HalfIntegers = "1.6.0" | ||
LRUCache = "1.6.1" | ||
LabelledNumbers = "0.1.0" | ||
LinearAlgebra = "1.10.0" | ||
SparseArraysBase = "0.2.0" | ||
Strided = "2.2.0" | ||
SymmetrySectors = "0.1.1" | ||
TensorAlgebra = "0.1.5" | ||
TypeParameterAccessors = "0.2.0" | ||
WignerSymbols = "2.0.0" | ||
julia = "1.10" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,13 @@ | ||
module FusionTensors | ||
|
||
# Write your package code here. | ||
include("fusion_trees/fusiontree.jl") | ||
include("fusion_trees/clebsch_gordan_tensors.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 |
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( | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
There was a problem hiding this comment.
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 thesymbol_3j
andsymbol_6j
notations instead ofclebsch_gordan_tensor
? In general, clebsch gordan seems to be very often related specifically to SU(N) anyways.There was a problem hiding this comment.
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
andflipper
,clebsch_gordan
andf_symbol
interface, with one implementation and one converter.