Implement parity string operator

+1 vote

Hi! I would like to implement the parity operator between site 1 and site j
and then measure its expectation value.
My question has two points:
- what is the syntax for writing an operator which is a product of single-site operators rather than a sum of them?
- how do I take its expectation value? Is the function overlap(psi,P,psi) a good option?

My first attempt was the following:

void Jordan_String(const IQMPS& psi, string op="N")

{

const SiteSet& sites = psi.sites();
const int L = sites.N();
string name = "<JS_i>";

for(int i=1; i<=L; i++)
{
auto ampo = AutoMPO(sites);
for(int j=1; j<=i; j++)
{
ampo += op,j;
}
auto G = toMPO<IQTensor>(ampo,{"Exact=",true}); // MPO(ampo);
auto expG = toExpH<IQTensor>(ampo,M_PI*Cplx_i);
cout << name <<' '<<i<<' '<< psiHphi(psi,expG,psi) << endl;
}
}


I tried to exponentiate the partial sum of number operators up to site i and then evaluate the expectation value with overlap.
As a result, I got nonsensical results such as:

<JS_i> 15
Real psiHphi: WARNING, dropping non-zero (=6.82255E+01) imaginary part of expectation         value.
21.8497509084841


Do you have any idea how to fix it? Thanks in advance!

+1 vote
selected by

Hi thanks for the question. We don't quite have a syntax for a product of operators across many sites (at least not in the C++ version of ITensor) if by syntax you mean something like a simple-to-use input system such as the AutoMPO system for sums of local operators.

But a good way to make such a product is to make an MPO in a custom way, by setting the individual tensors to be what you want. For the case of a product of operators, each MPO tensor on some site "j" is just the operator you want on site "j", including identity operators on sites where you don't want any non-trivial operator.

So then a pattern of code you could write would be to make an MPO on N sites;

auto m = MPO(N);


then make a for loop from 1 to N and on each site set the operator that you want using:

m.ref(j) = opj;

where opj is an ITensor with one unprimed and one primed index, both indices being the site index for site j. You can obtain many predefined operators using syntax like:

auto opj = op(sites,"Sz",j);


where sites is something like a SpinHalf or SpinOne or other "site set" object.

Please let me know if you have any questions about that process, or if you need, say, a custom operator that's not pre defined for a given site set.

Miles

commented by (170 points)
Hi, Miles! Thank you for the suggestion! Now I am trying to write the function that computes the expectation value of the parity operator between sites 1 and j (for a system of spinless fermions).
I wrote the following:

void Jordan_String(const IQMPS& psi, string oper="F", int i=0)

{
// i=0 means all sites                                                                                                                      \

const SiteSet& sites = psi.sites();
const int L = sites.N();
string name = "<JS_i>";

for (int i=1; i<=L; i++){
auto m = MPO(L);
for (int j=1; j<=L; j++){
if (j<=i) {
auto opj = op(sites,"F",j);
m.ref(j) = opj;
}
else {
auto opj = op(sites,"Id",j);
m.ref(j) = opj;
}
cout << name <<" "<<i<<" "<<psiHphi(psi,m,psi)<<endl;
}
}

}

But when I try to compile it, I still get the errors:

error: ‘op’ was not declared in this scope
error: ‘class itensor::MPOt<itensor::ITensorT<itensor::Index> >’ has no member named
‘ref’; did you mean ‘Aref’?
error: no matching function for call to ‘psiHphi(const IQMPS&,
itensor::MPOt<itensor::ITensorT<itensor::Index> >&, const IQMPS&)’

Do you know what is causing them and how to fix it?
commented by (70.1k points)
At a glance it seems like a compilation or file structuring issue. At the top of this file do you do:
#include <itensor/all.h>
using namespace itensor;

?
commented by (170 points)
Hi, yes, I write it.
commented by (70.1k points)
Ok thanks. It is some kind of compilation issue, so it can only either be a compilation error in the code itself (whether the #include and using statements are correct) or an issue with compiling and linking flags, such as those set by the Makefile and the variables in options.mk.

Since it sounds like your files and #includes are ok, please review your Makefile and ITensor options.mk settings. Have you compiled another code successfully before based on ITensor besides this one?
commented by (170 points)
Thank you for the insights! I have already compiled a few codes with ITensor. I will try to have a look at those files. The thing that puzzles me is the fact that, if I remove the above function from the code, it compiles without problems.
commented by (70.1k points)
I see – it looks like what's happened is likely that you are using an old version of ITensor then. What version are you using? Could you please update to the latest version?
commented by (170 points)
Thanks, it must be the problem, because I am using version 2, while version 3 should be available.
commented by (70.1k points)
Yes, please do use version 3 if possible. I should probably make it so that version 2 is not available anymore, since I updated to version 3 in 2019.
commented by (70.1k points)
If you have been using ITensor since then – thanks for being a long-time user!