def calc_K_l(Km1, Cm1, lm2, r, A, Am1, sanity_checks=False): """Calculates the K_left using the recursive definition. This is the "bra-vector" K_left, which means (K_left.dot(r)).trace() = <K_left|r>. In other words, K_left ~ <K_left| and K_left.conj().T ~ |K_left>. """ D = A.shape[2] q = A.shape[0] qm1 = Am1.shape[0] K = sp.zeros((D, D), dtype=A.dtype) Hl = sp.zeros_like(K) for s in xrange(qm1): Am1sh = Am1[s].conj().T for t in xrange(q): Hl += A[t].conj().T.dot(Am1sh).dot(lm2.dot(Cm1[s, t])) K += A[s].conj().T.dot(Km1.dot(A[s])) op_expect = mm.adot_noconj(Hl, r) K += Hl return K, op_expect
def calc_K(self): """Generates the right K matrices used to calculate the B's K[n] contains 'column-vectors' such that <l[n]|K[n]> = trace(l[n].dot(K[n])). K_l[n] contains 'bra-vectors' such that <K_l[n]|r[n]> = trace(K_l[n].dot(r[n])). """ self.h_expect = sp.zeros((self.N + 1), dtype=self.typ) self.uni_r.calc_AA() self.uni_r.calc_C() self.uni_r.calc_K() self.K[self.N + 1][:] = self.uni_r.K[0] self.uni_l.calc_AA() self.uni_l.calc_C() K_left, h_left_uni = self.uni_l.calc_K_l() self.K_l[0][:] = K_left[-1] for n in xrange(self.N, self.N_centre - 1, -1): self.K[n], he = tm.calc_K(self.K[n + 1], self.C[n], self.get_l(n - 1), self.r[n + 1], self.A[n], self.get_AA(n)) self.h_expect[n] = he for n in xrange(1, self.N_centre + 1): self.K_l[n], he = tm.calc_K_l(self.K_l[n - 1], self.C[n - 1], self.get_l(n - 2), self.r[n], self.A[n], self.get_AA(n - 1)) self.h_expect[n - 1] = he self.dH_expect = (mm.adot_noconj(self.K_l[self.N_centre], self.r[self.N_centre]) + mm.adot(self.l[self.N_centre - 1], self.K[self.N_centre]) - (self.N + 1) * self.uni_r.h_expect)
def calc_K_3s_l(Km1, Cm2, lm3, r, A, Am2Am1A): K = eps_l_noop(Km1, A, A) Hl = eps_l_op_3s_AAA123_C456(lm3, Am2Am1A, Cm2) op_expect = mm.adot_noconj(Hl, r) K += Hl return K, op_expect
def calc_K_l_tp(Km1, lm2, r, Am1, A, Cm1_tp): K = eps_l_noop(Km1, A, A) Hl = eps_l_op_2s_C34_tp(lm2, Am1, A, Cm1_tp) op_expect = mm.adot_noconj(Hl, r) K += Hl return K, op_expect
def calc_K_l(Km1, Cm1, lm2, r, A, Am1A): """Calculates the K_left using the recursive definition. This is the "bra-vector" K_left, which means (K_left.dot(r)).trace() = <K_left|r>. In other words, K_left ~ <K_left| and K_left.conj().T ~ |K_left>. """ K = eps_l_noop(Km1, A, A) Hl = eps_l_op_2s_AA12_C34(lm2, Am1A, Cm1) op_expect = mm.adot_noconj(Hl, r) K += Hl return K, op_expect
def calc_K(self): """Generates the right K matrices used to calculate the B's K[n] contains 'column-vectors' such that <l[n]|K[n]> = trace(l[n].dot(K[n])). K_l[n] contains 'bra-vectors' such that <K_l[n]|r[n]> = trace(K_l[n].dot(r[n])). """ self.h_expect = sp.zeros((self.N + 1), dtype=self.typ) self.uni_r.calc_AA() self.uni_r.calc_C() self.uni_r.calc_K() self.K[self.N + 1][:] = self.uni_r.K self.uni_l.calc_AA() self.uni_l.calc_C() K_left, h_left_uni = self.uni_l.calc_K_l() self.K_l[0][:] = K_left for n in xrange(self.N, self.N_centre - 1, -1): self.K[n], he = tm.calc_K(self.K[n + 1], self.C[n], self.get_l(n - 1), self.r[n + 1], self.A[n], self.A[n + 1], sanity_checks=self.sanity_checks) self.h_expect[n] = he for n in xrange(1, self.N_centre + 1): self.K_l[n], he = tm.calc_K_l(self.K_l[n - 1], self.C[n - 1], self.get_l(n - 2), self.r[n], self.A[n], self.A[n - 1], sanity_checks=self.sanity_checks) self.h_expect[n - 1] = he self.dH_expect = ( mm.adot_noconj(self.K_l[self.N_centre], self.r[self.N_centre]) + mm.adot(self.l[self.N_centre - 1], self.K[self.N_centre]) - (self.N + 1) * self.uni_r.h_expect)
def calc_B_centre(self): """Calculate the optimal B_centre given right gauge-fixing on n_centre+1..N and left gauge-fixing on 1..n_centre-1. We use the non-norm-preserving K's, since the norm-preservation is not needed elsewhere. It is cleaner to subtract the relevant norm-changing terms from the K's here than to generate all K's with norm-preservation. """ Bc = sp.empty_like(self.A[self.N_centre]) Nc = self.N_centre try: rc_i = self.r[Nc].inv() except AttributeError: rc_i = mm.invmh(self.r[Nc]) try: lcm1_i = self.l[Nc - 1].inv() except AttributeError: lcm1_i = mm.invmh(self.l[Nc - 1]) Acm1 = self.A[Nc - 1] Ac = self.A[Nc] Acp1 = self.A[Nc + 1] rc = self.r[Nc] rcp1 = self.r[Nc + 1] lcm1 = self.l[Nc - 1] lcm2 = self.l[Nc - 2] #Note: this is a 'bra-vector' K_l_cm1 = self.K_l[Nc - 1] - lcm1 * mm.adot_noconj( self.K_l[Nc - 1], self.r[Nc - 1]) Kcp1 = self.K[Nc + 1] - rc * mm.adot(self.l[Nc], self.K[Nc + 1]) Cc = self.C[Nc] - self.h_expect[Nc] * self.AAc Ccm1 = self.C[Nc - 1] - self.h_expect[Nc - 1] * self.AAcm1 for s in xrange(self.q[1]): try: #3 Bc[s] = Ac[s].dot(rc_i.dot_left(Kcp1)) except AttributeError: Bc[s] = Ac[s].dot(Kcp1.dot(rc_i)) for t in xrange(self.q[2]): #1 try: Bc[s] += Cc[s, t].dot(rcp1.dot(rc_i.dot_left(mm.H(Acp1[t])))) except AttributeError: Bc[s] += Cc[s, t].dot(rcp1.dot(mm.H(Acp1[t]).dot(rc_i))) Bcsbit = K_l_cm1.dot(Ac[s]) #4 for t in xrange(self.q[0]): #2 Bcsbit += mm.H(Acm1[t]).dot(lcm2.dot(Ccm1[t, s])) Bc[s] += lcm1_i.dot(Bcsbit) rb = tm.eps_r_noop(rc, Bc, Bc) eta = sp.sqrt(mm.adot(lcm1, rb)) return Bc, eta
def calc_B_centre(self): """Calculate the optimal B_centre given right gauge-fixing on n_centre+1..N and left gauge-fixing on 1..n_centre-1. We use the non-norm-preserving K's, since the norm-preservation is not needed elsewhere. It is cleaner to subtract the relevant norm-changing terms from the K's here than to generate all K's with norm-preservation. """ Bc = sp.empty_like(self.A[self.N_centre]) Nc = self.N_centre try: rc_i = self.r[Nc].inv() except AttributeError: rc_i = mm.invmh(self.r[Nc]) try: lcm1_i = self.l[Nc - 1].inv() except AttributeError: lcm1_i = mm.invmh(self.l[Nc - 1]) Acm1 = self.A[Nc - 1] Ac = self.A[Nc] Acp1 = self.A[Nc + 1] rc = self.r[Nc] rcp1 = self.r[Nc + 1] lcm1 = self.l[Nc - 1] lcm2 = self.l[Nc - 2] #Note: this is a 'bra-vector' K_l_cm1 = self.K_l[Nc - 1] - lcm1 * mm.adot_noconj(self.K_l[Nc - 1], self.r[Nc - 1]) Kcp1 = self.K[Nc + 1] - rc * mm.adot(self.l[Nc], self.K[Nc + 1]) Cc = self.C[Nc] - self.h_expect[Nc] * self.AAc Ccm1 = self.C[Nc - 1] - self.h_expect[Nc - 1] * self.AAcm1 for s in xrange(self.q[1]): try: #3 Bc[s] = Ac[s].dot(rc_i.dot_left(Kcp1)) except AttributeError: Bc[s] = Ac[s].dot(Kcp1.dot(rc_i)) for t in xrange(self.q[2]): #1 try: Bc[s] += Cc[s, t].dot(rcp1.dot(rc_i.dot_left(mm.H(Acp1[t])))) except AttributeError: Bc[s] += Cc[s, t].dot(rcp1.dot(mm.H(Acp1[t]).dot(rc_i))) Bcsbit = K_l_cm1.dot(Ac[s]) #4 for t in xrange(self.q[0]): #2 Bcsbit += mm.H(Acm1[t]).dot(lcm2.dot(Ccm1[t,s])) Bc[s] += lcm1_i.dot(Bcsbit) rb = tm.eps_r_noop(rc, Bc, Bc) eta = sp.sqrt(mm.adot(lcm1, rb)) return Bc, eta