NDTensors.jl
NDTensors.jl copied to clipboard
Borrow some interface ideas from BlockArrays and other packages
It could be useful to adopt some interface ideas from other Julia packages that implement blocked arrays/matrices, for example:
For example, in BlockArrays.jl, the "block index" (the label of the block) has a special type Block. This allows notation like:
julia> using BlockArrays
julia> A = PseudoBlockArray(ones(3,3), [1,2], [2,1]) # A dense array split into 4 blocks
2×2-blocked 3×3 PseudoBlockArray{Float64,2}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
1.0 1.0 │ 1.0
julia> @view A[Block(2,1)] # Similar to our `blockview` function
2×2 view(::PseudoBlockArray{Float64,2,Array{Float64,2},Tuple{BlockedUnitRange{Array{Int64,1}},BlockedUnitRange{Array{Int64,1}}}}, BlockSlice(Block(2),2:3), BlockSlice(Block(1),1:2)) with eltype Float64:
1.0 1.0
1.0 1.0
julia> A[BlockIndex((2,1), (2,2))] = 2 # Set the (2,2) index of the (2,1) block
2
julia> A
2×2-blocked 3×3 PseudoBlockArray{Float64,2}:
1.0 1.0 │ 1.0
──────────┼─────
1.0 1.0 │ 1.0
1.0 2.0 │ 1.0
It would be nice to use similar concepts in NDTensors for the BlockSparseTensor and DiagBlockSparseTensor.
Note that this may be a breaking change for ITensors when it is introduced, since it would make sense for functions like nzblocks to return a vector of Block objects.
Maybe it’s kind of sneaky, but I think it’s ok to make occasional changes which are technically breaking if it’s to a part of a code that no one is (likely) relying on at the moment. Especially for the 0.x series of releases. I believe Julia itself did this a bit throughout the 0.x series and it wasn’t too bad.
Yeah, it could be a pretty silent change, if we make sure all of the functions that were using Block-like objects now accept Block, and make Block act like an NTuple in every relevant way.
I think we can have the strategy that breaking changes can happen from 0.x.y to 0.x+1.0, if we can't deprecate something (if we can deprecate, we will have warnings with the jump to 0.x+1.0, then errors in the jump to 0.x+2.0).
Some BlockArrays.jl functionality to add:
blocksize(::Tensor)- get the number of blocks in each dimension as a tuple (like our currentnblocksfunction).blocklength(::Tensor) = prod(blocksize(T))- get the total number of blocks (zero and nonzero).
Also these functions for ITensor.