What’s the canonical way to drop length 1 Indices in ITensors? Specifically, I for tensor train algorithms, it is convenient to have order-3 tensors on both ends, but with the first and last index being of length 1. Is there convenient in-place way to drop these dimensions?
Example
i1 = Index(1, "i1")
i2 = Index(10, "i1")
A = ITensor(rand(1, 10), (i1, i2))
# how to drop `i1` in-place?
Good question. Mostly what we are recommending to users is that they just contract with a (dimension 1) vector to remove unwanted indices. Even though this does more work than is necessary, it’s usually not a bottleneck in most applications. So like
D = A * onehot(i1=>1)
Alternatively, you could use the following function drop_ones to do it:
using ITensors
function drop_ones(A::ITensor)
one_inds = findall(isone,dim.(inds(A))) # dim==1 index locations
d_inds = setdiff(1:order(A),i1s) # locations of > 1 indices
a = dropdims(array(A);dims=tuple(one_inds...)) # remove dim==1 axes
return ITensor(a,inds(A)[d_inds])
end
let
i1 = Index(1, "i1")
i2 = Index(10, "i2")
A = ITensor(rand(1, 10), (i1, i2))
D = drop_ones(A)
@show D
return
end
Thanks! Love ITensors btw. Carrying around named indices really makes working with tensors a breeze. Compared to macro solutions, it’s much easier to build on top of it.