You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current design for labelled numbers incurs a rather large number of method ambiguities and can possibly lead to invalidations, since defining new integer types etc is a big source of that.
Of course, this should not be an argument to never define new number types, but just to carefully consider the benefits.
Here, (correct me if I'm wrong), the main purpose is to have labels attached to GradedUnitRange objects, such that these can easily/automatically be carried along.
One alternative could be to separate the labels and the integers again, and manually handle that kind of logic in GradedUnitRange. The benefit is that this does not suffer from ambiguities and invalidations, but of course requires a bit more manual work.
Just to add this information here, as @mtfishman mentioned, one nice feature that we probably should preserve in any case is that indexing into a gradedrange outputs something that contains both the label as well as the range information:
what I like about the current design is that when you index into a GradedUnitRange, i.e. g[2], it outputs the range value along with information about the sector. That is consistent with the fact that we want slices like g[Block.(2:3)], g[2:5], g[Block(2)], etc. to preserve the sector information.
After thinking about this a bit more, it seems to me that - at least for slicing operations - this should not be a real problem to support in any case, since indexing into a gradedrange object returns another gradedrange, which thus retains that information. The harder case to figure out is what "scalar indexing" should do, similar to how scalar indexing into BlockArrays becomes a bit more involved. The normal Julia array behavior is to drop scalar dimensions, reducing the total number of dimensions as you index. This is slightly annoying to deal with for ranges/axes that want to hold on to more information, since there you really don't want to drop these dimensions, because that would also discard the label/grading information.
Effectively, I would probably advocate that for these kinds of arrays, indexing should either be "fully scalar", and if not, considered as a slicing operation.
a[1,2,3] # scalar
a[1:3, 2:4, 2:3] # slicing: Array{T,3} as result
a[1, :, :] # slicing: Matrix as result -- should really just stay Array{T,3}!!
To achieve this, effectively you would have that a[i, ...] would become a[i:i, ...] whenever not all indices are "scalar". This would also solve the issue that indexing with a scalar into a gradedrange loses the label information, as now g[i:i] would still output a range.
The text was updated successfully, but these errors were encountered:
So, I remembered the feature I like the most about the current design, which is that code like this:
r =blockedrange([2, 3])
# Or:
r =gradedrange([U1(0) =>2, U1(1) =>3])
# Outputs either blocked range or graded range# depending on `r`blockedrange(blocklengths(r))
"just works". That is helpful for making code generic between graded unit ranges and plain blocked unit ranges. Right now that is made possible because blocklengths(::AbstractGradedUnitRange) outputs a list of labelled integers, but maybe we can get that behavior (and similar behavior where we want the sector information preserved in generic code) in other ways, such as the suggestion in ITensor/SymmetrySectors.jl#4 (comment) to have blocklengths(::AbstractGradedUnitRange) output an iterator object.
Maybe a different way to formulate the question could be if we can get away with not making LabelledInteger a subtype of Integer, which would also solve these issues.
In some sense, I would indeed expect blocklengths to return information about the different sectors and their corresponding lengths.
I think it might be intuitive to think about this as follows: you need to blocklengths needs to return two pieces of information: the "order" of the blocks and their sizes.
standard blockaxes have blocklengths that are just ordered according to linear ordering: blocklengths(r)[i] yields the length of block i::Int. Ie, this behaves like vectors of blocklengths.
graded blockaxes have blocklengths that are ordered according to their label: blocklengths(r)[c] yields the length of the block with label c. Ie, this behaves somewhat like a dictionary.
Clearly, whether this is a vector or a dictionary should just be an implementation detail
The current design for labelled numbers incurs a rather large number of method ambiguities and can possibly lead to invalidations, since defining new integer types etc is a big source of that.
Of course, this should not be an argument to never define new number types, but just to carefully consider the benefits.
Here, (correct me if I'm wrong), the main purpose is to have labels attached to
GradedUnitRange
objects, such that these can easily/automatically be carried along.One alternative could be to separate the labels and the integers again, and manually handle that kind of logic in
GradedUnitRange
. The benefit is that this does not suffer from ambiguities and invalidations, but of course requires a bit more manual work.Just to add this information here, as @mtfishman mentioned, one nice feature that we probably should preserve in any case is that indexing into a gradedrange outputs something that contains both the label as well as the range information:
(linking #3)
After thinking about this a bit more, it seems to me that - at least for slicing operations - this should not be a real problem to support in any case, since indexing into a
gradedrange
object returns anothergradedrange
, which thus retains that information. The harder case to figure out is what "scalar indexing" should do, similar to how scalar indexing intoBlockArrays
becomes a bit more involved. The normal Julia array behavior is to drop scalar dimensions, reducing the total number of dimensions as you index. This is slightly annoying to deal with for ranges/axes that want to hold on to more information, since there you really don't want to drop these dimensions, because that would also discard the label/grading information.Effectively, I would probably advocate that for these kinds of arrays, indexing should either be "fully scalar", and if not, considered as a slicing operation.
To achieve this, effectively you would have that
a[i, ...]
would becomea[i:i, ...]
whenever not all indices are "scalar". This would also solve the issue that indexing with a scalar into a gradedrange loses the label information, as nowg[i:i]
would still output a range.The text was updated successfully, but these errors were encountered: