# Conserving difference of two bosonic species

0 votes
asked

Hello,

I am trying to make use of a U1 symmetry in my model and IQTensors to speed up the calculations. I have some conserved quantity that involves different particle types.
To be concrete, imagine two sets of bosonic sites @@a@@ and @@b@@, and a Hamiltonian that conserves the difference, i.e commutes with
$$S =\sum_x (a_x^\dagger a_x - b_x^\dagger b_x).$$
I originally defined a generic bosonic site as follows (if there is interest I would be glad to share the siteset so that it can be included in ITensor):

BosonSite(int n, Args const& args = Args::global())
{
auto d = args.getInt("d",5); //max number of bosons
auto v = stdx::reserve_vector<IndexQN>(d+1);
for (int i = 0; i <= d; ++i) {
std::string temp = nameint("n",i);
temp += "_";
temp += std::to_string(n);
v.emplace_back(Index(temp,1,Site),QN({i,1}));
}
s = IQIndex(nameint("b_site=",n),std::move(v));

}


However, that does not seems to work if I want to conserve @@S@@. I tried to modify
the QN object for the @@b@@ species by replacing

 QN({i,1})


with

 QN({-i,1}));


on the sites where the @@b@@ bosons live.

However, that does not work either, I am getting an error

IQIndex does not contain given QN block.
Aborted (core dumped)


Now, I have read the iTensor book and documentation on IQTensors, but I admit that I still do not fully understand it, so I would appreciate any help with this particular example.
Also, the model I am looking at is slightly more complicated with a spin-1/2 in addition to the two different kinds of bosons, but I am hoping that by understanding this simple case I could solve the more general problem.

Thanks

## 1 Answer

0 votes
answered by (70k points)
selected by

Best answer

Hi, thanks for the question. So in version 2 (we've made this easier in the soon to be released version 3) the way the QNs work is that they are globally defined throughout your code. They are ordered tuples of pairs of integers.

The design you'll want to then do is define your QNs like this (all of them):

QN({na,1},{nb,1},{sz,1})

where na, nb, and sz are integers that are the number of A bosons; number of B bosons; and Sz quantum number of that site. If a site consists purely of one type of boson (say "A"), that's ok: just set nb=0. Similar for if a site carries no spin, just set sz=0.

If your A and B bosons reside on different sites, I'd recommend making two different site types, which could be named ABosonSite and BBosonSite, say. Then you can write code similar to that for BasicSiteSet (see line 376 of itensor/mps/siteset.h) except have the for loop switch the site type between odd and even sites.

If you want to post your code here I'd be happy to take a look.

An alternative is that you could go ahead and switch to version 3. To do this, just do "git checkout rc3" and then "make clean" and "make" from the top level of the ITensor folder. The rc3 branch means "release candidate 3". Howver, I should caution that one of the last parts of ITensor we're taking a hard look at before we finally release version 3 happens to be site sets! We probably won't change them too much, but there's a chance we might.

The advantage of version 3, though, is the new QN design. In that version, each quantum number within a QN object has a name string that goes with it, so for a case like yours you can just make QN's like QN({"A",na,1}) for A sites and QN({"B",nb,1}) for B sites and they will mix together just fine.

Best regards,
Miles

commented by (440 points)
edited by
Hello Miles,

Thank you for the answer.
I tried what you suggest (creating two Bosonic sites A,B with QN({na,1},{nb,1}) but it does not seems to work. I still get the "IQIndex does not contain given QN block." error.
Perhaps I am still missing something.

It does work if the Hamiltonian conserves the sum of all bosons, but in that situation there is no need for me to consider them as two different species.

An example Hamiltonian which conserves the difference of A, B bosons (but not the sum):
$$H = \sum_i (a_i^\dagger a_i+b_i^\dagger b_i) + t\sum_i (a_i^\dagger a_{i+1} +b_i^\dagger b_{i+1} +H.c) + (a_2^\dagger b_2^\dagger + H.c)$$
commented by (70k points)
Oh I see, I didn’t realize your model does not conserve the number of A and B bosons separately. I thought it did. (I thought the S operator you wrote was the Hamiltonian.) so the approach I said definitely wouldn’t work for your case.

Off hand the only way I can think to do your case is to combine the A and B degrees of freedom onto a single site, then label each state by what the difference of A versus B is.

More generally, the QN system we have as you probably know is mainly useful for handling the case where there is some total number the Hamiltonian conserves which is a sum, or sum mod k, of a number defined by the state of each site. So if you can formulate your conserved quantity that way you can use the QN system to conserve it.
commented by (440 points)
edited by
Thanks!

The idea of combining the two modes into a single site did occur to me, and it seems to work.
It is not obvious to me however which approach is more efficient:
1)  having the A, B modes on different sites without any conserved quantities implementation.
2) combining A,B into a single site, which would halve the system size, but increase the local Hilbert space dimension (from say @@d@@ to @@ d^2@@). Here I can make use of the conserved quantity.

In trying to answer this question I stumbled upon another issue (let me know if I should open a separate thread for this). It appears that performing time evolution with IQTensors is slower than with ITensors!
Do you have any idea why that might be the case?

My test case is very simple. I use my BosonSite class to create a SiteSet with up to @@d@@ bosons in each site (say d=4) and evolve under a Hamiltonian that conserves the total number of bosons, which I take a simple tight-binding:
$$H = \sum_i a_i^\dagger a_i + t\sum_i (a_i^\dagger a_{i+1} +H.c)$$
I start from a product state with a single boson on one site and vacuum everywhere else and time evolve using exactApplyMPO where I use the trick to get a second order error by having a complex time-step.

The only thing I change is MPS -> IQMPS, toExpH<ITensor> -> toExpH<IQTensor>, and the version with IQTensors runs slower (whereas I expected it to be faster).
commented by (70k points)
Hi, so you're right that it's not obvious which of (1) or (2) would be faster, and which one is also depends on which algorithm you're doing and what parameters you use to control the algorithm (and how it's implemented in code etc.). So the only way to know is to do timing. Also you can think about how each one scales formally.

Best regards,
Miles