# std:bad_alloc when using overlap(psi_1, psi_2) to calculate the overlap between two MPS

+1 vote
edited

Here I present a minimal example that shows such problem

#include "itensor/all.h"
#include <iostream>

using namespace std;
using namespace itensor;

int main()
{
double t_ls[2] = {0.5, 0.6};
MPS psi_ls[2];

for (int i = 0; i < 2; i++){
int N = 100;
auto sites = SpinOne(N);
auto t = t_ls[i];
auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
{
ampo += t,"S+",j,"S-",j+1;
ampo += t,"S-",j,"S+",j+1;
ampo +=     "Sz",j,"Sz",j+1;
}
auto H = MPO(ampo);

//Create MPS
auto psi = MPS(sites);

//Define DMRG sweeps
auto sweeps = Sweeps(5);
sweeps.maxm() = 10,20,100,100,200;
sweeps.cutoff() = 1E-10;

auto energy = dmrg(psi, H, sweeps, {"Quiet", true});
psi_ls[i] = psi;
}

cout << overlap(psi_ls[0], psi_ls[1]) << endl;

return 0;

}


this example shows the std::bad_alloc error. However, if we modified it such that the SpinOne sites is defined outside the for-loop, as presented as follows

#include "itensor/all.h"
#include <iostream>

using namespace std;
using namespace itensor;

int main()
{
int N = 100;
auto sites = SpinOne(N);
double t_ls[2] = {0.5, 0.6};
MPS psi_ls[2];

for (int i = 0; i < 2; i++){
auto t = t_ls[i];
auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
{
ampo += t,"S+",j,"S-",j+1;
ampo += t,"S-",j,"S+",j+1;
ampo +=     "Sz",j,"Sz",j+1;
}
auto H = MPO(ampo);

//Create MPS
auto psi = MPS(sites);

//Define DMRG sweeps
auto sweeps = Sweeps(5);
sweeps.maxm() = 10,20,100,100,200;
sweeps.cutoff() = 1E-10;

auto energy = dmrg(psi, H, sweeps, {"Quiet", true});
psi_ls[i] = psi;
}

cout << overlap(psi_ls[0], psi_ls[1]) << endl;

return 0;

}


then correct answer can be given by overlap and no std:bad_alloc error occurs.

Thus I wonder why overlap fails in the first case and how to fix it ? In fact, in my problem, I got two IQMPS (psi1, psi2) and sites(sites1, sites2) read from files. Both of them correspond to the same model, but with different physical parameters, just as I showed in the minimal example above. However, since they are exported using writeToFile in different machine, there will be std:bad_alloc error when using overlap function just as the first example given above. In fact, I try to import both IQMPS and sites as follows

S1BH_NC sites1;
IQMPS psi1(sites1);

S1BH_NC sites2;
IQMPS psi2(sites2);


where S1BHNC is a self-defined sites, but overlap(psi1, psi2) still gives std:badalloc.

Hi,
An MPS is defined on a sites object. But if you define the sites object inside the for-loop, then you have two different sites objects. Thus, calculating the overlap of two MPS defined on these two sites objects is like calculating the overlap of two vectors on different Hilbert spaces. You're not supposed to do it. I guess this kind of error wasn't expected by the developer, so there is no error message.
On the other hand, when you define the sites object before the for-loop, you're using the same Hilbert space, and the overlap is well-defined.
For this reason if you're doing the same model with different parameters you should probably define a single sites object and export it to each realization of the model, so that all your MPS will be on the same Hilbert space.
Best,
Yishai

commented by (220 points)
For the case the MPS are already on different sites objects, perhaps it would be helpful to try something like:
IQMPS psi3(sites1);
psi3=psi2;
So you'll have a MPS equal to psi2 defined on the same sites object as psi1. I'm not sure it will work, but I guess it's worth trying.
commented by (650 points)
thanks Yishai, I think you are right. In fact I try to first export one common sites (corresponds to the same model) and then import it in different tasks, then my problem is solved. By the way, your proposal is not working for my task and it seems that itensor does not treat psi2 and psi3 having common sites.
commented by (220 points)