Esempio n. 1
0
 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()
Esempio n. 2
0
 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()
Esempio n. 3
0
    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)
Esempio n. 4
0
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)
Esempio n. 5
0
    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]
Esempio n. 6
0
    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]
Esempio n. 7
0
 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])
Esempio n. 8
0
 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
Esempio n. 9
0
 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])
Esempio n. 10
0
 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
Esempio n. 11
0
 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
Esempio n. 12
0
    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])
Esempio n. 13
0
    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])
Esempio n. 14
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
Esempio n. 15
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
Esempio n. 16
0
    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
Esempio n. 17
0
 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
Esempio n. 18
0
 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()
Esempio n. 19
0
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)
Esempio n. 20
0
 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))
Esempio n. 21
0
    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
Esempio n. 22
0
    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
Esempio n. 23
0
    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
Esempio n. 24
0
    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)
Esempio n. 25
0
    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
Esempio n. 26
0
    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)
Esempio n. 27
0
    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
Esempio n. 28
0
    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
Esempio n. 29
0
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
Esempio n. 30
0
    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)
Esempio n. 31
0
    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  
Esempio n. 32
0
    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   
Esempio n. 33
0
    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)
Esempio n. 34
0
    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)
Esempio n. 35
0
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
Esempio n. 36
0
    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])