Пример #1
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
Пример #2
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