# Overlap between two MPS after time evolution

+1 vote

Hi all,

fist of all, I am using the version 1.2.

I am trying to compute the following quantity:

G{ij}(t)= < 0 | e^{iHt} * ai * e^{-iHt} * a^{\dagger}_j | 0 >

where | 0 > is the ground state of the Kitaev chain with Hamiltonian H, and a and a^{\dagger} are the usual fermionic operator. My idea is to compute the two time evolution of the two states separately:

• a^{\dagger}_j | 0 >
• |0>

in order to obtain:

• e^{-iHt} * a^{\dagger}_j | 0 >
• e^{-iHt} | 0 >.

Then I apply the operator a^{\dagger}i on the second state in order to obtain the state a{\dagger}i * e^{-iHt} | 0 >. Finally, I would like to take the bra - ket product between this two states for computing the previous quantity G_ij(t).

I attach the code:

 auto sites = Spinless(N,{"ConserveNf",false});
auto ampo = AutoMPO(sites);

for(int i=1; i<N; ++i) {
ampo += -1.0*w, "Cdag",   i,  "C", i+1;
ampo += -1.0*w, "Cdag", i+1,  "C", i;

ampo += +1.0*delta,               "C",   i,   "C", i+1;
ampo += +1.0*std::conj(delta), "Cdag", i+1,"Cdag", i;

ampo += +1.0*Uint, "Nint", i,  "Nint", i+1;
}

for(int i = 1; i <= N; ++i) {
ampo += -1.0*mu, "N", i;
}

auto H = IQMPO(ampo);
auto state = InitState(sites);

auto psi = IQMPS(state);

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

// Print the final energy reported by DMRG
printfln("\nGround State Energy = %.10f \n\n", energy);

// Time Evolution
auto tau = 0.01;
auto expH = toExpH<IQTensor>(ampo,tau*Cplx_i);

auto args = Args("Cutoff=",1E-9,"Maxm=",3000);
auto ttotal = 3.0;
auto nt = int(ttotal/tau+(1e-9*(ttotal/tau)));

for(int n = 1; n <= nt; ++n) {

for(int i = 1; i <=N; ++i) {
for(int j = i; j <=N; ++j) {

if (j > i) {

auto op_i = sites.op("Cdag",   i);
auto op_j = sites.op("Cdag",   j);

// Creating the new MPS for the ket
auto psi_ket = psi;
psi_ket.position(j);
auto new_psi_ket = op_j*psi_ket.A(j);
new_psi_ket.noprime();
psi_ket.setA(j, new_psi_ket);

// Evolving the ket
psi_ket = exactApplyMPO<IQTensor>(expH,psi_ket,args);
normalize(psi_ket);

// Evolving the state for the bra
psi = exactApplyMPO<IQTensor>(expH,psi,args);
normalize(psi);

// Replace the operator CDag in the state for the bra
psi.position(i);
auto new_psi = op_i*psi_ket.A(i);
new_psi.noprime();
psi.setA(i, new_psi);

psi.position(1);
psi_ket.position(1);

auto result = overlapC(psi, psi_ket);
Print(result);

}

}
}

printfln("MPO: Time %d, Maximum MPS bond dimension after time evolution is %d", n*tau,maxM(psi));

}


The problem is that I obtain the following error:

From line 211, file /Users/giuseppe/Desktop/iTensor/ITensor/itensor/itensor_interface.ih

Wrong number of IndexVals passed to real/cplx (expected 2, got 0)

Wrong number of IndexVals passed to real/cplx (expected 2, got 0)

Any idea?

Thank you very much.

commented by (47.7k points)
Hi, this error usually occurs when the contraction of two ITensors is supposed to result in a scalar but instead the tensor still has one or more indices. Do you know at which line of your code this error is occurring?  - Miles
commented by (240 points)
Hi Miles,

the error occurs in the overlapC function. Without that line everything seems fine.

Thank you.
commented by (47.7k points)
Thanks, I see. Did you print out the MPS psi and psi_ket to inspect whether they have compatible indices and a correct MPS structure (neighboring tensors share indices)? That’s the most likely issue because otherwise overlapC should always succeed.

Best, Miles
commented ago by (240 points)
Thanks, now it works. Actually, it was a problem with neighboring indices. Thank you very much!
commented ago by (47.7k points)
Great! Glad you got it sorted out