-
Notifications
You must be signed in to change notification settings - Fork 124
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
[GradedAxes] Introduce GradedUnitRangeDual #1531
Conversation
Overall I still find there are too many kind of For instance, |
For dispatch it is helpful to have special ranges that start at one since that is used as axes by most arrays, like how Base has |
To be more specific, if we write most code in terms of One thing to consider is that dual only really makes sense for graded unit ranges, so maybe we could consider dropping |
I have no strong opinion whether there should be a However I believe dual and not dual axes should be handled on equal footing: deciding who is dual and who is not is a pure convention and they should always appear with a 1:1 ratio for contraction to be possible. If there is some gain in having both |
I realize that with the current design, there are already I will remove |
Sounds good, that's what I was going to suggest (i.e. |
I think this is now ready for |
@ogauthe I realized that one reason to keep That could be helpful since then it could make it easier to create a dual graded unit range out of the blocks of another dual graded unit range (say if you have a dual graded unit range and want to remove one of the blocks, it could make it easier to write that kind of code). |
Indeed slicing a Now, how generic I favor the second as it would make it simpler to use a |
I agree with your assessment that I think it should be valid to make a The question to me more comes down to how and when dual axes get constructed, depending on the unit range type and operation. So to be concrete, if you have a block sparse matrix However, I think it would be surprising and unnecessarily complicated if EDIT: One idea for an interface for constructing the dual type of a unit range, even if it is defined to be self-dual with function Dual(r::AbstractUnitRange)
r_dual = dual(r)
!isdual(r_dual) && return UnitRangeDual(r)
return r_dual
end though maybe would choose another implementation in practice. An interesting side comment is that this could be a new design for array wrappers in Julia, for example instead of a single We may want to define that |
This is copied from this comment: #1363 (comment): It would be nice to think through how functions like: flip(g::AbstractGradedUnitRange) = dual(gradedrange(label_dual.(blocklengths(g)))) could be written in a simpler way. One proposal would be to make this work as an implementation: flip(g::AbstractGradedUnitRange) = gradedrange(flip.(blocklengths(g))) In order to make that work, we would need to have An implementation could be the following: flip(l::LabelledInteger) = labelled(unlabel(l), flip(label(l)))
struct CategoryDual{NondualCategory<:AbstractCategory} <: AbstractCategory
nondual_category::NondualCategory
end
flip(c::AbstractCategory) = CategoryDual(dual(c))
nondual(c::AbstractCategory) = c
nondual(c::CategoryDual) = c.nondual_category
dual(c::CategoryDual) = nondual(c) In general, Additionally, EDIT: I don't think this is needed right now and may not be a good idea, just something to keep in mind for future work. |
The other problems where due to the change |
That seems simpler, for context the primary purpose of |
I fixed all the tests for Now all errors boil down to some version of g = dual(gradedrange([U1(-1) => 1, U1(1) => 2, U1(2) => 3]))
@test_broken isdual(g[Block(1)]) i.e. slicing a |
NDTensors/src/lib/BlockSparseArrays/ext/BlockSparseArraysGradedAxesExt/test/runtests.jl
Outdated
Show resolved
Hide resolved
@ogauthe this PR looks good to me, given the current type hierarchy that we are aiming for right now. I definitely get your point about there being a lot of code that needs to be defined to make all of the different unit range types work. I think there are a few potential solutions, some of which are more benign like reassessing what code can be made more generic and can get shared across unit range types or even simplified by making upstream changes to From what I can tell, at least with the current code design and organization a lot of the complexity for dealing with the different unit range types is living in Regarding slicing |
Thanks for the review. I already started working on a slicing I am pretty happy that many issues appearing in #1336 actually come from |
All tests are passing locally. The failures come from unchanged |
That's a good sign about the design, my goal with designing |
@ogauthe looks like the test failures are fixed now, is this ready to merge once the rest of the tests pass? |
yes it is |
This PR aims to simplify the use of
GradedAxes.dual
, especially to be used in aBlockSparseArray
. It proposes to remove theUnitRangeDual
type:AbstractUnitRange
is now self dualGradedUnitRange
orGradedOneTo
are cast toGradedUnitRangeDual{<:LabelledInteger,<:AbstractGradedUnitRange} <: AbstractGradedUnitRange
This should simplify slicing a
BlockSparseArray
with dual axes and allows to preserve labels or take their dual.This branch is similar to #1529 but is based on main.
Currently, this branche solves:
blocklengths(dual(...))
GradedUnitRange
behavior when slicing:DualGradedUnitRange
Meaning one can create and manipulate
BlockSparseArray
withGradedUnitRange
or its dual (not justBlockedOneTo
). Howeveraxes(a[:,:])
are stillBase.IdentityUnitRange(GradedUnitRangeDual{...})
, which creates other issues.It also adds many tests, including broken ones.
UnitRangeDual <: UnitRange
,GradedUnitRangeDual <: AbstractGradedUnitRange
, and maybeBlockedUnitRangeDual <: AbstractBlockedUnitRange
. In that case, it would be useful to define anIsDual
trait based on theisdual
function (say using SimpleTraits.jl). See https://github.com/ITensor/ITensors.jl/pull/1363/files#r1779660676 and https://github.com/ITensor/ITensors.jl/pull/1363/files#r1779708817 for examples of where that would be useful, say for generalizingblocklabels(a::UnitRangeDual)
andflip_dual(r::UnitRangeDual)
.