def genHRfacSpatialQt(pindx, nsite, isite, int1e, int2e, qpts, pdic, maxslc=1): p, ip = pindx iop = 1 isym = 2 status = 'L' isz = p % 2 site = mpo_dmrg_opers.genHRfacSpatial(pindx, nsite, isite, int1e, int2e, qpts, pdic) # Site physical indices qu, qd = genQphys(isym, isite) # Orbital dependent part ql1e, qr1e = genElemQnums(p, 2 * isite, iop, status) ql2e, qr2e = genElemQnums(p, 2 * isite + 1, iop, status) ql1 = ql1e qr1 = qr2e ql1w, qr1w = genWfacQnums(nsite, 2 * isite, isz, status) ql2w, qr2w = genWfacQnums(nsite, 2 * isite + 1, isz, status) ql2 = ql1w qr2 = qr2w ql = [q1 + q2 for q1, q2 in itertools.product(ql1, ql2)] qr = [q1 + q2 for q1, q2 in itertools.product(qr1, qr2)] # Reduce symmetry: local spin rotation do not change particle number if ip is not None: ql = qtensor_util.reduceQnumsToN(ql) qr = qtensor_util.reduceQnumsToN(qr) qu = qtensor_util.reduceQnumsToN(qu) qd = qtensor_util.reduceQnumsToN(qd) # # We sort the internal quantum number first # nql = len(ql) nqr = len(qr) idxl = sortQnums(ql) idxr = sortQnums(qr) ql = numpy.array(ql)[idxl] qr = numpy.array(qr)[idxr] site = site[numpy.ix_(idxl, idxr)].copy() # Slice operators if necessary qts = qtensor.Qt(2) qts.maxslc[0] = min(maxslc, nql) qts.maxslc[1] = min(maxslc, nqr) qts.genDic() for islc in range(qts.maxslc[0]): slc0 = parallel_util.partitionSites(nql, qts.maxslc[0], islc) for jslc in range(qts.maxslc[1]): slc1 = parallel_util.partitionSites(nqr, qts.maxslc[1], jslc) ijdx = qts.ravel([islc, jslc]) qts.dic[ijdx] = qtensor.qtensor([False, True, False, True]) # Note that the qsyms for the last two dimensions are not collected qts.dic[ijdx].fromDenseTensor(site[numpy.ix_(slc0, slc1)], [ql[slc0], qr[slc1], qu, qd], ifcollect=[1, 1, 0, 0]) qts.size[ijdx] = qts.dic[ijdx].size_allowed return qts
def testHRfacSpatial(): # # Savings are slightly reduced due to the nonzero terms # that mix blocks with different Sz values. [2 times] # # [ 1 0 0 0 ] # R(a) = [ 0 c -s 0 ] # [ 0 -s c 0 ] # [ 0 0 0 1 ] # # p,isz,isite= 9 1 39 # hop= (162, 1, 4, 4) # site0.shape= (162, 1, 4, 4) sum= 19.4722422084 # Basic information: # rank = 4 shape= [162 1 4 4] nsyms= [4 1 3 3] # nblks_allowed = 8 nblks = 36 # size_allowed = 572 size = 2592 savings= 0.220679012346 # site1a.shape= (162, 1, 4, 4) sum= 19.4722422084 # isz,isite,diffa= 1 39 0.0 # numpy.random.seed(10) nsite = 10 nbas = nsite * 2 hmo = numpy.random.uniform(-1, 1, (nbas, nbas)) hmo[::2, 1::2] = hmo[1::2, ::2] = 0. # [ij|kl] eri = numpy.random.uniform(-1, 1, (nbas, nbas, nbas, nbas)) eri[::2, 1::2] = eri[1::2, ::2] = eri[:, :, ::2, 1::2] = eri[:, :, 1::2, ::2] = 0. # The spin symmetry is essential. # <ij|kl>=[ik|jl] eri = eri.transpose(0, 2, 1, 3) # Antisymmetry is not since only r<s is taken. # # Antisymmetrize V[pqrs]=-1/2*<pq||rs> # eri = -0.5*(eri-eri.transpose(0,1,3,2)) ta = 0. tb = 0. for p in range(nbas): isz = p % 2 for isite in range(nsite): print '\np,isz,isite=', p, isz, isite t0 = time.time() pindx = (p, 0) qpts = numpy.array([0.3]) site0 = mpo_dmrg_opers.genHRfacSpatial(pindx, nbas, isite, hmo, eri, qpts) t1 = time.time() print 'hop=', site0.shape print 'site0.shape=', site0.shape, ' sum=', numpy.sum(site0) # Wsite pdic = None #fake qt12a = genHRfacSpatialQt(pindx, nbas, isite, hmo, eri, pdic, qpts) qt12a.prt() site1a = qt12a.toDenseTensor() t2 = time.time() print 'site1a.shape=', site1a.shape, ' sum=', numpy.sum(site1a) assert site0.shape == site1a.shape diffa = numpy.linalg.norm(site0 - site1a) print 'isz,isite,diffa=', isz, isite, diffa ta += t1 - t0 tb += t2 - t1 print print 'ta =', ta print 'tb =', tb qt12a.prt() print 'qsyms=', qt12a.qsyms print 'nsyms=', qt12a.nsyms print 'idlst=', qt12a.idlst print 'vals =', qt12a.value return 0
def test_HRfac(): # LOAD MPS fname = './mps.h5' mps, qnum = mps_io.loadMPS(fname) lmps = [mps, qnum] bdim = [len(x) for x in qnum] print(' bdim = ', bdim) nsite = len(mps) qphys = mpo_dmrg_qphys.initSpatialOrb(nsite, 2) ta = 0. tb = 0. nbas = 2 * nsite # random hmo = numpy.random.uniform(-1, 1, (nbas, nbas)) hmo[::2, 1::2] = hmo[1::2, ::2] = 0. # [ij|kl] eri = numpy.random.uniform(-1, 1, (nbas, nbas, nbas, nbas)) eri[::2, 1::2] = eri[1::2, ::2] = eri[:, :, ::2, 1::2] = eri[:, :, 1::2, ::2] = 0. # The spin symmetry is essential. # <ij|kl>=[ik|jl] eri = eri.transpose(0, 2, 1, 3) maxn = 3 for p in [6, 5]: isz = p % 2 for isite in range(min(nsite, 5)): ql = qnum[isite] qn = qphys[isite] qr = qnum[isite + 1] cl = qtensor_util.classification(ql) cn = qtensor_util.classification(qn) cr = qtensor_util.classification(qr) print() print('isite/nsite=', isite, nsite) site = mps[isite] tmps = qtensor.qtensor([False, False, True]) tmps.fromDenseTensor(site, [ql, qn, qr]) print('mps site info:') tmps.prt() if isite < maxn: # Reference value: t0 = time.time() pindx = (p, 0) qpts = numpy.array([0.3]) op = mpo_dmrg_opers.genHRfacSpatial(pindx, nbas, isite, hmo, eri, qpts) print(' wop=', op.shape) #csite = numpy.einsum('lrij,ajb->lairb',op,site) csite = numpy.tensordot(op, site, axes=([3], [1])) # lriab csite = csite.transpose(0, 3, 2, 1, 4) # lriab->lairb s = csite.shape csite = csite.reshape((s[0] * s[1], s[2], s[3] * s[4])) t1 = time.time() print(' t1=', t1 - t0) # Lowering the symmetry of MPS? qop = qtensor_opers.genHRfacSpatialQt(pindx, nbas, isite, hmo, eri, qpts) # We need to change qop construction allowing given qsyms ! tmps2 = tmps.reduceQsymsToN() #tmps2 = tmps2.projectionNMs(tmps.qsyms) #diff = numpy.linalg.norm(tmps2.value-tmps.value) #print ' diff=',diff tmps2 = qtensor.tensordot(qop, tmps2, axes=([3], [1])) tmps2 = tmps2.transpose(0, 3, 2, 1, 4) tmps2 = tmps2.merge([[0, 1], [2], [3, 4]]) tsite = tmps2.toDenseTensor() t2 = time.time() print(' t2=', t2 - t1) assert csite.shape == tsite.shape diff = numpy.linalg.norm(tsite - csite) print('isite,diff=', isite, csite.shape, diff, ' t0=', t1 - t0, ' t1=', t2 - t1) assert diff < 1.e-10 ta += t1 - t0 tb += t2 - t1 else: # Reference value: t0 = time.time() pindx = (p, 0) qpts = numpy.array([0.3]) t1 = time.time() qop = qtensor_opers.genHRfacSpatialQt(pindx, nbas, isite, hmo, eri, qpts) tmps2 = tmps.reduceQsymsToN() tmps2 = qtensor.tensordot(qop, tmps2, axes=([3], [1])) print('before transposing:') tmps2.prt() tmps2 = tmps2.transpose(0, 3, 2, 1, 4) print('after transposing:') tmps2.prt() tmps2 = tmps2.merge([[0, 1], [2], [3, 4]]) print('after merging:') tmps2.prt() t2 = time.time() print('isite=', isite, ' t2=', t2 - t1) print() print('ta=', ta) print('tb=', tb) print() return 0