Exemplo n.º 1
0
    def calc_C_diss(self, L, n_low=-1, n_high=-1):
        """Generates the C tensors used to calculate the K's and ultimately the B's.
        
        This is called automatically by self.update().
        
        C[n] contains a contraction of the Hamiltonian self.ham with the parameter
        tensors over the local basis indices.
        
        This is prerequisite for calculating the tangent vector parameters B,
        which optimally approximate the exact time evolution.
        
        These are to be used on one side of the super-operator when applying the
        nearest-neighbour Hamiltonian, similarly to C in eqn. (44) of 
        arXiv:1103.0936v2 [cond-mat.str-el], for the non-norm-preserving case.

        Makes use only of the nearest-neighbour Hamiltonian, and of the A's.
        
        C[n] depends on A[n] through A[n + self.ham_sites - 1].
        
        """

        LC = sp.zeros_like(self.C)

        if L is None:
            return 0
        
        if n_low < 1:
            n_low = 1
        if n_high < 1:
            n_high = self.N - self.ham_sites + 1
        
        for n in xrange(n_low, n_high + 1):
            if callable(L):
                ham_n = lambda *args: L(n, *args)
                ham_n = sp.vectorize(ham_n, otypes=[sp.complex128])
                ham_n = sp.fromfunction(ham_n, tuple(self.C[n].shape[:-2] * 2))
            else:
                #print "L shape", L.shape
                ham_n = L.reshape(4,4,4,4)
                
            if self.ham_sites == 2:
                AA = tm.calc_AA(self.A[n], self.A[n + 1])                
                LC[n] = tm.calc_C_mat_op_AA(ham_n, AA)
            else:
                AAA = tm.calc_AAA(self.A[n], self.A[n + 1], self.A[n + 2])
                LC[n] = tm.calc_C_3s_mat_op_AAA(ham_n, AAA)
        return LC
Exemplo n.º 2
0
    def calc_C_diss(self, L, n_low=-1, n_high=-1):
        """Generates the C tensors used to calculate the K's and ultimately the B's.
        
        This is called automatically by self.update().
        
        C[n] contains a contraction of the Hamiltonian self.ham with the parameter
        tensors over the local basis indices.
        
        This is prerequisite for calculating the tangent vector parameters B,
        which optimally approximate the exact time evolution.
        
        These are to be used on one side of the super-operator when applying the
        nearest-neighbour Hamiltonian, similarly to C in eqn. (44) of 
        arXiv:1103.0936v2 [cond-mat.str-el], for the non-norm-preserving case.

        Makes use only of the nearest-neighbour Hamiltonian, and of the A's.
        
        C[n] depends on A[n] through A[n + self.ham_sites - 1].
        
        """

        LC = sp.zeros_like(self.C)

        if L is None:
            return 0

        if n_low < 1:
            n_low = 1
        if n_high < 1:
            n_high = self.N - self.ham_sites + 1

        for n in xrange(n_low, n_high + 1):
            if callable(L):
                ham_n = lambda *args: L(n, *args)
                ham_n = sp.vectorize(ham_n, otypes=[sp.complex128])
                ham_n = sp.fromfunction(ham_n, tuple(self.C[n].shape[:-2] * 2))
            else:
                #print "L shape", L.shape
                ham_n = L.reshape(4, 4, 4, 4)

            if self.ham_sites == 2:
                AA = tm.calc_AA(self.A[n], self.A[n + 1])
                LC[n] = tm.calc_C_mat_op_AA(ham_n, AA)
            else:
                AAA = tm.calc_AAA(self.A[n], self.A[n + 1], self.A[n + 2])
                LC[n] = tm.calc_C_3s_mat_op_AAA(ham_n, AAA)
        return LC
Exemplo n.º 3
0
    def expect_2s_diss(self, op, LC, LK, n, AA=None):
        """Applies a two-site operator to two sites and returns
        the value after the change. In contrast to
        mps_gen.apply_op_2s, this routine does not change the state itself.
        
        Also, this does not perform self.update().
        
        Parameters
        ----------
        op : ndarray or callable
            The two-site operator. See self.expect_2s().
        n: int
            The site to apply the operator to.
            (It's also applied to n-1.)
        """
        #No neighbors, no fun.

        if n is 1:
            return 0
        if n is N:
            return 0

        A = self.A[n - 1]
        Ap1 = self.A[n]
        if AA is None:
            AA = tm.calc_AA(A, Ap1)

        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(
                op, (A.shape[0], Ap1.shape[0], A.shape[0], Ap1.shape[0]))

        op = op.reshape(4, 4, 4, 4)
        C = tm.calc_C_mat_op_AA(op, AA)
        res = tm.eps_r_op_2s_C12_AA34(self.r[n + 1], LC, AA)
        operand = self.l[n - 1]
        operand = sp.reshape(operand, (1, 16))
        operand = sp.reshape(operand, (2, 8))

        return mm.mmul(operand, res)
        return mm.adot(self.l[n - 1], res)
Exemplo n.º 4
0
 def expect_2s_diss(self, op, LC, LK, n, AA=None):
     """Applies a two-site operator to two sites and returns
     the value after the change. In contrast to
     mps_gen.apply_op_2s, this routine does not change the state itself.
     
     Also, this does not perform self.update().
     
     Parameters
     ----------
     op : ndarray or callable
         The two-site operator. See self.expect_2s().
     n: int
         The site to apply the operator to.
         (It's also applied to n-1.)
     """
     #No neighbors, no fun.
     
     if n is 1:
         return 0
     if n is N:
         return 0
         
     A = self.A[n-1]
     Ap1 = self.A[n]
     if AA is None:
         AA = tm.calc_AA(A, Ap1)
         
     if callable(op):
         op = sp.vectorize(op, otypes=[sp.complex128])
         op = sp.fromfunction(op, (A.shape[0], Ap1.shape[0], A.shape[0], Ap1.shape[0]))
     
     op = op.reshape(4,4,4,4)
     C = tm.calc_C_mat_op_AA(op, AA)
     res = tm.eps_r_op_2s_C12_AA34(self.r[n + 1], LC, AA)
     operand = self.l[n-1]
     operand = sp.reshape(operand, (1,16))
     operand = sp.reshape(operand, (2,8))
             
     return mm.mmul(operand,res)
     return mm.adot(self.l[n - 1], res)