def restore_LCF(self, use_QR=True, update_r=True, diag_r=True): """Use a gauge-transformation to restore left canonical form. See restore_RCF. """ if use_QR: tm.restore_LCF_l_seq(self.A, self.l, sanity_checks=self.sanity_checks, sc_data="restore_LCF_l") else: G = sp.eye(self.D[0], dtype=self.typ) #This is actually just the number 1 for n in xrange(1, self.N + 1): self.l[n], G, Gi = tm.restore_LCF_l(self.A[n], self.l[n - 1], G, zero_tol=self.zero_tol, sanity_checks=self.sanity_checks) if self.sanity_checks: lN = tm.eps_l_noop(self.l[self.N - 1], self.A[self.N], self.A[self.N]) if not sp.allclose(lN, 1, atol=1E-12, rtol=1E-12): log.warning("Sanity Fail in restore_LCF!: l_N is bad / norm failure") if diag_r: tm.restore_LCF_r_seq(self.A, self.r, sanity_checks=self.sanity_checks, sc_data="restore_LCF_r") if self.sanity_checks: if not sp.allclose(self.r[0].A, 1, atol=1E-12, rtol=1E-12): log.warning("Sanity Fail in restore_LCF!: r_0 is bad / norm failure") log.warning("r_0 = %s", self.r[0].squeeze().real) for n in xrange(1, self.N + 1): l = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n]) if not sp.allclose(l, self.l[n], atol=1E-11, rtol=1E-11): log.warning("Sanity Fail in restore_LCF!: l_%u is bad (off by %g)", n, la.norm(l - self.l[n])) elif update_r: self.calc_r()
def restore_LCF(self): Gm1 = sp.eye(self.D[0], dtype=self.typ) #This is actually just the number 1 for n in xrange(1, self.N): self.l[n], G, Gi = tm.restore_LCF_l(self.A[n], self.l[n - 1], Gm1, zero_tol=self.zero_tol, sanity_checks=self.sanity_checks) Gm1 = G #Now do A[N]... #Apply the remaining G[N - 1] from the previous step. for s in xrange(self.q[self.N]): self.A[self.N][s] = Gm1.dot(self.A[self.N][s]) #Now finish off tm.eps_l_noop_inplace(self.l[self.N - 1], self.A[self.N], self.A[self.N], out=self.l[self.N]) #normalize GNi = 1. / sp.sqrt(self.l[self.N].squeeze().real) self.A[self.N] *= GNi self.l[self.N][:] = 1 if self.sanity_checks: lN = tm.eps_l_noop(self.l[self.N - 1], self.A[self.N], self.A[self.N]) if not sp.allclose(lN, 1, atol=1E-12, rtol=1E-12): log.warning("Sanity Fail in restore_LCF!: l_N is bad / norm failure") #diag r Gi = sp.eye(self.D[self.N], dtype=self.typ) for n in xrange(self.N, 1, -1): self.r[n - 1], Gm1, Gm1_i = tm.restore_LCF_r(self.A[n], self.r[n], Gi, self.sanity_checks) Gi = Gm1_i #Apply remaining G1i to A[1] for s in xrange(self.q[1]): self.A[1][s] = self.A[1][s].dot(Gi) #Deal with final, scalar r[0] tm.eps_r_noop_inplace(self.r[1], self.A[1], self.A[1], out=self.r[0]) if self.sanity_checks: if not sp.allclose(self.r[0], 1, atol=1E-12, rtol=1E-12): log.warning("Sanity Fail in restore_LCF!: r_0 is bad / norm failure") log.warning("r_0 = %s", self.r[0].squeeze().real) for n in xrange(1, self.N + 1): l = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n]) if not sp.allclose(l, self.l[n], atol=1E-11, rtol=1E-11): log.warning("Sanity Fail in restore_LCF!: l_%u is bad (off by %g)", n, la.norm(l - self.l[n])) log.warning((l - self.l[n]).diagonal().real)
def _excite_expect_2s_tp_sep(AL, AR, B, lL, rR, op, d, n1, n2): ls = [None] * (d + 1) ls[0] = lL rs = [None] * (d + 1) rs[-1] = rR As1 = [None] + [AL] * (n1 - 1) + [B] + [AR] * (d - n1 + 1) As2 = [None] + [AL] * (n2 - 1) + [B] + [AR] * (d - n2 + 1) for n in xrange(1, d): ls[n] = tm.eps_l_noop(ls[n - 1], As1[n], As2[n]) for n in xrange(d, 0, -1): rs[n - 1] = tm.eps_r_noop(rs[n], As1[n], As2[n]) Cs1 = [None] * (d + 1) for n in xrange(1, d): Cs1[n] = tm.calc_C_tp(op, As1[n], As1[n + 1]) res = [ m.adot(ls[n - 1], tm.eps_r_op_2s_C12_tp(rs[n + 1], Cs1[n], As2[n], As2[n + 1])) for n in xrange(1, d) ] return sp.array(res)
def expect_1s_1s(self, op1, op2, n1, n2, return_intermediates=False): """Computes the expectation value of two single site operators acting on two different sites. The result is < op1 op2 >. See expect_1s(). Requires n1 < n2. The state must be up-to-date -- see self.update()! Parameters ---------- op1 : ndarray or callable The first operator, acting on the first site. op2 : ndarray or callable The second operator, acting on the second site. n1 : int The site number of the first site. n2 : int The site number of the second site (must be > n1). return_intermediates : bool Whether to return results for intermediate sites. Returns ------- expval : complex128 or sequence of complex128 The expectation value (data type may be complex), or values if return_intermediates == True. """ if callable(op1): op1 = sp.vectorize(op1, otypes=[sp.complex128]) op1 = sp.fromfunction(op1, (self.q[n1], self.q[n1])) if callable(op2): op2 = sp.vectorize(op2, otypes=[sp.complex128]) op2 = sp.fromfunction(op2, (self.q[n2], self.q[n2])) d = n2 - n1 res = sp.zeros((d + 1), dtype=sp.complex128) lj = tm.eps_l_op_1s(self.l[n1 - 1], self.A[n1], self.A[n1], op1) if return_intermediates: res[0] = self.expect_1s(op1.dot(op1), n1) for j in xrange(1, d + 1): if return_intermediates or j == d: lj_op = tm.eps_l_op_1s(lj, self.A[n1 + j], self.A[n1 + j], op2) res[j] = m.adot(lj_op, self.r[n1 + j]) if j < d: lj = tm.eps_l_noop(lj, self.A[n1 + j], self.A[n1 + j]) if return_intermediates: return res else: return res[-1]
def calc_l(self, n_low=-1, n_high=-1): """Updates the l matrices to reflect the current state parameters self.A. Implements step 5 of the TDVP algorithm or, equivalently, eqn. (41). (arXiv:1103.0936v2 [cond-mat.str-el]) """ if n_low < 0: n_low = 1 if n_high < 0: n_high = self.N for n in xrange(n_low, n_high + 1): self.l[n] = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n])
def get_l(self, n): """Gets an l[n], even if n < 0 or n > N + 1 """ if 0 < n <= self.N + 1: return self.l[n] elif n < 1: return self.uni_l.l[(n - 1) % self.uni_l.L] else: l_m1 = self.l[self.N + 1] #this is position 0 in the block for m in (sp.arange(self.N + 2, n + 1) - 1) % self.uni_r.L: l_m1 = tm.eps_l_noop(l_m1, self.uni_r.A[m], self.uni_r.A[m]) return l_m1
def get_l(self, n): """Gets an l[n], even if n < 0 or n > N + 1 """ if 0 <= n <= self.N + 1: return self.l[n] elif n < 0: return self.l[0] else: l_m = self.l[self.N + 1] for m in xrange(self.N + 2, n + 1): l_m = tm.eps_l_noop(l_m, self.A[self.N + 1], self.A[self.N + 1]) return l_m
def calc_l(self, n_low=-1, n_high=-1): """Updates the l matrices using the current state. Implements step 5 of the TDVP algorithm or, equivalently, eqn. (41). (arXiv:1103.0936v2 [cond-mat.str-el]) """ if n_low < 0: n_low = 1 if n_high < 0: n_high = self.N super(EvoMPS_MPS_Sandwich, self).calc_l(n_low=n_low, n_high=n_high) self.l[self.N + 1] = tm.eps_l_noop(self.l[self.N], self.uni_r.A[0], self.uni_r.A[0])
def expect_string_1s(self, op, n, d): """Calculates the expectation values of finite strings with lengths 1 to d, starting at position n. """ if callable(op): op = sp.vectorize(op, otypes=[sp.complex128]) op = sp.fromfunction(op, (self.q, self.q)) res = sp.zeros((d), dtype=self.A[1].dtype) x = self.l[n - 1] for j in xrange(n, n + d + 1): Aop = sp.tensordot(op, self.A[j], axes=([1],[0])) x = tm.eps_l_noop(x, self.A[j], Aop) res[j - n - 1] = m.adot(x, self.r[j]) return res
def calc_B(self, n, set_eta=True): """Generates the B[n] tangent vector corresponding to physical evolution of the state. In other words, this returns B[n][x*] (equiv. eqn. (47) of arXiv:1103.0936v2 [cond-mat.str-el]) with x* the parameter matrices satisfying the Euler-Lagrange equations as closely as possible. In the case of Bc, use the general Bc generated in calc_B_centre(). """ if n == self.N_centre: B, eta_c = self.calc_B_centre() if set_eta: self.eta[self.N_centre] = eta_c else: l_sqrt, r_sqrt, l_sqrt_inv, r_sqrt_inv = self.calc_l_r_roots(n) if n > self.N_centre: Vsh = tm.calc_Vsh(self.A[n], r_sqrt, sanity_checks=self.sanity_checks) x = self.calc_x(n, Vsh, l_sqrt, r_sqrt, l_sqrt_inv, r_sqrt_inv, right=True) B = sp.empty_like(self.A[n]) for s in xrange(self.q[n]): B[s] = mm.mmul(l_sqrt_inv, x, mm.H(Vsh[s]), r_sqrt_inv) if self.sanity_checks: M = tm.eps_r_noop(self.r[n], B, self.A[n]) if not sp.allclose(M, 0): print "Sanity Fail in calc_B!: B_%u does not satisfy GFC!" % n else: Vsh = tm.calc_Vsh_l(self.A[n], l_sqrt, sanity_checks=self.sanity_checks) x = self.calc_x(n, Vsh, l_sqrt, r_sqrt, l_sqrt_inv, r_sqrt_inv, right=False) B = sp.empty_like(self.A[n]) for s in xrange(self.q[n]): B[s] = mm.mmul(l_sqrt_inv, mm.H(Vsh[s]), x, r_sqrt_inv) if self.sanity_checks: M = tm.eps_l_noop(self.l[n - 1], B, self.A[n]) if not sp.allclose(M, 0): print "Sanity Fail in calc_B!: B_%u does not satisfy GFC!" % n if set_eta: self.eta[n] = sp.sqrt(mm.adot(x, x)) return B
def matvec(self, x): self.calls += 1 #print self.calls t = self.tdvp n = self.n An = x.reshape((self.q[n], self.D[n - 1], self.D[n])) if n > 1: AAnm1 = tm.calc_AA(t.A[n - 1], An) Cnm1 = tm.calc_C_mat_op_AA(t.ham[n - 1], AAnm1) else: AAnm1 = None Cnm1 = None if n < t.N: AAn = tm.calc_AA(An, t.A[n + 1]) Cn = tm.calc_C_mat_op_AA(t.ham[n], AAn) else: AAn = None Cn = None res = sp.zeros_like(An) #Assuming RCF if not Cnm1 is None: for s in xrange(t.q[n]): res[s] += tm.eps_l_noop(t.l[n - 2], t.A[n - 1], Cnm1[:, s]) res[s] += self.KLnm1.dot(An[s]) res[s] = self.lm1_i.dot(res[s]) if not Cn is None: for s in xrange(t.q[n]): res[s] += tm.eps_r_noop(t.r[n + 1], Cn[s, :], t.A[n + 1]) res[s] += An[s].dot(t.K[n + 1]) #print "en = ", (sp.inner(An.conj().ravel(), res.ravel()) # / sp.inner(An.conj().ravel(), An.ravel())) return res.reshape(x.shape) * self.tau
def matvec(self, v): x = v.reshape((self.D, self.D)) if self.left: #Multiplying from the left, but x is a col. vector, so use mat_dagger Ehx = x for k in xrange(len(self.A1)): Ehx = tm.eps_l_noop(Ehx, self.A1[k], self.A2[k]) if self.pseudo: QEQhx = Ehx - self.lL * m.adot(self.rL, x) res = x - sp.exp(-1.j * self.p) * QEQhx else: res = x - sp.exp(-1.j * self.p) * Ehx else: Ex = x for k in xrange(len(self.A1) - 1, -1, -1): Ex = tm.eps_r_noop(Ex, self.A1[k], self.A2[k]) if self.pseudo: QEQx = Ex - self.rL * m.adot(self.lL, x) res = x - sp.exp(1.j * self.p) * QEQx else: res = x - sp.exp(1.j * self.p) * Ex return res.ravel()
def _excite_expect_2s_tp_sep(AL, AR, B, lL, rR, op, d, n1, n2): ls = [None] * (d + 1) ls[0] = lL rs = [None] * (d + 1) rs[-1] = rR As1 = [None] + [AL] * (n1 - 1) + [B] + [AR] * (d - n1 + 1) As2 = [None] + [AL] * (n2 - 1) + [B] + [AR] * (d - n2 + 1) for n in xrange(1, d): ls[n] = tm.eps_l_noop(ls[n - 1], As1[n], As2[n]) for n in xrange(d, 0, -1): rs[n - 1] = tm.eps_r_noop(rs[n], As1[n], As2[n]) Cs1 = [None] * (d + 1) for n in xrange(1, d): Cs1[n] = tm.calc_C_tp(op, As1[n], As1[n + 1]) res = [m.adot(ls[n - 1], tm.eps_r_op_2s_C12_tp(rs[n + 1], Cs1[n], As2[n], As2[n + 1])) for n in xrange(1, d)] return sp.array(res)
def _calc_lr_brute(self): E = np.zeros((self.D**2, self.D**2), dtype=self.typ, order='C') for s in xrange(self.q): E += sp.kron(self.A[s], self.A[s].conj()) ev, eVL, eVR = la.eig(E, left=True, right=True) i = np.argmax(ev) self.A *= 1 / sp.sqrt(ev[i]) self.l = eVL[:,i].reshape((self.D, self.D)) self.r = eVR[:,i].reshape((self.D, self.D)) norm = m.adot(self.l, self.r) self.l *= 1 / sp.sqrt(norm) self.r *= 1 / sp.sqrt(norm) log.warning("Sledgehammer:") log.warning("Left ok?: %s", np.allclose( tm.eps_l_noop(self.l, self.A, self.A), self.l)) log.warning("Right ok?: %s", np.allclose( tm.eps_r_noop(self.r, self.A, self.A), self.r))
def _calc_lr_ARPACK(self, x, tmp, calc_l=False, A1=None, A2=None, rescale=True, tol=1E-14, ncv=None, k=1): if A1 is None: A1 = self.A if A2 is None: A2 = self.A if self.D == 1: x.fill(1) if calc_l: ev = tm.eps_l_noop(x, A1, A2)[0, 0] else: ev = tm.eps_r_noop(x, A1, A2)[0, 0] if rescale and not abs(ev - 1) < tol: A1 *= 1 / sp.sqrt(ev) return x, True, 1 try: norm = la.get_blas_funcs("nrm2", [x]) except (ValueError, AttributeError): norm = np.linalg.norm n = x.size #we will scale x so that stuff doesn't get too small #start = time.clock() opE = EOp(A1, A2, calc_l) x *= n / norm(x.ravel()) try: ev, eV = las.eigs(opE, which='LM', k=k, v0=x.ravel(), tol=tol, ncv=ncv) conv = True except las.ArpackNoConvergence: log.warning("Reset! (l? %s)", calc_l) ev, eV = las.eigs(opE, which='LM', k=k, tol=tol, ncv=ncv) conv = True #print ev2 #print ev2 * ev2.conj() ind = ev.argmax() ev = np.real_if_close(ev[ind]) ev = np.asscalar(ev) eV = eV[:, ind] #remove any additional phase factor eVmean = eV.mean() eV *= sp.sqrt(sp.conj(eVmean) / eVmean) if eV.mean() < 0: eV *= -1 eV = eV.reshape(self.D, self.D) eV *= n / norm(eV.ravel()) x[:] = eV #print "splinalg: %g" % (time.clock() - start) #print "Herm? %g" % norm((eV - m.H(eV)).ravel()) #print "Norm of diff: %g" % norm((eV - x).ravel()) #print "Norms: (%g, %g)" % (norm(eV.ravel()), norm(x.ravel())) if rescale and not abs(ev - 1) < tol: A1 *= 1 / sp.sqrt(ev) if self.sanity_checks: if not A1 is A2: log.warning("Sanity check failed: Re-scaling with A1 <> A2!") if calc_l: tm.eps_l_noop_inplace(x, A1, A2, tmp) else: tm.eps_r_noop_inplace(x, A1, A2, tmp) ev = tmp.mean() / x.mean() if not abs(ev - 1) < tol: log.warning("Sanity check failed: Largest ev after re-scale = %s", ev) return x, conv, opE.calls
def calc_BHB(self, x, p, tdvp, tdvp2, prereq, M_prev=None, y_pi_prev=None, pinv_solver=None): if pinv_solver is None: pinv_solver = las.gmres if self.ham_sites == 3: V_, Vr_, Vri_, Vri_A_, C_, C_Vri_AA_, C_AAA_r_Ah_Vrih, \ C_AhAhlAA, C_AA_r_Ah_Vrih_, C_AAA_Vrh_, C_Vri_A_r_Ah_, \ C_AhlAA, C_AhlAA_conj, C_AA_Vrh, rhs10 = prereq else: C_, C_conj, V_, Vr_, Vri_, C_Vri_A_conj, C_AhlA, C_A_Vrh_, rhs10 = prereq A = tdvp.A[0] A_ = tdvp2.A[0] AA = tdvp.AA[0] l = tdvp.l[0] r_ = tdvp2.r[0] l_sqrt = tdvp.l_sqrt[0] l_sqrt_i = tdvp.l_sqrt_i[0] r__sqrt = tdvp2.r_sqrt[0] r__sqrt_i = tdvp2.r_sqrt_i[0] K__r = tdvp2.K[0] K_l = tdvp.K_left[0] pseudo = tdvp2 is tdvp B = tdvp2.get_B_from_x(x, tdvp2.Vsh[0], l_sqrt_i, r__sqrt_i) #Skip zeros due to rank-deficiency if la.norm(B) == 0: return sp.zeros_like(x), M_prev, y_pi_prev if self.sanity_checks: tst = tm.eps_r_noop(r_, B, A_) if not la.norm(tst) > self.sanity_tol: log.warning("Sanity check failed: Gauge-fixing violation! " + str(la.norm(tst))) if self.sanity_checks: B2 = np.zeros_like(B) for s in xrange(self.q): B2[s] = l_sqrt_i.dot(x.dot(Vri_[s])) if la.norm(B - B2) / la.norm(B) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad Vri!") BA_ = tm.calc_AA(B, A_) AB = tm.calc_AA(A, B) if self.ham_sites == 3: BAA_ = tm.calc_AAA_AA(BA_, A_) ABA_ = tm.calc_AAA_AA(AB, A_) AAB = tm.calc_AAA_AA(AA, B) y = tm.eps_l_noop(l, B, A) # if pseudo: # y = y - m.adot(r_, y) * l #should just = y due to gauge-fixing M = pinv_1mE(y, [A_], [A], l, r_, p=-p, left=True, pseudo=pseudo, out=M_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='M') #print m.adot(r, M) if self.sanity_checks: y2 = M - sp.exp(+1.j * p) * tm.eps_l_noop(M, A_, A) norm = la.norm(y.ravel()) if norm == 0: norm = 1 tst = la.norm(y - y2) / norm if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad M. Off by: %g", tst) # if pseudo: # M = M - l * m.adot(r_, M) Mh = M.conj().T.copy(order='C') if self.ham_sites == 3: tmp = BAA_ + sp.exp(+1.j * p) * ABA_ + sp.exp(+2.j * p) * AAB res = l_sqrt.dot(tm.eps_r_op_3s_C123_AAA456( r_, tmp, C_Vri_AA_)) #1 1D, #3, #3c else: tmp = BA_ + sp.exp(+1.j * p) * AB res = l_sqrt.dot(tm.eps_r_op_2s_AA12_C34(r_, tmp, C_Vri_A_conj)) #1, #3 OK res += sp.exp(-1.j * p) * l_sqrt_i.dot(Mh.dot(rhs10)) #10 exp = sp.exp subres = sp.zeros_like(res) eye = m.eyemat(C_.shape[2], dtype=tdvp.typ) eye2 = m.eyemat(A.shape[2], dtype=tdvp.typ) if self.ham_sites == 3: subres += exp(-2.j * p) * tm.eps_l_noop(Mh, A, C_AAA_r_Ah_Vrih) #12 subres += exp(-3.j * p) * tm.eps_l_op_2s_AA12_C34( Mh, AA, C_AAA_Vrh_) #12b for s in xrange(self.q): #subres += exp(-2.j * p) * A[s].conj().T.dot(Mh.dot(C_AAA_r_Ah_Vrih[s])) #12 subres += tm.eps_r_noop(B[s], C_AhAhlAA[s, :], Vr_) #2b subres += exp(-1.j * p) * tm.eps_l_noop( l.dot(B[s]), A, C_AA_r_Ah_Vrih_[s, :]) #4 subres += A[s].conj().T.dot( l.dot( tm.eps_r_op_2s_AA12_C34(eye2, AB, C_Vri_A_r_Ah_[ s, :, :]))) #2 -ive of that it should be.... subres += exp(-1.j * p) * tm.eps_l_op_2s_AA12_C34( eye2, C_AhlAA_conj[s, :, :], BA_).dot(Vr_[s].conj().T) #4b subres += exp(-2.j * p) * tm.eps_l_op_2s_AA12_C34( l.dot(B[s]), AA, C_AA_Vrh[s, :, :]) #4c subres += exp(+1.j * p) * tm.eps_r_op_2s_AA12_C34( r_.dot_left(B[s]), C_AhlAA[s, :, :], Vri_A_) #3b #for t in xrange(self.q): #subres += (C_AhAhlAA[t, s].dot(B[s]).dot(Vr_[t].conj().T)) #2b #subres += (exp(-1.j * p) * A[s].conj().T.dot(l.dot(B[t])).dot(C_AA_r_Ah_Vrih_[s, t])) #4 #subres += (exp(-3.j * p) * AA[t, s].conj().T.dot(Mh).dot(C_AAA_Vrh_[t, s])) #12b #for u in xrange(self.q): #subres += A[s].conj().T.dot(l.dot(AB[t, u]).dot(C_A_r_Ah_Vrih[s, t, u])) #2 -ive of that it should be.... #subres += (exp(+1.j * p) * C_AhlAA[t, s, s].dot(B[u]).dot(r_.dot(A_[u].conj().T)).dot(Vri_[t].conj().T)) #3b #subres += (exp(-1.j * p) * C_AhAhlA[s, t, u].dot(BA_[t, u]).dot(Vr_[s].conj().T)) #4b #subres += (exp(-2.j * p) * AA[t, s].conj().T.dot(l.dot(B[u])).dot(C_AA_Vrh[t, s, u])) #4c else: for s in xrange(self.q): #subres += C_AhlA[s, t].dot(B[s]).dot(Vr_[t].conj().T) #2 OK subres += tm.eps_r_noop(B[s], C_AhlA[s, :], Vr_) #2 #+ exp(-1.j * p) * A[t].conj().T.dot(l.dot(B[s])).dot(C_A_Vrh_[t, s]) #4 OK with 3 subres += exp(-1.j * p) * tm.eps_l_noop( l.dot(B[s]), A, C_A_Vrh_[s, :]) #4 #+ exp(-2.j * p) * A[s].conj().T.dot(Mh.dot(C_[s, t])).dot(Vr_[t].conj().T)) #12 subres += exp(-2.j * p) * A[s].conj().T.dot(Mh).dot( tm.eps_r_noop(eye, C_[s, :], Vr_)) #12 res += l_sqrt_i.dot(subres) res += l_sqrt.dot(tm.eps_r_noop(K__r, B, Vri_)) #5 res += l_sqrt_i.dot(K_l.dot(tm.eps_r_noop(r__sqrt, B, V_))) #6 res += sp.exp(-1.j * p) * l_sqrt_i.dot( Mh.dot(tm.eps_r_noop(K__r, A_, Vri_))) #8 y1 = sp.exp(+1.j * p) * tm.eps_r_noop(K__r, B, A_) #7 if self.ham_sites == 3: tmp = sp.exp(+1.j * p) * BAA_ + sp.exp(+2.j * p) * ABA_ + sp.exp( +3.j * p) * AAB #9, #11, #11b y = y1 + tm.eps_r_op_3s_C123_AAA456(r_, tmp, C_) elif self.ham_sites == 2: tmp = sp.exp(+1.j * p) * BA_ + sp.exp(+2.j * p) * AB #9, #11 y = y1 + tm.eps_r_op_2s_AA12_C34(r_, tmp, C_conj) if pseudo: y = y - m.adot(l, y) * r_ y_pi = pinv_1mE(y, [A], [A_], l, r_, p=p, left=False, pseudo=pseudo, out=y_pi_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='y_pi') #print m.adot(l, y_pi) if self.sanity_checks: z = y_pi - sp.exp(+1.j * p) * tm.eps_r_noop(y_pi, A, A_) tst = la.norm((y - z).ravel()) / la.norm(y.ravel()) if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad x_pi. Off by: %g", tst) res += l_sqrt.dot(tm.eps_r_noop(y_pi, A, Vri_)) if self.sanity_checks: expval = m.adot(x, res) / m.adot(x, x) #print "expval = " + str(expval) if expval < -self.sanity_tol: log.warning( "Sanity Fail in calc_BHB! H is not pos. semi-definite (%s)", expval) if abs(expval.imag) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not Hermitian (%s)", expval) return res, M, y_pi
def calc_BHB(self, x, p, tdvp, tdvp2, prereq, M_prev=None, y_pi_prev=None, pinv_solver=None): if pinv_solver is None: pinv_solver = las.gmres if self.ham_sites == 3: return else: V_, AhlAo1, A_o2c, Ao1, Ao1c, A_Vr_ho2, A_A_o12c, rhs10, _ham_tp = prereq A = tdvp.A[0] A_ = tdvp2.A[0] l = tdvp.l[0] r_ = tdvp2.r[0] l_sqrt = tdvp.l_sqrt[0] l_sqrt_i = tdvp.l_sqrt_i[0] r__sqrt = tdvp2.r_sqrt[0] r__sqrt_i = tdvp2.r_sqrt_i[0] K__r = tdvp2.K[0] K_l = tdvp.K_left[0] pseudo = tdvp2 is tdvp B = tdvp2.get_B_from_x(x, tdvp2.Vsh[0], l_sqrt_i, r__sqrt_i) #Skip zeros due to rank-deficiency if la.norm(B) == 0: return sp.zeros_like(x), M_prev, y_pi_prev if self.sanity_checks: tst = tm.eps_r_noop(r_, B, A_) if not la.norm(tst) > self.sanity_tol: log.warning("Sanity check failed: Gauge-fixing violation! " + str(la.norm(tst))) if self.sanity_checks: B2 = np.zeros_like(B) for s in xrange(self.q): B2[s] = l_sqrt_i.dot(x.dot(m.mmul(V_[s], r__sqrt_i))) if la.norm(B - B2) / la.norm(B) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad Vri!") y = tm.eps_l_noop(l, B, A) # if pseudo: # y = y - m.adot(r_, y) * l #should just = y due to gauge-fixing M = pinv_1mE(y, [A_], [A], l, r_, p=-p, left=True, pseudo=pseudo, out=M_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='M') #print m.adot(r, M) if self.sanity_checks: y2 = M - sp.exp(+1.j * p) * tm.eps_l_noop(M, A_, A) norm = la.norm(y.ravel()) if norm == 0: norm = 1 tst = la.norm(y - y2) / norm if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad M. Off by: %g", tst) # if pseudo: # M = M - l * m.adot(r_, M) Mh = M.conj().T.copy(order='C') res_ls = 0 res_lsi = 0 exp = sp.exp if self.ham_sites == 3: pass else: Bo1 = get_Aop(B, _ham_tp, 2, conj=False) tmp = sp.empty((B.shape[1], V_.shape[1]), dtype=A.dtype, order='C') tmp2 = sp.empty((A_.shape[1], A_o2c[0].shape[1]), dtype=A.dtype, order='C') tmp3 = sp.empty_like(tmp2, order='C') for al in xrange(len(Bo1)): tmp3 = m.dot_inplace( tm.eps_r_noop_inplace(r_, A_, A_o2c[al], tmp2), r__sqrt_i, tmp3) res_ls += tm.eps_r_noop_inplace(tmp3, Bo1[al], V_, tmp) #1 tmp3 = m.dot_inplace( tm.eps_r_noop_inplace(r_, B, A_o2c[al], tmp2), r__sqrt_i, tmp3) tmp = tm.eps_r_noop_inplace(tmp3, Ao1[al], V_, tmp) #3 tmp *= exp(+1.j * p) res_ls += tmp del (tmp) del (tmp2) del (tmp3) res_lsi += sp.exp(-1.j * p) * Mh.dot(rhs10) #10 if self.ham_sites == 3: pass else: Bo2 = get_Aop(B, _ham_tp, 3, conj=False) for al in xrange(len(AhlAo1)): res_lsi += AhlAo1[al].dot(tm.eps_r_noop(r__sqrt, Bo2[al], V_)) #2 res_lsi += exp(-1.j * p) * tm.eps_l_noop(l, Ao1c[al], B).dot( A_Vr_ho2[al]) #4 res_lsi += exp(-2.j * p) * tm.eps_l_noop(Mh, Ao1c[al], A_).dot( A_Vr_ho2[al]) #12 K__rri = m.mmul(K__r, r__sqrt_i) res_ls += tm.eps_r_noop(K__rri, B, V_) #5 res_lsi += K_l.dot(tm.eps_r_noop(r__sqrt, B, V_)) #6 res_lsi += sp.exp(-1.j * p) * Mh.dot(tm.eps_r_noop(K__rri, A_, V_)) #8 y1 = sp.exp(+1.j * p) * tm.eps_r_noop(K__r, B, A_) #7 if self.ham_sites == 3: pass elif self.ham_sites == 2: tmp = 0 for al in xrange(len(A_A_o12c)): tmp += sp.exp(+1.j * p) * tm.eps_r_noop( tm.eps_r_noop(r_, A_, A_A_o12c[al][1]), B, A_A_o12c[al][0]) #9 tmp += sp.exp(+2.j * p) * tm.eps_r_noop( tm.eps_r_noop(r_, B, A_A_o12c[al][1]), A, A_A_o12c[al][0]) #11 y = y1 + tmp #7, 9, 11 del (tmp) if pseudo: y = y - m.adot(l, y) * r_ y_pi = pinv_1mE(y, [A], [A_], l, r_, p=p, left=False, pseudo=pseudo, out=y_pi_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='y_pi') #print m.adot(l, y_pi) if self.sanity_checks: z = y_pi - sp.exp(+1.j * p) * tm.eps_r_noop(y_pi, A, A_) tst = la.norm((y - z).ravel()) / la.norm(y.ravel()) if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad x_pi. Off by: %g", tst) res_ls += tm.eps_r_noop(m.mmul(y_pi, r__sqrt_i), A, V_) res = l_sqrt.dot(res_ls) res += l_sqrt_i.dot(res_lsi) if self.sanity_checks: expval = m.adot(x, res) / m.adot(x, x) #print "expval = " + str(expval) if expval < -self.sanity_tol: log.warning( "Sanity Fail in calc_BHB! H is not pos. semi-definite (%s)", expval) if abs(expval.imag) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not Hermitian (%s)", expval) return res, M, y_pi
def calc_lr(self): """Determines the dominant left and right eigenvectors of the transfer operator E. Uses an iterative method (e.g. Arnoldi iteration) to determine the largest eigenvalue and the correspoinding left and right eigenvectors, which are stored as self.l and self.r respectively. The parameter tensor self.A is rescaled so that the largest eigenvalue is equal to 1 (thus normalizing the state). The largest eigenvalue is assumed to be non-degenerate. """ tmp = np.empty_like(self.tmp) #Make sure... self.l_before_CF = np.asarray(self.l_before_CF) self.r_before_CF = np.asarray(self.r_before_CF) if self.ev_use_arpack: self.l, self.conv_l, self.itr_l = self._calc_lr_ARPACK(self.l_before_CF, tmp, calc_l=True, tol=self.itr_rtol, k=self.ev_arpack_nev, ncv=self.ev_arpack_ncv) else: self.l, self.conv_l, self.itr_l = self._calc_lr(self.l_before_CF, tmp, calc_l=True, max_itr=self.pow_itr_max, rtol=self.itr_rtol, atol=self.itr_atol) self.l_before_CF = self.l.copy() if self.ev_use_arpack: self.r, self.conv_r, self.itr_r = self._calc_lr_ARPACK(self.r_before_CF, tmp, calc_l=False, tol=self.itr_rtol, k=self.ev_arpack_nev, ncv=self.ev_arpack_ncv) else: self.r, self.conv_r, self.itr_r = self._calc_lr(self.r_before_CF, tmp, calc_l=False, max_itr=self.pow_itr_max, rtol=self.itr_rtol, atol=self.itr_atol) self.r_before_CF = self.r.copy() #normalize eigenvectors: if self.symm_gauge: norm = m.adot(self.l, self.r).real itr = 0 while not np.allclose(norm, 1, atol=1E-13, rtol=0) and itr < 10: self.l *= 1. / ma.sqrt(norm) self.r *= 1. / ma.sqrt(norm) norm = m.adot(self.l, self.r).real itr += 1 if itr == 10: log.warning("Warning: Max. iterations reached during normalization!") else: fac = self.D / np.trace(self.r).real self.l *= 1 / fac self.r *= fac norm = m.adot(self.l, self.r).real itr = 0 while not np.allclose(norm, 1, atol=1E-13, rtol=0) and itr < 10: self.l *= 1. / norm norm = m.adot(self.l, self.r).real itr += 1 if itr == 10: log.warning("Warning: Max. iterations reached during normalization!") if self.sanity_checks: if not np.allclose(tm.eps_l_noop(self.l, self.A, self.A), self.l, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Left eigenvector bad! Off by: %s", la.norm(tm.eps_l_noop(self.l, self.A, self.A) - self.l)) if not np.allclose(tm.eps_r_noop(self.r, self.A, self.A), self.r, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Right eigenvector bad! Off by: %s", la.norm(tm.eps_r_noop(self.r, self.A, self.A) - self.r)) if not np.allclose(self.l, m.H(self.l), rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: l is not hermitian!") if not np.allclose(self.r, m.H(self.r), rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: r is not hermitian!") if not np.all(la.eigvalsh(self.l) > 0): log.warning("Sanity check failed: l is not pos. def.!") if not np.all(la.eigvalsh(self.r) > 0): log.warning("Sanity check failed: r is not pos. def.!") norm = m.adot(self.l, self.r) if not np.allclose(norm, 1.0, atol=1E-13, rtol=0): log.warning("Sanity check failed: Bad norm = %s", norm)
def restore_SCF(self, ret_g=False, zero_tol=None): """Restores symmetric canonical form. In this canonical form, self.l == self.r and are diagonal matrices with the Schmidt coefficients corresponding to the half-chain decomposition form the diagonal entries. Parameters ---------- ret_g : bool Whether to return the gauge-transformation matrices used. Returns ------- g, g_i : ndarray Gauge transformation matrix g and its inverse g_i. """ if zero_tol is None: zero_tol = self.zero_tol X, Xi = tm.herm_fac_with_inv(self.r, lower=True, zero_tol=zero_tol) Y, Yi = tm.herm_fac_with_inv(self.l, lower=False, zero_tol=zero_tol) U, sv, Vh = la.svd(Y.dot(X)) #s contains the Schmidt coefficients, lam = sv**2 self.S_hc = - np.sum(lam * sp.log2(lam)) S = m.simple_diag_matrix(sv, dtype=self.typ) Srt = S.sqrt() g = m.mmul(Srt, Vh, Xi) g_i = m.mmul(Yi, U, Srt) for s in xrange(self.q): self.A[s] = m.mmul(g, self.A[s], g_i) if self.sanity_checks: Sfull = np.asarray(S) if not np.allclose(g.dot(g_i), np.eye(self.D)): log.warning("Sanity check failed! Restore_SCF, bad GT!") l = m.mmul(m.H(g_i), self.l, g_i) r = m.mmul(g, self.r, m.H(g)) if not np.allclose(Sfull, l): log.warning("Sanity check failed: Restorce_SCF, left failed!") if not np.allclose(Sfull, r): log.warning("Sanity check failed: Restorce_SCF, right failed!") l = tm.eps_l_noop(Sfull, self.A, self.A) r = tm.eps_r_noop(Sfull, self.A, self.A) if not np.allclose(Sfull, l, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Restorce_SCF, left bad!") if not np.allclose(Sfull, r, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Restorce_SCF, right bad!") self.l = S self.r = S if ret_g: return g, g_i else: return
def restore_LCF(self): Gm1 = sp.eye(self.D[0], dtype=self.typ) #This is actually just the number 1 for n in xrange(1, self.N): self.l[n], G, Gi = tm.restore_LCF_l( self.A[n], self.l[n - 1], Gm1, zero_tol=self.zero_tol, sanity_checks=self.sanity_checks) Gm1 = G #Now do A[N]... #Apply the remaining G[N - 1] from the previous step. for s in xrange(self.q[self.N]): self.A[self.N][s] = Gm1.dot(self.A[self.N][s]) #Now finish off tm.eps_l_noop_inplace(self.l[self.N - 1], self.A[self.N], self.A[self.N], out=self.l[self.N]) #normalize GNi = 1. / sp.sqrt(self.l[self.N].squeeze().real) self.A[self.N] *= GNi self.l[self.N][:] = 1 if self.sanity_checks: lN = tm.eps_l_noop(self.l[self.N - 1], self.A[self.N], self.A[self.N]) if not sp.allclose(lN, 1, atol=1E-12, rtol=1E-12): log.warning( "Sanity Fail in restore_LCF!: l_N is bad / norm failure") #diag r Gi = sp.eye(self.D[self.N], dtype=self.typ) for n in xrange(self.N, 1, -1): self.r[n - 1], Gm1, Gm1_i = tm.restore_LCF_r( self.A[n], self.r[n], Gi, self.sanity_checks) Gi = Gm1_i #Apply remaining G1i to A[1] for s in xrange(self.q[1]): self.A[1][s] = self.A[1][s].dot(Gi) #Deal with final, scalar r[0] tm.eps_r_noop_inplace(self.r[1], self.A[1], self.A[1], out=self.r[0]) if self.sanity_checks: if not sp.allclose(self.r[0], 1, atol=1E-12, rtol=1E-12): log.warning( "Sanity Fail in restore_LCF!: r_0 is bad / norm failure") log.warning("r_0 = %s", self.r[0].squeeze().real) for n in xrange(1, self.N + 1): l = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n]) if not sp.allclose(l, self.l[n], atol=1E-11, rtol=1E-11): log.warning( "Sanity Fail in restore_LCF!: l_%u is bad (off by %g)", n, la.norm(l - self.l[n])) log.warning((l - self.l[n]).diagonal().real)
def restore_RCF(self, ret_g=False, zero_tol=None): """Restores right canonical form. In this form, self.r = sp.eye(self.D) and self.l is diagonal, with the squared Schmidt coefficients corresponding to the half-chain decomposition as eigenvalues. Parameters ---------- ret_g : bool Whether to return the gauge-transformation matrices used. Returns ------- g, g_i : ndarray Gauge transformation matrix g and its inverse g_i. """ if zero_tol is None: zero_tol = self.zero_tol #First get G such that r = eye G, G_i, rank = tm.herm_fac_with_inv(self.r, lower=True, zero_tol=zero_tol, return_rank=True) self.l = m.mmul(m.H(G), self.l, G) #Now bring l into diagonal form, trace = 1 (guaranteed by r = eye..?) ev, EV = la.eigh(self.l) G = G.dot(EV) G_i = m.H(EV).dot(G_i) for s in xrange(self.q): self.A[s] = m.mmul(G_i, self.A[s], G) #ev contains the squares of the Schmidt coefficients, self.S_hc = - np.sum(ev * sp.log2(ev)) self.l = m.simple_diag_matrix(ev, dtype=self.typ) r_old = self.r if rank == self.D: self.r = m.eyemat(self.D, self.typ) else: self.r = sp.zeros((self.D), dtype=self.typ) self.r[-rank:] = 1 self.r = m.simple_diag_matrix(self.r, dtype=self.typ) if self.sanity_checks: r_ = m.mmul(G_i, r_old, m.H(G_i)) if not np.allclose(self.r, r_, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: RestoreRCF, bad r (bad GT).") l = tm.eps_l_noop(self.l, self.A, self.A) r = tm.eps_r_noop(self.r, self.A, self.A) if not np.allclose(r, self.r, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Restore_RCF, r not eigenvector! %s", la.norm(r - self.r)) if not np.allclose(l, self.l, rtol=self.itr_rtol*self.check_fac, atol=self.itr_atol*self.check_fac): log.warning("Sanity check failed: Restore_RCF, l not eigenvector! %s", la.norm(l - self.l)) if ret_g: return G, G_i else: return
def _excite_correlation_1s_1s(AL, AR, B, lL, rR, op1, op2, d, g): pseudo = AL is AR BBL = pinv_1mE(tm.eps_l_noop(lL, B, B), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) B1L = pinv_1mE(tm.eps_l_noop(lL, B, AL), [AR], [AL], lL, rR, p=0, left=True, pseudo=pseudo) B2L = pinv_1mE(tm.eps_l_noop(lL, AL, B), [AL], [AR], lL, rR, p=0, left=True, pseudo=pseudo) B1B2L = pinv_1mE(tm.eps_l_noop(B1L, AR, B), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) B2B1L = pinv_1mE(tm.eps_l_noop(B2L, B, AR), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) BBR = pinv_1mE(tm.eps_r_noop(rR, B, B), [AL], [AL], lL, rR, p=0, left=False, pseudo=True) print "gauge fixing:", la.norm(tm.eps_r_noop(rR, B, AR)) res = [0.] * (d + 1) #B's on the left terms (0, 1, 2, 5) res[0] += m.adot( tm.eps_l_op_1s(BBL + B1B2L + B2B1L, AR, AR, op1.dot(op2) - g[0] * sp.eye(len(op1))), rR) res[0] += m.adot(tm.eps_l_op_1s(B1L, AR, B, op1.dot(op2)), rR) res[0] += m.adot(tm.eps_l_op_1s(B2L, B, AR, op1.dot(op2)), rR) res[0] += m.adot( tm.eps_l_op_1s(lL, B, B, op1.dot(op2) - g[0] * sp.eye(len(op1))), rR) l1 = tm.eps_l_op_1s(BBL + B1B2L + B2B1L, AR, AR, op1) l1 += tm.eps_l_op_1s(B1L, AR, B, op1) l1 += tm.eps_l_op_1s(B2L, B, AR, op1) l1 += tm.eps_l_op_1s(lL, B, B, op1) for n in xrange(1, d + 1): res[n] += m.adot(l1, tm.eps_r_op_1s(rR, AR, AR, op2)) res[n] -= 2 * g[n] if n == d: break l1 = tm.eps_l_noop(l1, AR, AR) print 1, res #Terms 3, 4, 6, 7, a ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(B1L, AR, AL, op1) + tm.eps_l_op_1s(lL, B, AL, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AR, AL) rs = [None] * (d + 1) rs[d - 1] = tm.eps_r_op_1s(rR, AR, AR, op2) for k in xrange(d - 1, 0, -1): rs[k - 1] = tm.eps_r_noop(rs[k], AR, AR) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], AR, B)) res[n] += m.adot(ls[n - 1], tm.eps_r_op_1s(rR, AR, B, op2)) print 2, res #Terms 3, 4, 6, 7, b ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(B2L, AL, AR, op1) + tm.eps_l_op_1s(lL, AL, B, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AL, AR) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], B, AR)) res[n] += m.adot(ls[n - 1], tm.eps_r_op_1s(rR, B, AR, op2)) print 3, res #Term 8 ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(lL, AL, AL, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AL, AL) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], B, B)) res[n] -= g[n] print 4, res #Terms 9 and 10 for n in xrange(2, d + 1): for k in xrange(2, n): lj = tm.eps_l_noop(ls[k - 1], AL, B) for j in xrange(k + 1, n): res[n] += m.adot(lj, tm.eps_r_noop(rs[-(n + 1):][j], B, AR)) lj = tm.eps_l_noop(lj, AL, AR) res[n] += m.adot(lj, tm.eps_r_op_1s(rR, B, AR, op2)) lj = tm.eps_l_noop(ls[k - 1], B, AL) for j in xrange(k + 1, n): res[n] += m.adot(lj, tm.eps_r_noop(rs[-(n + 1):][j], AR, B)) lj = tm.eps_l_noop(lj, AL, AR) res[n] += m.adot(lj, tm.eps_r_op_1s(rR, AR, B, op2)) print 5, res #Term 11 res[0] += m.adot( tm.eps_l_op_1s(lL, AL, AL, op1.dot(op2) - g[0] * sp.eye(len(op1))), BBR) for n in xrange(1, d + 1): res[n] += m.adot(tm.eps_l_op_1s(ls[n - 1], AL, AL, op2), BBR) res[n] -= g[n] return res
def restore_CF(self, dbg=False): if dbg: self.calc_l() self.calc_r() self.simple_renorm() print "BEFORE..." h_before, h_left_before, h_right_before = self.restore_CF_dbg() print (h_left_before, h_before, h_right_before) self.uni_l.A = self.uni_l.A #.copy() #self.uni_l.l = self.uni_l.l.copy() #r_old = self.uni_l.r.copy() self.uni_l.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_l calc_lr iterations: ", (self.uni_l.itr_l, self.uni_l.itr_r) #uniform calc_lr() scales for RCF, but we have LCF, #so we have to correct the scaling here fac = self.uni_l.D / self.uni_l.l.trace().real if dbg: print "Scale l[0]: %g" % fac self.uni_l.l *= fac self.uni_l.r *= 1/fac # if self.sanity_checks: # if not sp.allclose(self.uni_l.l, self.l[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: True l[0] and l[L] mismatch!", la.norm(self.l[0] - self.uni_l.l) # # if not sp.allclose(self.uni_l.r, r_old, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad r[L]!", la.norm(r_old - self.uni_l.r) # # if not sp.allclose(self.uni_l.A, self.A[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[0] was scaled!", la.norm(self.A[0] - self.uni_l.A) #self.uni_l.l = self.l[0] #self.uni_l.r = r_old #self.uni_l.A = self.A[0] self.l[0] = self.uni_l.l self.A[0] = self.uni_l.A self.uni_r.A = self.uni_r.A #.copy() self.uni_r.r = self.uni_r.r #.copy() #l_old = self.uni_r.l.copy() self.uni_r.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_r calc_lr iterations: ", (self.uni_r.itr_l, self.uni_r.itr_r) # if self.sanity_checks: # if not sp.allclose(self.uni_r.A, self.A[self.N + 1], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[R] was scaled! ", la.norm(self.A[self.N + 1] - self.uni_r.A) # # if not sp.allclose(l_old, self.uni_r.l, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad l[R]! ", la.norm(l_old - self.uni_r.l) # # if not sp.allclose(self.r[self.N], self.uni_r.r, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: r[N] and r[R] mismatch!", la.norm(self.r[self.N] - self.uni_r.r) self.r[self.N] = self.uni_r.r self.A[self.N + 1] = self.uni_r.A self._restore_CF_ONR() nc = self.N_centre self.r[nc - 1] = tm.eps_r_noop(self.r[nc], self.A[nc], self.A[nc]) self.simple_renorm(update_lr=False) if dbg: self.calc_l() self.calc_r() print "AFTER ONR..." h_mid, h_left_mid, h_right_mid = self.restore_CF_dbg() print (h_left_mid, h_mid, h_right_mid) self._restore_CF_diag() #l[0] is identity, r_L = ? self.uni_l.A = self.A[0] self.uni_l.l = self.l[0] self.uni_l.l_before_CF = self.uni_l.l self.uni_l.r_before_CF = self.uni_l.r #r[N] is identity, l_R = ? self.uni_r.A = self.A[self.N + 1] self.uni_r.r = self.r[self.N] self.uni_r.l_before_CF = self.uni_r.l self.uni_r.r_before_CF = self.uni_r.r #Set l[N + 1] as well... self.l[self.N + 1][:] = tm.eps_l_noop(self.l[self.N], self.A[self.N + 1], self.A[self.N + 1]) if self.sanity_checks: l_n = self.l[0] for n in xrange(0, self.N + 1): l_n = tm.eps_l_noop(l_n, self.A[n], self.A[n]) if not sp.allclose(l_n, self.l[n], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: l_%u is bad" % n r_nm1 = self.r[self.N + 1] for n in reversed(xrange(1, self.N + 2)): r_nm1 = tm.eps_r_noop(r_nm1, self.A[n], self.A[n]) if not sp.allclose(r_nm1, self.r[n - 1], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: r_%u is bad" % (n - 1) if dbg: print "AFTER..." h_after, h_left_after, h_right_after = self.restore_CF_dbg() print (h_left_after, h_after, h_right_after) print h_after - h_before print (h_after.sum() - h_before.sum() + h_left_after - h_left_before + h_right_after - h_right_before)
def calc_BHB(self, x, p, tdvp, tdvp2, prereq, M_prev=None, y_pi_prev=None, pinv_solver=None): if pinv_solver is None: pinv_solver = las.gmres if self.ham_sites == 3: return else: V_, AhlAo1, A_o2c, Ao1, Ao1c, A_Vr_ho2, A_A_o12c, rhs10, _ham_tp = prereq A = tdvp.A[0] A_ = tdvp2.A[0] l = tdvp.l[0] r_ = tdvp2.r[0] l_sqrt = tdvp.l_sqrt[0] l_sqrt_i = tdvp.l_sqrt_i[0] r__sqrt = tdvp2.r_sqrt[0] r__sqrt_i = tdvp2.r_sqrt_i[0] K__r = tdvp2.K[0] K_l = tdvp.K_left[0] pseudo = tdvp2 is tdvp B = tdvp2.get_B_from_x(x, tdvp2.Vsh[0], l_sqrt_i, r__sqrt_i) #Skip zeros due to rank-deficiency if la.norm(B) == 0: return sp.zeros_like(x), M_prev, y_pi_prev if self.sanity_checks: tst = tm.eps_r_noop(r_, B, A_) if not la.norm(tst) > self.sanity_tol: log.warning("Sanity check failed: Gauge-fixing violation! " + str(la.norm(tst))) if self.sanity_checks: B2 = np.zeros_like(B) for s in xrange(self.q): B2[s] = l_sqrt_i.dot(x.dot(m.mmul(V_[s], r__sqrt_i))) if la.norm(B - B2) / la.norm(B) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad Vri!") y = tm.eps_l_noop(l, B, A) # if pseudo: # y = y - m.adot(r_, y) * l #should just = y due to gauge-fixing M = pinv_1mE(y, [A_], [A], l, r_, p=-p, left=True, pseudo=pseudo, out=M_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='M') #print m.adot(r, M) if self.sanity_checks: y2 = M - sp.exp(+1.j * p) * tm.eps_l_noop(M, A_, A) norm = la.norm(y.ravel()) if norm == 0: norm = 1 tst = la.norm(y - y2) / norm if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad M. Off by: %g", tst) # if pseudo: # M = M - l * m.adot(r_, M) Mh = M.conj().T.copy(order='C') res_ls = 0 res_lsi = 0 exp = sp.exp if self.ham_sites == 3: pass else: Bo1 = get_Aop(B, _ham_tp, 2, conj=False) tmp = sp.empty((B.shape[1], V_.shape[1]), dtype=A.dtype, order='C') tmp2 = sp.empty((A_.shape[1], A_o2c[0].shape[1]), dtype=A.dtype, order='C') tmp3 = sp.empty_like(tmp2, order='C') for al in xrange(len(Bo1)): tmp3 = m.dot_inplace(tm.eps_r_noop_inplace(r_, A_, A_o2c[al], tmp2), r__sqrt_i, tmp3) res_ls += tm.eps_r_noop_inplace(tmp3, Bo1[al], V_, tmp) #1 tmp3 = m.dot_inplace(tm.eps_r_noop_inplace(r_, B, A_o2c[al], tmp2), r__sqrt_i, tmp3) tmp = tm.eps_r_noop_inplace(tmp3, Ao1[al], V_, tmp) #3 tmp *= exp(+1.j * p) res_ls += tmp del(tmp) del(tmp2) del(tmp3) res_lsi += sp.exp(-1.j * p) * Mh.dot(rhs10) #10 if self.ham_sites == 3: pass else: Bo2 = get_Aop(B, _ham_tp, 3, conj=False) for al in xrange(len(AhlAo1)): res_lsi += AhlAo1[al].dot(tm.eps_r_noop(r__sqrt, Bo2[al], V_)) #2 res_lsi += exp(-1.j * p) * tm.eps_l_noop(l, Ao1c[al], B).dot(A_Vr_ho2[al]) #4 res_lsi += exp(-2.j * p) * tm.eps_l_noop(Mh, Ao1c[al], A_).dot(A_Vr_ho2[al]) #12 K__rri = m.mmul(K__r, r__sqrt_i) res_ls += tm.eps_r_noop(K__rri, B, V_) #5 res_lsi += K_l.dot(tm.eps_r_noop(r__sqrt, B, V_)) #6 res_lsi += sp.exp(-1.j * p) * Mh.dot(tm.eps_r_noop(K__rri, A_, V_)) #8 y1 = sp.exp(+1.j * p) * tm.eps_r_noop(K__r, B, A_) #7 if self.ham_sites == 3: pass elif self.ham_sites == 2: tmp = 0 for al in xrange(len(A_A_o12c)): tmp += sp.exp(+1.j * p) * tm.eps_r_noop(tm.eps_r_noop(r_, A_, A_A_o12c[al][1]), B, A_A_o12c[al][0]) #9 tmp += sp.exp(+2.j * p) * tm.eps_r_noop(tm.eps_r_noop(r_, B, A_A_o12c[al][1]), A, A_A_o12c[al][0]) #11 y = y1 + tmp #7, 9, 11 del(tmp) if pseudo: y = y - m.adot(l, y) * r_ y_pi = pinv_1mE(y, [A], [A_], l, r_, p=p, left=False, pseudo=pseudo, out=y_pi_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='y_pi') #print m.adot(l, y_pi) if self.sanity_checks: z = y_pi - sp.exp(+1.j * p) * tm.eps_r_noop(y_pi, A, A_) tst = la.norm((y - z).ravel()) / la.norm(y.ravel()) if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad x_pi. Off by: %g", tst) res_ls += tm.eps_r_noop(m.mmul(y_pi, r__sqrt_i), A, V_) res = l_sqrt.dot(res_ls) res += l_sqrt_i.dot(res_lsi) if self.sanity_checks: expval = m.adot(x, res) / m.adot(x, x) #print "expval = " + str(expval) if expval < -self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not pos. semi-definite (%s)", expval) if abs(expval.imag) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not Hermitian (%s)", expval) return res, M, y_pi
def calc_BHB(self, x, p, tdvp, tdvp2, prereq, M_prev=None, y_pi_prev=None, pinv_solver=None): if pinv_solver is None: pinv_solver = las.gmres if self.ham_sites == 3: V_, Vr_, Vri_, Vri_A_, C_, C_Vri_AA_, C_AAA_r_Ah_Vrih, \ C_AhAhlAA, C_AA_r_Ah_Vrih_, C_AAA_Vrh_, C_Vri_A_r_Ah_, \ C_AhlAA, C_AhlAA_conj, C_AA_Vrh, rhs10 = prereq else: C_, C_conj, V_, Vr_, Vri_, C_Vri_A_conj, C_AhlA, C_A_Vrh_, rhs10 = prereq A = tdvp.A[0] A_ = tdvp2.A[0] AA = tdvp.AA[0] l = tdvp.l[0] r_ = tdvp2.r[0] l_sqrt = tdvp.l_sqrt[0] l_sqrt_i = tdvp.l_sqrt_i[0] r__sqrt = tdvp2.r_sqrt[0] r__sqrt_i = tdvp2.r_sqrt_i[0] K__r = tdvp2.K[0] K_l = tdvp.K_left[0] pseudo = tdvp2 is tdvp B = tdvp2.get_B_from_x(x, tdvp2.Vsh[0], l_sqrt_i, r__sqrt_i) #Skip zeros due to rank-deficiency if la.norm(B) == 0: return sp.zeros_like(x), M_prev, y_pi_prev if self.sanity_checks: tst = tm.eps_r_noop(r_, B, A_) if not la.norm(tst) > self.sanity_tol: log.warning("Sanity check failed: Gauge-fixing violation! " + str(la.norm(tst))) if self.sanity_checks: B2 = np.zeros_like(B) for s in xrange(self.q): B2[s] = l_sqrt_i.dot(x.dot(Vri_[s])) if la.norm(B - B2) / la.norm(B) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad Vri!") BA_ = tm.calc_AA(B, A_) AB = tm.calc_AA(A, B) if self.ham_sites == 3: BAA_ = tm.calc_AAA_AA(BA_, A_) ABA_ = tm.calc_AAA_AA(AB, A_) AAB = tm.calc_AAA_AA(AA, B) y = tm.eps_l_noop(l, B, A) # if pseudo: # y = y - m.adot(r_, y) * l #should just = y due to gauge-fixing M = pinv_1mE(y, [A_], [A], l, r_, p=-p, left=True, pseudo=pseudo, out=M_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='M') #print m.adot(r, M) if self.sanity_checks: y2 = M - sp.exp(+1.j * p) * tm.eps_l_noop(M, A_, A) norm = la.norm(y.ravel()) if norm == 0: norm = 1 tst = la.norm(y - y2) / norm if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad M. Off by: %g", tst) # if pseudo: # M = M - l * m.adot(r_, M) Mh = M.conj().T.copy(order='C') if self.ham_sites == 3: tmp = BAA_ + sp.exp(+1.j * p) * ABA_ + sp.exp(+2.j * p) * AAB res = l_sqrt.dot(tm.eps_r_op_3s_C123_AAA456(r_, tmp, C_Vri_AA_)) #1 1D, #3, #3c else: tmp = BA_ + sp.exp(+1.j * p) * AB res = l_sqrt.dot(tm.eps_r_op_2s_AA12_C34(r_, tmp, C_Vri_A_conj)) #1, #3 OK res += sp.exp(-1.j * p) * l_sqrt_i.dot(Mh.dot(rhs10)) #10 exp = sp.exp subres = sp.zeros_like(res) eye = m.eyemat(C_.shape[2], dtype=tdvp.typ) eye2 = m.eyemat(A.shape[2], dtype=tdvp.typ) if self.ham_sites == 3: subres += exp(-2.j * p) * tm.eps_l_noop(Mh, A, C_AAA_r_Ah_Vrih) #12 subres += exp(-3.j * p) * tm.eps_l_op_2s_AA12_C34(Mh, AA, C_AAA_Vrh_) #12b for s in xrange(self.q): #subres += exp(-2.j * p) * A[s].conj().T.dot(Mh.dot(C_AAA_r_Ah_Vrih[s])) #12 subres += tm.eps_r_noop(B[s], C_AhAhlAA[s, :], Vr_) #2b subres += exp(-1.j * p) * tm.eps_l_noop(l.dot(B[s]), A, C_AA_r_Ah_Vrih_[s, :]) #4 subres += A[s].conj().T.dot(l.dot(tm.eps_r_op_2s_AA12_C34(eye2, AB, C_Vri_A_r_Ah_[s, :, :]))) #2 -ive of that it should be.... subres += exp(-1.j * p) * tm.eps_l_op_2s_AA12_C34(eye2, C_AhlAA_conj[s, :, :], BA_).dot(Vr_[s].conj().T) #4b subres += exp(-2.j * p) * tm.eps_l_op_2s_AA12_C34(l.dot(B[s]), AA, C_AA_Vrh[s, :, :]) #4c subres += exp(+1.j * p) * tm.eps_r_op_2s_AA12_C34(r_.dot_left(B[s]), C_AhlAA[s, :, :], Vri_A_) #3b #for t in xrange(self.q): #subres += (C_AhAhlAA[t, s].dot(B[s]).dot(Vr_[t].conj().T)) #2b #subres += (exp(-1.j * p) * A[s].conj().T.dot(l.dot(B[t])).dot(C_AA_r_Ah_Vrih_[s, t])) #4 #subres += (exp(-3.j * p) * AA[t, s].conj().T.dot(Mh).dot(C_AAA_Vrh_[t, s])) #12b #for u in xrange(self.q): #subres += A[s].conj().T.dot(l.dot(AB[t, u]).dot(C_A_r_Ah_Vrih[s, t, u])) #2 -ive of that it should be.... #subres += (exp(+1.j * p) * C_AhlAA[t, s, s].dot(B[u]).dot(r_.dot(A_[u].conj().T)).dot(Vri_[t].conj().T)) #3b #subres += (exp(-1.j * p) * C_AhAhlA[s, t, u].dot(BA_[t, u]).dot(Vr_[s].conj().T)) #4b #subres += (exp(-2.j * p) * AA[t, s].conj().T.dot(l.dot(B[u])).dot(C_AA_Vrh[t, s, u])) #4c else: for s in xrange(self.q): #subres += C_AhlA[s, t].dot(B[s]).dot(Vr_[t].conj().T) #2 OK subres += tm.eps_r_noop(B[s], C_AhlA[s, :], Vr_) #2 #+ exp(-1.j * p) * A[t].conj().T.dot(l.dot(B[s])).dot(C_A_Vrh_[t, s]) #4 OK with 3 subres += exp(-1.j * p) * tm.eps_l_noop(l.dot(B[s]), A, C_A_Vrh_[s, :]) #4 #+ exp(-2.j * p) * A[s].conj().T.dot(Mh.dot(C_[s, t])).dot(Vr_[t].conj().T)) #12 subres += exp(-2.j * p) * A[s].conj().T.dot(Mh).dot(tm.eps_r_noop(eye, C_[s, :], Vr_)) #12 res += l_sqrt_i.dot(subres) res += l_sqrt.dot(tm.eps_r_noop(K__r, B, Vri_)) #5 res += l_sqrt_i.dot(K_l.dot(tm.eps_r_noop(r__sqrt, B, V_))) #6 res += sp.exp(-1.j * p) * l_sqrt_i.dot(Mh.dot(tm.eps_r_noop(K__r, A_, Vri_))) #8 y1 = sp.exp(+1.j * p) * tm.eps_r_noop(K__r, B, A_) #7 if self.ham_sites == 3: tmp = sp.exp(+1.j * p) * BAA_ + sp.exp(+2.j * p) * ABA_ + sp.exp(+3.j * p) * AAB #9, #11, #11b y = y1 + tm.eps_r_op_3s_C123_AAA456(r_, tmp, C_) elif self.ham_sites == 2: tmp = sp.exp(+1.j * p) * BA_ + sp.exp(+2.j * p) * AB #9, #11 y = y1 + tm.eps_r_op_2s_AA12_C34(r_, tmp, C_conj) if pseudo: y = y - m.adot(l, y) * r_ y_pi = pinv_1mE(y, [A], [A_], l, r_, p=p, left=False, pseudo=pseudo, out=y_pi_prev, tol=self.pinv_tol, solver=pinv_solver, use_CUDA=self.pinv_CUDA, CUDA_use_batch=self.pinv_CUDA_batch, sanity_checks=self.sanity_checks, sc_data='y_pi') #print m.adot(l, y_pi) if self.sanity_checks: z = y_pi - sp.exp(+1.j * p) * tm.eps_r_noop(y_pi, A, A_) tst = la.norm((y - z).ravel()) / la.norm(y.ravel()) if tst > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! Bad x_pi. Off by: %g", tst) res += l_sqrt.dot(tm.eps_r_noop(y_pi, A, Vri_)) if self.sanity_checks: expval = m.adot(x, res) / m.adot(x, x) #print "expval = " + str(expval) if expval < -self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not pos. semi-definite (%s)", expval) if abs(expval.imag) > self.sanity_tol: log.warning("Sanity Fail in calc_BHB! H is not Hermitian (%s)", expval) return res, M, y_pi
def restore_CF(self, dbg=False): if dbg: self.calc_l() self.calc_r() self.simple_renorm() print "BEFORE..." h_before, h_left_before, h_right_before = self.restore_CF_dbg() print (h_left_before, h_before, h_right_before) self.uni_l.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_l calc_lr iterations: ", (self.uni_l.itr_l, self.uni_l.itr_r) # if self.sanity_checks: # if not sp.allclose(self.uni_l.l, self.l[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: True l[0] and l[L] mismatch!", la.norm(self.l[0] - self.uni_l.l) # # if not sp.allclose(self.uni_l.r, r_old, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad r[L]!", la.norm(r_old - self.uni_l.r) # # if not sp.allclose(self.uni_l.A, self.A[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[0] was scaled!", la.norm(self.A[0] - self.uni_l.A) self.l[0] = self.uni_l.l[-1] self.A[0] = None self.uni_r.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_r calc_lr iterations: ", (self.uni_r.itr_l, self.uni_r.itr_r) # if self.sanity_checks: # if not sp.allclose(self.uni_r.A, self.A[self.N + 1], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[R] was scaled! ", la.norm(self.A[self.N + 1] - self.uni_r.A) # # if not sp.allclose(l_old, self.uni_r.l, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad l[R]! ", la.norm(l_old - self.uni_r.l) # # if not sp.allclose(self.r[self.N], self.uni_r.r, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: r[N] and r[R] mismatch!", la.norm(self.r[self.N] - self.uni_r.r) self.r[self.N] = self.uni_r.r[-1] self.A[self.N + 1] = None self._restore_CF_ONR() nc = self.N_centre self.r[nc - 1] = tm.eps_r_noop(self.r[nc], self.A[nc], self.A[nc]) self.simple_renorm(update_lr=False) if dbg: self.calc_l() self.calc_r() print "AFTER ONR..." h_mid, h_left_mid, h_right_mid = self.restore_CF_dbg() print (h_left_mid, h_mid, h_right_mid) self._restore_CF_diag(dbg=dbg) #l[0] is identity, r_L = ? self.uni_l.l_before_CF = self.uni_l.l[-1] self.uni_l.r_before_CF = self.uni_l.r[-1] #r[N] is identity, l_R = ? self.uni_r.l_before_CF = self.uni_r.l[-1] self.uni_r.r_before_CF = self.uni_r.r[-1] #Set l[N + 1] as well... self.l[self.N + 1][:] = tm.eps_l_noop(self.l[self.N], self.uni_r.A[0], self.uni_r.A[0]) if self.sanity_checks: l_n = self.l[0] for n in xrange(1, self.N + 1): l_n = tm.eps_l_noop(l_n, self.A[n], self.A[n]) if not sp.allclose(l_n, self.l[n], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: l_%u is bad" % n r_nm1 = self.r[self.N] for n in reversed(xrange(1, self.N)): r_nm1 = tm.eps_r_noop(r_nm1, self.A[n], self.A[n]) if not sp.allclose(r_nm1, self.r[n - 1], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: r_%u is bad" % (n - 1) if dbg: print "AFTER..." h_after, h_left_after, h_right_after = self.restore_CF_dbg() print (h_left_after, h_after, h_right_after) print h_after - h_before print (h_after.sum() - h_before.sum() + h_left_after - h_left_before + h_right_after - h_right_before)
def restore_CF(self, dbg=False): if dbg: self.calc_l() self.calc_r() self.simple_renorm() print "BEFORE..." h_before, h_left_before, h_right_before = self.restore_CF_dbg() print(h_left_before, h_before, h_right_before) self.uni_l.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_l calc_lr iterations: ", (self.uni_l.itr_l, self.uni_l.itr_r) # if self.sanity_checks: # if not sp.allclose(self.uni_l.l, self.l[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: True l[0] and l[L] mismatch!", la.norm(self.l[0] - self.uni_l.l) # # if not sp.allclose(self.uni_l.r, r_old, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad r[L]!", la.norm(r_old - self.uni_l.r) # # if not sp.allclose(self.uni_l.A, self.A[0], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[0] was scaled!", la.norm(self.A[0] - self.uni_l.A) self.l[0] = self.uni_l.l[-1] self.A[0] = None self.uni_r.calc_lr() #Ensures largest ev of E=1 if dbg: print "uni_r calc_lr iterations: ", (self.uni_r.itr_l, self.uni_r.itr_r) # if self.sanity_checks: # if not sp.allclose(self.uni_r.A, self.A[self.N + 1], atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: A[R] was scaled! ", la.norm(self.A[self.N + 1] - self.uni_r.A) # # if not sp.allclose(l_old, self.uni_r.l, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: Bad l[R]! ", la.norm(l_old - self.uni_r.l) # # if not sp.allclose(self.r[self.N], self.uni_r.r, atol=1E-12, rtol=1E-12): # print "Sanity Fail in restore_CF!: r[N] and r[R] mismatch!", la.norm(self.r[self.N] - self.uni_r.r) self.r[self.N] = self.uni_r.r[-1] self.A[self.N + 1] = None self._restore_CF_ONR() nc = self.N_centre self.r[nc - 1] = tm.eps_r_noop(self.r[nc], self.A[nc], self.A[nc]) self.simple_renorm(update_lr=False) if dbg: self.calc_l() self.calc_r() print "AFTER ONR..." h_mid, h_left_mid, h_right_mid = self.restore_CF_dbg() print(h_left_mid, h_mid, h_right_mid) self._restore_CF_diag(dbg=dbg) #l[0] is identity, r_L = ? self.uni_l.l_before_CF = self.uni_l.l[-1] self.uni_l.r_before_CF = self.uni_l.r[-1] #r[N] is identity, l_R = ? self.uni_r.l_before_CF = self.uni_r.l[-1] self.uni_r.r_before_CF = self.uni_r.r[-1] #Set l[N + 1] as well... self.l[self.N + 1][:] = tm.eps_l_noop(self.l[self.N], self.uni_r.A[0], self.uni_r.A[0]) if self.sanity_checks: l_n = self.l[0] for n in xrange(1, self.N + 1): l_n = tm.eps_l_noop(l_n, self.A[n], self.A[n]) if not sp.allclose(l_n, self.l[n], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: l_%u is bad" % n r_nm1 = self.r[self.N] for n in reversed(xrange(1, self.N)): r_nm1 = tm.eps_r_noop(r_nm1, self.A[n], self.A[n]) if not sp.allclose( r_nm1, self.r[n - 1], atol=1E-12, rtol=1E-12): print "Sanity Fail in restore_CF!: r_%u is bad" % (n - 1) if dbg: print "AFTER..." h_after, h_left_after, h_right_after = self.restore_CF_dbg() print(h_left_after, h_after, h_right_after) print h_after - h_before print(h_after.sum() - h_before.sum() + h_left_after - h_left_before + h_right_after - h_right_before)
def _excite_correlation_1s_1s(AL, AR, B, lL, rR, op1, op2, d, g): pseudo = AL is AR BBL = pinv_1mE(tm.eps_l_noop(lL, B, B), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) B1L = pinv_1mE(tm.eps_l_noop(lL, B, AL), [AR], [AL], lL, rR, p=0, left=True, pseudo=pseudo) B2L = pinv_1mE(tm.eps_l_noop(lL, AL, B), [AL], [AR], lL, rR, p=0, left=True, pseudo=pseudo) B1B2L = pinv_1mE(tm.eps_l_noop(B1L, AR, B), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) B2B1L = pinv_1mE(tm.eps_l_noop(B2L, B, AR), [AR], [AR], lL, rR, p=0, left=True, pseudo=True) BBR = pinv_1mE(tm.eps_r_noop(rR, B, B), [AL], [AL], lL, rR, p=0, left=False, pseudo=True) print "gauge fixing:", la.norm(tm.eps_r_noop(rR, B, AR)) res = [0.] * (d + 1) #B's on the left terms (0, 1, 2, 5) res[0] += m.adot(tm.eps_l_op_1s(BBL + B1B2L + B2B1L, AR, AR, op1.dot(op2) - g[0] * sp.eye(len(op1))), rR) res[0] += m.adot(tm.eps_l_op_1s(B1L, AR, B, op1.dot(op2)), rR) res[0] += m.adot(tm.eps_l_op_1s(B2L, B, AR, op1.dot(op2)), rR) res[0] += m.adot(tm.eps_l_op_1s(lL, B, B, op1.dot(op2) - g[0] * sp.eye(len(op1))), rR) l1 = tm.eps_l_op_1s(BBL + B1B2L + B2B1L, AR, AR, op1) l1 += tm.eps_l_op_1s(B1L, AR, B, op1) l1 += tm.eps_l_op_1s(B2L, B, AR, op1) l1 += tm.eps_l_op_1s(lL, B, B, op1) for n in xrange(1, d + 1): res[n] += m.adot(l1, tm.eps_r_op_1s(rR, AR, AR, op2)) res[n] -= 2 * g[n] if n == d: break l1 = tm.eps_l_noop(l1, AR, AR) print 1, res #Terms 3, 4, 6, 7, a ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(B1L, AR, AL, op1) + tm.eps_l_op_1s(lL, B, AL, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AR, AL) rs = [None] * (d + 1) rs[d - 1] = tm.eps_r_op_1s(rR, AR, AR, op2) for k in xrange(d - 1, 0, -1): rs[k - 1] = tm.eps_r_noop(rs[k], AR, AR) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], AR, B)) res[n] += m.adot(ls[n - 1], tm.eps_r_op_1s(rR, AR, B, op2)) print 2, res #Terms 3, 4, 6, 7, b ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(B2L, AL, AR, op1) + tm.eps_l_op_1s(lL, AL, B, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AL, AR) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], B, AR)) res[n] += m.adot(ls[n - 1], tm.eps_r_op_1s(rR, B, AR, op2)) print 3, res #Term 8 ls = [None] * (d + 1) ls[0] = tm.eps_l_op_1s(lL, AL, AL, op1) for k in xrange(1, d + 1): ls[k] = tm.eps_l_noop(ls[k - 1], AL, AL) for n in xrange(2, d + 1): for k in xrange(2, n): res[n] += m.adot(ls[k - 1], tm.eps_r_noop(rs[-(n + 1):][k], B, B)) res[n] -= g[n] print 4, res #Terms 9 and 10 for n in xrange(2, d + 1): for k in xrange(2, n): lj = tm.eps_l_noop(ls[k - 1], AL, B) for j in xrange(k + 1, n): res[n] += m.adot(lj, tm.eps_r_noop(rs[-(n + 1):][j], B, AR)) lj = tm.eps_l_noop(lj, AL, AR) res[n] += m.adot(lj, tm.eps_r_op_1s(rR, B, AR, op2)) lj = tm.eps_l_noop(ls[k - 1], B, AL) for j in xrange(k + 1, n): res[n] += m.adot(lj, tm.eps_r_noop(rs[-(n + 1):][j], AR, B)) lj = tm.eps_l_noop(lj, AL, AR) res[n] += m.adot(lj, tm.eps_r_op_1s(rR, AR, B, op2)) print 5, res #Term 11 res[0] += m.adot(tm.eps_l_op_1s(lL, AL, AL, op1.dot(op2) - g[0] * sp.eye(len(op1))), BBR) for n in xrange(1, d + 1): res[n] += m.adot(tm.eps_l_op_1s(ls[n - 1], AL, AL, op2), BBR) res[n] -= g[n] return res
def take_step_split(self, dtau, ham_is_Herm=True): """Take a time-step dtau using the split-step integrator. This is the one-site version of a DMRG-like time integrator described at: http://arxiv.org/abs/1408.5056 It has a fourth-order local error and is symmetric. It requires iteratively computing two matrix exponentials per site, and thus has less predictable CPU time requirements than the Euler or RK4 methods. NOTE: This requires the expokit extension, which is included in evoMPS but must be compiled during, e.g. using setup.py to build all extensions. Parameters ---------- dtau : complex The (imaginary or real) amount of imaginary time (tau) to step. ham_is_Herm : bool Whether the Hamiltonian is really Hermitian. If so, the lanczos method will be used for imaginary time evolution. """ #TODO: Compute eta. self.eta_sq.fill(0) self.eta = 0 assert self.canonical_form == 'right', 'take_step_split only implemented for right canonical form' assert self.ham_sites == 2, 'take_step_split only implemented for nearest neighbour Hamiltonians' dtau *= -1 from expokit_expmv import zexpmv, zexpmvh if sp.iscomplex(dtau) or not ham_is_Herm: expmv = zexpmv fac = 1.j dtau = sp.imag(dtau) else: expmv = zexpmvh fac = 1 norm_est = abs(self.H_expect.real) KL = [None] * (self.N + 1) KL[1] = sp.zeros((self.D[1], self.D[1]), dtype=self.typ) for n in xrange(1, self.N + 1): lop = Vari_Opt_Single_Site_Op(self, n, KL[n - 1], tau=fac) #print "Befor A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real An = expmv(lop, self.A[n].ravel(), dtau/2., norm_est=norm_est) self.A[n] = An.reshape((self.q[n], self.D[n - 1], self.D[n])) self.l[n] = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n]) norm = m.adot(self.l[n], self.r[n]) self.A[n] /= sp.sqrt(norm) #print "After A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real, norm.real #shift centre matrix right (RCF is like having a centre "matrix" at "1") G = tm.restore_LCF_l_seq(self.A[n - 1:n + 1], self.l[n - 1:n + 1], sanity_checks=self.sanity_checks) if n > 1: self.AA[n - 1] = tm.calc_AA(self.A[n - 1], self.A[n]) self.C[n - 1] = tm.calc_C_mat_op_AA(self.ham[n - 1], self.AA[n - 1]) KL[n], ex = tm.calc_K_l(KL[n - 1], self.C[n - 1], self.l[n - 2], self.r[n], self.A[n], self.AA[n - 1]) if n < self.N: lop2 = Vari_Opt_SC_op(self, n, KL[n], tau=fac) #print "Befor G", n, sp.inner(G.ravel().conj(), lop2.matvec(G.ravel())).real G = expmv(lop2, G.ravel(), -dtau/2., norm_est=norm_est) G = G.reshape((self.D[n], self.D[n])) norm = sp.trace(self.l[n].dot(G).dot(self.r[n].dot(G.conj().T))) G /= sp.sqrt(norm) #print "After G", n, sp.inner(G.ravel().conj(), lop2.matvec(G.ravel())).real, norm.real for s in xrange(self.q[n + 1]): self.A[n + 1][s] = G.dot(self.A[n + 1][s]) self.AA[n] = tm.calc_AA(self.A[n], self.A[n + 1]) self.C[n] = tm.calc_C_mat_op_AA(self.ham[n], self.AA[n]) for n in xrange(self.N, 0, -1): lop = Vari_Opt_Single_Site_Op(self, n, KL[n - 1], tau=fac, sanity_checks=self.sanity_checks) #print "Before A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real An = expmv(lop, self.A[n].ravel(), dtau/2., norm_est=norm_est) self.A[n] = An.reshape((self.q[n], self.D[n - 1], self.D[n])) self.l[n] = tm.eps_l_noop(self.l[n - 1], self.A[n], self.A[n]) norm = m.adot(self.l[n], self.r[n]) self.A[n] /= sp.sqrt(norm) #print "After A", n, sp.inner(self.A[n].ravel().conj(), lop.matvec(self.A[n].ravel())).real, norm.real #shift centre matrix left (LCF is like having a centre "matrix" at "N") Gi = tm.restore_RCF_r_seq(self.A[n - 1:n + 1], self.r[n - 1:n + 1], sanity_checks=self.sanity_checks) if n < self.N: self.AA[n] = tm.calc_AA(self.A[n], self.A[n + 1]) self.C[n] = tm.calc_C_mat_op_AA(self.ham[n], self.AA[n]) self.calc_K(n_low=n, n_high=n) if n > 1: lop2 = Vari_Opt_SC_op(self, n - 1, KL[n - 1], tau=fac, sanity_checks=self.sanity_checks) Gi = expmv(lop2, Gi.ravel(), -dtau/2., norm_est=norm_est) Gi = Gi.reshape((self.D[n - 1], self.D[n - 1])) norm = sp.trace(self.l[n - 1].dot(Gi).dot(self.r[n - 1].dot(Gi.conj().T))) G /= sp.sqrt(norm) #print "After G", n, sp.inner(Gi.ravel().conj(), lop2.matvec(Gi.ravel())).real, norm.real for s in xrange(self.q[n - 1]): self.A[n - 1][s] = self.A[n - 1][s].dot(Gi) self.AA[n - 1] = tm.calc_AA(self.A[n - 1], self.A[n]) self.C[n - 1] = tm.calc_C_mat_op_AA(self.ham[n - 1], self.AA[n - 1])