-
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?
Conversation
I have issues with building test both on local and on GitHub actions. Locally, I get an error LoadError: ArgumentError: Package LinearAlgebra not found in current path. although the package is included in the |
So I added test dependencies and I am now able to pass tests locally with |
I fixed it, the URL for |
src/fusiontensor/array_cast.jl
Outdated
get_tol(a::AbstractArray) = get_tol(real(eltype(a))) | ||
get_tol(T::Type{<:Integer}) = get_tol(Float64) | ||
get_tol(T::Type{<:Real}) = 10 * eps(T) |
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.
A naming convention I have been using is defining functions that provide default values for a keyword argument k
as default_k(...)
, so here it would be default_tol(...)
.
Also, here's a suggestion for making it a bit more compact and general:
default_tol(a::AbstractArray) = default_tol(eltype(a))
default_tol(arrayt::Type{<:AbstractArray}) = default_tol(eltype(arrayt))
default_tol(elt::Type{<:Number}) = 10 * eps(real(float(elt)))
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.
It might be nice to specify atol
or rtol
too, as this can become relevant for SU(N), or even larger irreps of SU(2), where the CGCs can become tiny
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.
Base Julia uses rtoldefault
, looks good to me. I also set atol
to 0
, could be higher.
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 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
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.
That sounds reasonable to me.
return sqrt(quantum_dimension(s)) * cgt[:, :, 1] | ||
end | ||
|
||
function clebsch_gordan_tensor( |
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 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.
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
and flipper
, clebsch_gordan
and f_symbol
interface, with one implementation and one converter.
# The interface uses AbstractGradedUnitRanges as input for interface simplicity | ||
# however only blocklabels are used and blocklengths are never read. | ||
|
||
struct SectorFusionTree{S,N,M} |
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 think it would be nice to be consistent with the fieldnames: either add _sector(s)
everywhere or nowhere? Given that sector
is already in the typename, it might not give that much additional information to add it in the fields as well, so it could maybe be leaves
, arrows
, root
, branches
and vertices
/multiplicities
/... I usually get a bit confused by outer_multiplicity_indices
because these don't actually live on the "outer" charges, but only inside of the tree. Ultimately I don't feel too strongly about this though, just sharing my opinion.
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.
Those changes all sound reasonable to me. I agree the name outer_multiplicity_indices
is a bit confusing.
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.
The problem here is we are using outer
for two different meaning. We use it to label the outer axes, the ones we fuse with the fusion tree. However in outer_multiplicity_indices
, outer
refers to the fusion ring outer multiplicity, a well defined concept widely used in the literature. Since we plan to use nsymbol
for this, maybe we should use nsymbol_indices
?
# TBD could have branch_sectors with length N-2 | ||
# currently first(branch_sectors) == first(leaves) |
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 deciding to keep this, definitely should make sure that this is properly documented :)
src/fusiontensor/fusiontensor.jl
Outdated
data_type::Type{<:Number}, codomain_fused_axes::FusedAxes, domain_fused_axes::FusedAxes | ||
) | ||
# fusion trees have Float64 eltype: need compatible type | ||
promoted = promote_type(data_type, Float64) |
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.
probably don't want to hard-code that here, since this is not always the case (could also be Complex, and for abelian symmetries it is even convenient to use Bool). eltype(fusiontensortype)
or something similar might work?
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 propose fusiontree_eltype(::Type<:AbstractSector})
as an interface. Currently it always return Float64
, we may use another type for abelian groups.
return nothing | ||
end | ||
|
||
Base.size(ft::FusionTensor) = quantum_dimension.(axes(ft)) |
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.
Related to the discussion elsewhere, probably we should redefine length(::AbstractGradedUnitRange)
to output the number of basis vectors in the vector space as opposed to the number of independent parameters, so then this can be defined as: Base.size(ft::FusionTensor) = length.(axes(ft))
(though I think we won't need to define this overload since Base defines size
automatically for AbstractArray
s as long as you define axes
).
From reading the comments above, I see two problems with the current design:
Independently, there is a question whether I think Concerning struct SymmetricDataMatrix <: AbstractBlockSparseMatrix
matrix_blocks::Vector{Pair{AbstractSector,AbstractMatrix}}
row_axis::AbstractGradedUnitRange
column_axis::AbstractGradedUnitRange
end which would act very similarly to the current |
This PR provides a first draft for
FusionTensors
. It defines a generic interface to implement non-abelian symmetries. It currently supportsO(2)
,SU(2)
, any abelian group defined inSymmetrySectors
. It allows to construct, permute and contract tensors.Work to be done in future PR:
FusedAxes
, currently only used inFusionTensor
initializationSymmetrySectors
Work depending on other packages
TensorAlgebra
interface oncecontract
preserves domain and codomain informationnsymbol
toSymmetrySectors
(define nsymbol SymmetrySectors.jl#4)