Hi Matt,
Thanks a lot for the detailed solution! I have come up with my own, just before you posted the comment.
To eliminate the extra Link index I used the delta tensor, like this:
auto spec = svd(tbond,U,S,V,{"Maxm",1});//,"ShowEigs",true});
edgeR = U*S;
edgeR *= delta(commonIndex(S,V));
I suppose that should be equivalent to what you used
psip.Aref(nmin) *= setElt(lmin(1));
Are those equivalent?
Here is my full function to cut an MPS by half and store the two halves as new MPS:
void cutMPS(MPS& psi,MPS& psi_cut_L,MPS& psi_cut_R, int bond){
//right cut begins with bond+1, left cut includes up to bond
psi.position(bond);
auto tbond = psi.A(bond)*psi.A(bond+1);
ITensor U = psi.A(bond);
ITensor S,V;
auto spec = svd(tbond,U,S,V,{"Maxm",1});//,"ShowEigs",true});
int N_L = psi_cut_L.N();
int N_R = psi_cut_R.N();
ITensor edgeR,edgeL,temp;
if ( bond != N_L ) {
throw std::invalid_argument( "bond and psi_cut.L dont match" );
}
edgeR = U*S;
edgeR *= delta(commonIndex(S,V)); //remove the unneccesery Link index of size one
psi_cut_L.setA(N_L,edgeR*delta(findtype(edgeR,Site),findtype(psi_cut_L.A(N_L),Site)));
for (int j = 1;j < N_L; ++j){
temp = psi.A(j);
psi_cut_L.setA(j,temp*delta(findtype(temp,Site),findtype(psi_cut_L.A(j),Site)));
}
edgeL = V;
edgeL *= delta(commonIndex(V,S)); //remove the unneccesery Link index of size one
psi_cut_R.setA(1,edgeL*delta(findtype(edgeL,Site),findtype(psi_cut_R.A(1),Site)));
for (int j = 2;j <= N_R; ++j){
temp = psi.A(j+bond);
psi_cut_R.setA(j,temp*delta(findtype(temp,Site),findtype(psi_cut_R.A(j),Site)));
}
psi_cut_L.position(1);
normalize(psi_cut_L);
psi_cut_R.position(1);
normalize(psi_cut_R);
}