def dotMPS(self, mps, debug=False): if debug: print '\n[mpo_class.dotMPS]' assert self.nsite == mps.nsite mps2 = mps.torank2() tmps = self.dot(mps2) # # Quantum number operations if Qnums exist # qnums = None if self.qnums is not None and mps.qnums is not None: if debug: print 'Merge quantum numbers:' q1 = self.qnums q2 = mps.qnums b1 = self.bdim() b2 = mps.bdim() qnums = [0] * self.nsite for ibond in range(self.nsite): q1i = self.qnums[ibond] q2i = mps.qnums[ibond] q12 = mpo_qphys.dpt(q1i, q2i) if debug: print 'q12=', q12 # Some compressions are required to remove negative # and large q12 that exceed the allowed qnums. qnums[ibond] = copy.deepcopy(q12) # Product new MPS mps2 = mps_class.class_mps(self.nsite, sites=tmps, qphys=mps.qphys, qnums=qnums) return mps2
def qrightCanon(self, thresh=-1.e-12, Dcut=-1, debug=False): print '\n[mps_class.qrightCanon]' print ' Bdim before: ', self.bdim() assert abs(self.norm() - 1.0) < 1.e-8 sites = self.sites nsite = len(sites) link = [0] * (nsite - 1) sval = [0] * (nsite - 1) rmps = [0] * nsite qnums = [0] * nsite # Current object tsite = sites[nsite - 1].copy() # Now the symmetry is purely determined from qphys qnumr = [copy.deepcopy(self.qphys[0][0])] qnums[nsite - 1] = copy.deepcopy(qnumr) qphys = copy.deepcopy(self.qphys) # rk3 for isite in range(nsite - 1, -1, -1): s = tsite.shape d1 = s[0] d2 = s[1] * s[2] # Combine quantum numbers qphys_isite = qphys[isite] qnum1 = mpo_qphys.dpt(qphys_isite, qnumr) mat = tsite.reshape((d1, d2)).copy() classes = qnum1 if isite != 0: dwts, qred, u, sigs, vt = qparser.row_svd( mat.T.copy(), classes, thresh, Dcut) bdim = len(sigs) print ' isite/bdim=', isite, bdim rmps[isite] = u.T.reshape((bdim, s[1], s[2])).copy() qnumr = numpy.array(copy.deepcopy(qred)) qnums[isite - 1] = qnumr.copy() # Update next tsite tmp = numpy.diag(sigs).dot(vt).T.copy() link[isite - 1] = tmp.copy() #tsite = numpy.einsum('lur,rs->lus',sites[isite-1],tmp) tsite = numpy.tensordot(sites[isite - 1], tmp, axes=([2], [0])) sval[isite - 1] = sigs.copy() else: # Always cut the last one dwts, qred, u, sigs, vt = qparser.row_svd( mat.T.copy(), classes, thresh, 1) bdim = len(sigs) print ' isite/bdim=', isite, bdim assert bdim == 1 rmps[isite] = u.T.reshape((bdim, s[1], s[2])).copy() if debug: print '-' * 80 print ' Results[i]:', isite print '-' * 80 print ' dimension:', (d1, d2), '->', bdim print ' qred:', qred print ' sum of sigs2:', numpy.sum( numpy.array(sigs)**2), ' dwts:', dwts print ' sigs:\n', sigs # Final self.sites = copy.deepcopy(rmps) self.qnums = copy.deepcopy(qnums) if debug: self.prt() print ' Bdim after: ', self.bdim() return link, sval
def qleftCanon(self, thresh=-1.e-12, Dcut=-1, debug=False): print '\n[mps_class.qleftCanon]' print ' Bdim before: ', self.bdim() assert abs(self.norm() - 1.0) < 1.e-8 sites = self.sites nsite = len(sites) link = [0] * (nsite - 1) sval = [0] * (nsite - 1) lmps = [0] * nsite qnums = [0] * nsite # Current object tsite = sites[0].copy() # Now the symmetry is purely determined from qphys qnuml = [copy.deepcopy(self.qphys[0][0])] qphys = copy.deepcopy(self.qphys) # rk3 for isite in range(nsite): s = tsite.shape d1 = s[0] * s[1] d2 = s[2] # Combine quantum numbers qphys_isite = qphys[isite] qnum1 = mpo_qphys.dpt(qnuml, qphys_isite) mat = tsite.reshape((d1, d2)).copy() classes = qnum1 if isite != nsite - 1: dwts, qred, u, sigs, vt = qparser.row_svd( mat, classes, thresh, Dcut) bdim = len(sigs) print ' isite/bdim=', isite, bdim lmps[isite] = u.reshape((s[0], s[1], bdim)).copy() qnuml = numpy.array(copy.deepcopy(qred)) qnums[isite] = qnuml.copy() # Update next tsite tmp = numpy.diag(sigs).dot(vt) link[isite] = tmp.copy() #tsite = numpy.einsum('sl,lur->sur',tmp,sites[isite+1]) tsite = numpy.tensordot(tmp, sites[isite + 1], axes=([1], [0])) sval[isite] = sigs.copy() else: # Otherwise the MPS is zero, or have multiple qnumbers # (particle number breaking!) dwts, qred, u, sigs, vt = qparser.row_svd( mat, classes, thresh, 1) bdim = len(sigs) print ' isite/bdim=', isite, bdim assert bdim == 1 lmps[isite] = u.reshape((s[0], s[1], bdim)).copy() qnuml = numpy.array(copy.deepcopy(qred)) qnums[isite] = qnuml.copy() if debug: print '-' * 80 print ' Results[i]:', isite print '-' * 80 print ' dimension:', (d1, d2), '->', bdim print ' qred:', qred print ' sum of sigs2:', numpy.sum( numpy.array(sigs)**2), ' dwts:', dwts print ' sigs:\n', sigs # Final self.sites = copy.deepcopy(lmps) self.qnums = copy.deepcopy(qnums) if debug: self.prt() print ' Bdim after: ', self.bdim() return link, sval