# Thermal state missing/null link index

+1 vote

I get the following error when calculating expectation values with an infinite temperature thermal state

"MPS or MPO has missing/null link index"

Everything is fine if I use gates to cool the state down from infinite temperature, but not at infinite temperature. The code was working fine before updating itensor today, it's probably been months since my last update. The following code reproduces the error.

auto sites = SpinHalf(4);
auto state = MPS(sites);
auto N = sites.length();
for(int n = 1; n <= N; n += 2)
{
auto s1 = sites(n);
auto s2 = sites(n+1);
auto wf = ITensor(s1,s2);
wf.set(s1(1),s2(2), ISqrt2);
wf.set(s1(2),s2(1), -ISqrt2);
ITensor D;
state.ref(n) = ITensor(s1);
state.ref(n+1) = ITensor(s2);
svd(wf,state.ref(n),D,state.ref(n+1));
state.ref(n) *= D;
}
Print(inner(state,state));


The error occurs in the call to inner, it seems like it comes from the "linkInds" call in the line in inner of the form

psidag.replaceLinkInds(sim(linkInds(psidag)));


Also, here is what I get if I call Print(state)

ITensor ord=2:
(dim=2|id=798|"n=1,Site,S=1/2") <Out>
1: 1 QN({"Sz",1})
2: 1 QN({"Sz",-1})
1: 1 QN({"Sz",-1})
2: 1 QN({"Sz",1})
{norm=1.00 (QDense Real)}

ITensor ord=2:
(dim=2|id=243|"n=2,Site,S=1/2") <Out>
1: 1 QN({"Sz",1})
2: 1 QN({"Sz",-1})
1: 1 QN({"Sz",-1})
2: 1 QN({"Sz",1})
{norm=1.41 (QDense Real)}

ITensor ord=2:
(dim=2|id=773|"n=3,Site,S=1/2") <Out>
1: 1 QN({"Sz",1})
2: 1 QN({"Sz",-1})
1: 1 QN({"Sz",-1})
2: 1 QN({"Sz",1})
{norm=1.00 (QDense Real)}

ITensor ord=2:
(dim=2|id=781|"n=4,Site,S=1/2") <Out>
1: 1 QN({"Sz",1})
2: 1 QN({"Sz",-1})
1: 1 QN({"Sz",-1})
2: 1 QN({"Sz",1})
{norm=1.41 (QDense Real)}


As you can see, site 1 is connected to 2, and site 3 is connected to 4, but there is no link connected site 2 to 3, and I'm thinking this is the source of the error.

I'm wondering if this is a bug, or if I should be initializing the link indices somehow? Thank you for your time.

Best,
Nick

+1 vote

Hi,

For now, you need to make sure your MPS always has link indices, even if they are trivial.

In the future, we would like to relax this constraint, since it is kind of annoying, but it would require some work to make sure all of the internal MPS code can properly handle the case where there are no link indices. This is a good example of where the current design is too strict, and a good reminder that we should loosen the restriction.

-Matt

commented by (650 points)
Hi Matt,

Thank you for the reply. Is there a simple way to create trivial link indices?

Best,
Nick
commented by (10.3k points)
You can just use auto l = Index(1, "Link") (or whatever tags you want).
commented by (650 points)
I guess I meant how can I give trivial link indices to the MPS in the code above? So what code should I add remove this error.
commented by (10.3k points)
You would start by defining your tensor like

auto wf = ITensor(l1, s1, s2, l2);

where the indices @@l1@@ and @@l2@@ are dimension 1 link indices. Then you will have to account for those indices in the rest of your code.

Hi Nick,
Matt's answer is correct, that unfortunately we require an MPS to have bond or link indices between all of its tensors for some functions to work correctly. We should lift this restriction in the future.

For now, here is a piece of code you can insert that will fix your issue. You should put it after your state MPS is defined and before the call to inner. For a non-QN-conserving code, just remove the "QN()" argument to the Index constructor making the links variables.

auto links = std::vector<Index>(N+1);
for(auto n : range(N+1))
{