I have an array of ITensors with the same indices: ts = [t1, t2, t3, ...]. I would like to combine them into a new ITensor with one added index, which indexes into the ITensors in the array, e.g. ts * onehot(i => 1) is equal to t1. Is there a good way to do this without converting all of the ITensors into arrays and then using the usual ITensor(arr, finds, newind)?
Interesting question. Here’s a code pattern that will do this for you, using the onehot function:
N = length(ts)
i = Index(N,"i")
its = [ts[n] * onehot(i=>n) for n=1:N]
Does that do what you want?
(Fyi, In the future we plan to add better “slicing” capabilities to ITensor that will also do something like the reverse of this (set i to different values and obtain the resulting tensors without needing to do contractions).)
Oh I see, you wanted them summed together. That makes sense. For that I would just recommend using a for loop, like this:
N = length(ts)
i = Index(N,"i")
combined = ITensor()
for n=1:N
combined += ts[n] * onehot(i=>n)
end
Another way to write that loop code would be:
combined = sum(n->ts[n]*onehot(i=>n),1:N)
Neither of the above makes an array of ITensors first, so might be a little bit cleaner and faster. Definitely slicing (in the future) would be the best of all. In a slicing system, one could make the combined tensor first then add all of the ts’s into it, without having to do separate allocations and contractions of the intermediates. So it would be faster and shorter code.