def mapply(mpo, mps): """ apply mpo to mps, or apply mpo to mpo """ nsites = len(mpo) assert len(mps) == nsites ret = [None] * nsites if len(mps[0].shape) == 3: # mpo x mps for i in xrange(nsites): assert mpo[i].shape[2] == mps[i].shape[1] mt = N.einsum("apqb,cqd->acpbd", mpo[i], mps[i]) mt = N.reshape(mt, [ mpo[i].shape[0] * mps[i].shape[0], mpo[i].shape[1], mpo[i].shape[-1] * mps[i].shape[-1] ]) ret[i] = mt elif len(mps[0].shape) == 4: # mpo x mpo for i in xrange(nsites): assert mpo[i].shape[2] == mps[i].shape[1] mt = N.einsum("apqb,cqrd->acprbd", mpo[i], mps[i]) mt = N.reshape(mt, [ mpo[i].shape[0] * mps[i].shape[0], mpo[i].shape[1], mps[i].shape[2], mpo[i].shape[-1] * mps[i].shape[-1] ]) ret[i] = mt return ret
def create(shape, pdim, config): peps_config = np.reshape(config, shape) peps0 = zeros(shape, pdim, 1) for i in range(shape[0]): for j in range(shape[1]): peps0[i, j][peps_config[i, j], 0, 0, 0, 0] = 1. return peps0
def cpeps(peps, config): shape = peps.shape cpeps = np.empty(shape, dtype=np.object) peps_config = np.reshape(config, peps.shape) for i in range(shape[0]): for j in range(shape[1]): cpeps[i, j] = peps[i, j][peps_config[i, j], :, :, :, :] return cpeps
def aspeps(vec, shape, pdim, bond): peps0 = empty(shape, pdim, bond) assert vec.size == size(peps0) ptr = 0 for i in range(shape[0]): for j in range(shape[1]): nelem = peps0[i, j].size peps0[i, j] = np.reshape(vec[ptr:ptr + nelem], peps0[i, j].shape) ptr += nelem return peps0
def create(ops): """ Create MPO operator from a tensor product of single site operators e.g. I otimes c otimes d otimes ... """ pdim = ops[0].shape[0] assert ops[0].shape[1] == pdim return [N.reshape(op, [1, pdim, pdim, 1]) for op in ops]
def from_mps(mps): """ squaren physical indices of MPS to MPO """ pdim = int(math.sqrt(mps[0].shape[1])) assert pdim * pdim == mps[0].shape[1] return [ N.reshape(mt, [mt.shape[0], pdim, pdim, mt.shape[2]]) for mt in mps ]
def to_mps(mpo): """ flatten physical indices of MPO to MPS """ pdim = mpo[0].shape[1] assert pdim == mpo[0].shape[2] return [ N.reshape(mt, [mt.shape[0], pdim * pdim, mt.shape[3]]) for mt in mpo ]
def epeps(pepsa, pepsb): shape = pepsa.shape epeps = np.empty(shape, dtype=np.object) for i in range(shape[0]): for j in range(shape[1]): epeps[i, j] = einsum("pludr,pLUDR->lLuUdDrR", pepsa[i, j], pepsb[i, j]) eshape = epeps[i, j].shape epeps[i, j] = np.reshape( epeps[i, j], (eshape[0] * eshape[1], eshape[2] * eshape[3], eshape[4] * eshape[5], eshape[6] * eshape[7])) return epeps
def contract_cpeps(cpeps, auxbond): cmps0 = [None] * cpeps.shape[1] for i in range(cpeps.shape[1]): l, u, d, r = cpeps[0, i].shape cmps0[i] = np.reshape(cpeps[0, i], (l, u * d, r)) for i in range(1, cpeps.shape[0]): cmpo = [None] * cpeps.shape[1] for j in range(cpeps.shape[1]): cmpo[j] = cpeps[i, j] cmps0 = mpo.mapply(cmpo, cmps0) if auxbond is not None: # compress cmps0 = mps.SVDcompress(cmps0, auxbond) return mps.ceval(cmps0, [0] * cpeps.shape[1])
def check_lortho(tens): tensm = N.reshape(tens, [N.prod(tens.shape[:-1]), tens.shape[-1]]) s = N.dot(N.conj(tensm.T), tensm) return scipy.linalg.norm(s - N.eye(s.shape[0]))
def check_rortho(tens): tensm = N.reshape(tens, [tens.shape[0], N.prod(tens.shape[1:])]) s = N.dot(tensm, N.conj(tensm.T)) return scipy.linalg.norm(s - N.eye(s.shape[0]))
def compress(mps, side, trunc=1.e-12, check_canonical=False): """ inp: canonicalise MPS (or MPO) trunc=0: just canonicalise 0<trunc<1: sigma threshold trunc>1: number of renormalised vectors to keep side='l': compress LEFT-canonicalised MPS by sweeping from RIGHT to LEFT output MPS is right canonicalised i.e. CRRR side='r': reverse of 'l' returns: truncated or canonicalised MPS """ assert side in ["l", "r"] # if trunc==0, we are just doing a canonicalisation, # so skip check, otherwise, ensure mps is canonicalised if trunc != 0 and check_canonical: if side == "l": assert is_left_canonical(mps) else: assert is_right_canonical(mps) ret_mps = [] nsites = len(mps) if side == "l": res = mps[-1] else: res = mps[0] for i in xrange(1, nsites): # physical indices exclude first and last indices pdim = list(res.shape[1:-1]) if side == "l": res = N.reshape(res, (res.shape[0], N.prod(res.shape[1:]))) else: res = N.reshape(res, (N.prod(res.shape[:-1]), res.shape[-1])) if svd_iop == 0: u, sigma, vt = svd(res, full_matrices=False, lapack_driver='gesvd') else: u, sigma, vt = svd(res, full_matrices=False) if trunc == 0: m_trunc = len(sigma) elif trunc < 1.: # count how many sing vals < trunc normed_sigma = sigma / scipy.linalg.norm(sigma) m_trunc = len([s for s in normed_sigma if s > trunc]) else: m_trunc = int(trunc) m_trunc = min(m_trunc, len(sigma)) u = u[:, 0:m_trunc] sigma = N.diag(sigma[0:m_trunc]) vt = vt[0:m_trunc, :] if side == "l": u = N.dot(u, sigma) res = N.dot(mps[nsites - i - 1], u) ret_mpsi = N.reshape(vt, [m_trunc] + pdim + [vt.shape[1] / N.prod(pdim)]) else: vt = N.dot(sigma, vt) res = N.tensordot(vt, mps[i], 1) ret_mpsi = N.reshape(u, [u.shape[0] / N.prod(pdim)] + pdim + [m_trunc]) ret_mps.append(ret_mpsi) ret_mps.append(res) if side == "l": ret_mps.reverse() #fidelity = dot(ret_mps, mps)/dot(mps, mps) #print "compression fidelity:: ", fidelity return ret_mps