Allocate an ITensor with given index structure

+1 vote

Dear ITensor team,

Given an ITensor G1 with rank r and a certain index structure, for example

G1 =
ITensor r=4: ("S=1/2 51",2,Site|104)' ("S=1/2 50",2,Site|722)' ("S=1/2 50",2,Site|722) ("S=1/2 51",2,Site|104)

and another ITensor with same rank r, but different index structure, for example

G2 =
ITensor r=4: ("S=1/2 101",2,Site|215)' ("S=1/2 99",2,Site|481)' ("S=1/2 99",2,Site|481) ("S=1/2 101",2,Site|215)

what is the easiest way to take their difference or sum or contract them?

Namely I would like to create an ITensor G2-2 with the same numerical content of G2 but same index structure of G1. Is there an easy way (in version 2.1.1) to do it?
Apologises for the quite standard question but I could not find an answer in the online documentation.

Thanks a lot for your time.

Best,
Jacopo.

commented by (70.1k points)
Hi Jacopo, Matt's answer below is the right one. But I wanted to comment that if you find yourself in this situation, it's worthwhile to look more broadly at the design of your code to think about if there was another way to organize it so this situation wouldn't happen in the first place.

In my experience with ITensor, I almost never have to replace or change indices. So if you even want to post more of your code here, or a summary of it, I'd be happy to take a look and discuss the design with you.

But I do understand that there can be complicated situations where replacing indices becomes necessary. One example would be translation invariant / infinite systems, where at the end of the unit cell you want it to reconnect with the beginning, and might need to change the indices to make the connection work. But even in this case, a superior option can be to keep the indices identical only up to prime levels or tags.

Best regards,
Miles
commented by (390 points)
Dear Miles,

thanks a lot for your time. Matt answer indeed works very well!

I need to take the trace of the difference between a 2-site thermal density matrix computed with ancilla method (so on a 2*N sites chain) and the 2-site reduced density matrix computed on a chain with N sites. Since the two ITensor have different index structure I do not see another way to take their difference if not to change the index of one of them. Or maybe you know better ways to proceed?
Thanks a lot!
Jacopo
commented by (70.1k points)
Hi Jacopo, based on your explanation, I would suggest that a good idea would be to set things up so that the ITensors end up having the same index structure.

One way to do this would be to use a site set (of size N) for the physical indices for both states. Then use a separate site set for the ancilla indices of the 2N long state.

You could make the tensors of the ancilla MPS by "hand" at the beginning, using a loop pattern like:

auto psi = MPS(2*N);
for(int n = 1; n <= 2*N; ++n)
{
auto s = isodd(n) ? phys_sites(n) : anc_sites(n);
// ...
// ...
psi.setA(n,A);
}

Just an idea. It may be impractical or more trouble than it's worth though.

Miles

Hello,

An easy way to replace the indices of an ITensor is by multiplying with a series of delta tensors. If the original tensor has indices {i,j,k} and you want it changed to {a,b,c}, you can do:

G2 = G2 * delta(i,a) * delta(j,b) * delta(k,c);


In your case, {i,j,k} would be the indices of G2, and {a,b,c} would be the corresponding indices of G1.

Cheers,
Matt