ITensors.jl
ITensors.jl copied to clipboard
Setting block of QN ITensor should check flux consistency
Right now all ITensors support setting a subblock from an array, like this
T[i=>2:3,j=>2:3] = randn(2,2)
However, while this also works in the block sparse case, it allows setting blocks inconsistent with the QN flux.
Probably the easiest way to catch this error would be to first do the assignment naively as-is, and then loop through the blocks of the ITensor that exist after the assignment was done and check the flux of those blocks are consistent.
Another nice feature would be to not set new blocks if the value being set is zero, which would allow this to work:
julia> using ITensors
julia> i = Index([QN(0) => 1, QN(1) => 1])
(dim=2|id=265) <Out>
1: QN(0) => 1
2: QN(1) => 1
julia> A = randomITensor(i', dag(i))
ITensor ord=2
(dim=2|id=265)' <Out>
1: QN(0) => 1
2: QN(1) => 1
(dim=2|id=265) <In>
1: QN(0) => 1
2: QN(1) => 1
ITensors.NDTensors.BlockSparse{Float64, Vector{Float64}, 2}
julia> using LinearAlgebra
julia> A[i' => 1:2, i => 1:2] = Matrix(I, 2, 2)
2×2 Matrix{Bool}:
1 0
0 1
julia> @show A;
A = ITensor ord=2
Dim 1: (dim=2|id=265)' <Out>
1: QN(0) => 1
2: QN(1) => 1
Dim 2: (dim=2|id=265) <In>
1: QN(0) => 1
2: QN(1) => 1
ITensors.NDTensors.BlockSparse{Float64, Vector{Float64}, 2}
2×2
Block(1, 1)
[1:1, 1:1]
1.0
Block(2, 2)
[2:2, 2:2]
1.0
Block(2, 1)
[2:2, 1:1]
0.0
Block(1, 2)
[1:1, 2:2]
0.0
but instead of erroring it would just not introduce the blocks (2,1) and (1, 2). Though I guess we would want to make sure this is desirable behavior since there may be legitimate cases where you want to introduce a block of zeros.
Note we can just add a call to checkflux which checks that all blocks have the same flux and errors if not.