# How to add two MPS of different QN blocks

Hi Miles,

I am calculating the Entanglement Entropy(EE) of a Bose-Fermi mixture chain. There are two degenerated ground states which belong to two different QN blocks ( The Bose particle number and Fermi particle number are both conservation.), one is located in the (Nb,Nf)=(22,0) Hilbert sub-space and the other is in the (Nb,Nf)=(21,1) space. The total number of sites is 36. Besides, I am using the IQMPS in the DMRG calculation.

I can do the EE calculation of the single ground state and it worked well. But I think the truly ground state |phi> is a linear combination of these two states and the coefficients can be determined by minimizing the EE (This way can be found from D.N.Sheng's paper). I try to evaluate these values and the key function used in my program is .plusEq(psi1,{"Maxm",3000,"Cutoff",1E-9}). The following is my code:

#include "itensor/all.h"
#include <fstream>
#include "itensor/decomp.h"
#include<math.h>
using namespace std;
using namespace itensor;

int main(int argc, char* argv[])
{
//Parse the input file   //DMRG parameter
if(argc != 2) { printfln("Usage: %s inputfile_bsfm",argv[0]); return 0; }
auto input = InputGroup(argv[1],"input");
auto N = input.getInt("N");       // auto N=80;

auto sites2=BF(N);
IQMPS psi2(sites2);

auto sites3=BF(N);
IQMPS psi3(sites3);

ofstream SaveFile("EE_mixed.dat");

auto pi=4*atan(1.0);
std::complex<double> z {0, 1};
auto imag=z;

auto b=36;
auto c1=0.5;
auto c2=sqrt(1-pow(c1,2));
auto fai=pi;

psi2 *= c1;
psi3 *= c2*exp(imag*fai);
auto psi=toMPS(psi2);
auto psi1=toMPS(psi3);
println("Add two states ");
// psi=psi*c1+psi1*c2*exp(i*fai)
psi.plusEq(psi1,{"Maxm",3000,"Cutoff",1E-9});

//Entanglement Entropy
printfln("\n");
println("Entanglement Entropy");

//Given an MPS or IQMPS called "psi",
//and some particular bond "b" (1 <= b < psi.N())
//across which we want to compute the von Neumann entanglement

//"Gauge" the MPS to site b

if(b%2==0){
psi.position(b);

//Here assuming an MPS of ITensors, but same code works
//for IQMPS by replacing ITensor -> IQTensor

//Compute two-site wavefunction for sites (b,b+1)
//    IQTensor wf = psi.A(b)*psi.A(b+1);
ITensor wf = psi.A(b)*psi.A(b+1);

//SVD this wavefunction to get the spectrum
//of density-matrix eigenvalues
auto U = psi.A(b);
//    IQTensor S,V;
ITensor S,V;
auto spectrum = svd(wf,U,S,V);

//Apply von Neumann formula
//spectrum.eigs() is a Vector containing
//the density matrix eigenvalues
//(squares of the singular values)
Real SvN = 0.;
for(auto p : spectrum.eigs())
{
if(p > 1E-12) SvN += -p*log(p);
}
SaveFile<<b/2<<" "<<SvN<<endl;

}

println("\n");
SaveFile.close();
return 0;
}

It can be built but something wrong when I run the code. The error message is ITensor has different index structure. I believe that the error occurred at the psi.plusEq(psi1,{"Maxm",3000,"Cutoff",1E-9}); line, because the message "Add two states" has been output on the screen but there is no "Entanglement Entropy" string. So, my question is whether it's possible to do this or are there some tricks?

Thank you.

Best,

Chenrong

answered by (7.5k points)

Hi Chenrong,

If I understand your question correctly, the short answer is that you cannot add IQMPS/IQTensors with different total QN, since it would result in an IQMPS/IQTensor with ill-defined QN flux. You should be able to convert the IQMPS to MPS using the toMPS function (http://www.itensor.org/docs.cgi?vers=cppv2&page=classes/mps ) and then add them together.

Cheers,
Matt

commented by (200 points)
Hi Matt,
Thank you for your answer.  In fact, I have converted the IQMPS to MPS in my code. As you can see in my attached file, I using the command: auto psi=toMPS(psi2) before add them.  Maybe I missed something?
best,
Chenrong
commented by (7.5k points)
Sorry, I missed that part of your code.

It looks like the problem is that you are make the MPS psi2 and psi3 from two different sitesets, sites2 and sites3. This will make the MPS have indices that won't recognize each other (they will have different index ids, which are randomly assigned when the SiteSet is made). If you just use the same SiteSet to make both MPS (i.e. sites2) then you should be able to add them.
commented by (200 points)
Hi Matt,
Thank you for your answers. I know that if use the same SiteSet to make MPS then it can be able to add them. While in my project, the two MPS ground states were calculated by using different particle number. Thus, I do the calculation separately. And this can leading the different Site index and Link index. I hope there is a way that can add them. I try to fix this by modify  the Site index and Link Index of the MPS to be the same but I failed. Is it possible to do this thing?
Sincerely,
Chenrong
commented by (200 points)
I have solved this  by modified my main program. Although the question not solved, but I  still thank you for your patients. I noticed that there are some functions about the index operation in the version 3 but it may need more changes in my code.
commented by (7.5k points)
Hi Chenrong,

In order to add two MPS, you do not need them to have the same link indices, just the same site indices. Here is a minimal example of how to do that in ITensor v2:

auto N = 10;

// Make state 1
auto sites1 = SpinHalf(N);
auto state1 = InitState(sites1,"Up");
auto psi1_qn = IQMPS(state1);

// Make state 2
auto sites2 = SpinHalf(N);
auto state2 = InitState(sites2,"Dn");
auto psi2_qn = IQMPS(state2);

auto psi1 = toMPS(psi1_qn);
auto psi2 = toMPS(psi2_qn);

// Make psi2 have the same indices
// as psi1
for(auto n : range1(N))
{
auto s1n = findtype(psi1.A(n),Site);
auto s2n = findtype(psi2.A(n),Site);
psi2.Aref(n) *= delta(s1n,s2n);
}

psi1.plusEq(psi2);

Here, we use findtype(...) to grab the site indices of MPS psi1 and MPS psi2. Then, we replace the site indices of psi2 with the site indices of psi1 using a delta function. Once the site indices are the same, the MPS can be added together.

Please let us know if you have any question about how this works. We have added some more convenient functions for doing these sorts of operations in ITensor v3, so it may be worth upgrading to make some of these things easier.

Cheers,
Matt
commented by (200 points)
Hi Matt,

Thank you. It's really helpful for me.  I modified my code by using your method and it worked well.

Best,

Chenrong