Hello,
Unfortunately in ITensor V2 this is admittedly a confusing situation. The following would be one way to do this:
auto N = 4;
auto sites = SpinHalf(N);
auto init = InitState(sites);
for(auto n : range1(N))
{
init.set(n, "Up");
}
auto psi = MPS(init);
auto i = 2;
ITensor Sxi = sites.op("Sx",i);
ITensor Sxip = sites.op("Sx",i+1);
auto G = Sxi*Sxip;
PrintData(G);
The reason this works and what you tried did not is because by default, the SpinHalf
SiteSet (and other SiteSets) create indices with QNs. That means operators like sites.op("Sx",i)
must return an IQTensor. However, the "Sx" operator doesn't have a well defined QN. Through a little bit of a trick, we allow you to make this operator anyway, only so that it can get converted to an ITensor, for example using the line ITensor Sxi = sites.op("Sx",i)
. Once the operators are converted to ITensors, you can use them as you would any other ITensor, but before you convert them, the multiplication sites.op("Sx",i)*sites.op("Sx",i+1)
is not defined (which is why you get an error message mentioning QMixed
storage, which is the storage type those IQTensors are created with).
The situation is greatly improved in ITensor V3, where you can do the following:
auto N = 4;
auto sites = SpinHalf(N,{"ConserveQNs=",false});
auto init = InitState(sites);
for(auto n : range1(N))
{
init.set(n, "Up");
}
auto psi = MPS(init);
auto i = 2;
auto G = sites.op("Sx",i)*sites.op("Sx",i+1);
PrintData(G);
In ITensor V3, the IQTensor and ITensor classes have been merged, so all of the objects are ITensors. Putting {"ConserveQNs=",false}
just makes the choice of whether or not the indices have QN information and whether or not the ITensors are block sparse. We would encourage you to try out ITensor V3 (http://www.itensor.org/docs.cgi?vers=cppv3&page=upgrade2to3 ) for this and a variety of other improvements.
Cheers,
Matt