示例#1
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 range(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]
示例#2
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]
def GenerateSineArray(gridShape, dimension, randomPhase = False):
    if randomPhase:
        phase = numpy.random.random()*2.*pi 
    else:
        phase = 0.
    result = fromfunction(lambda x: sin(pi*(x)/gridShape[0]+phase), [gridShape[0]])  
    for dim in range(1, dimension):
        if randomPhase:
            phase = numpy.random.random()*2.*pi 
        else:
            phase = 0.
        temp = fromfunction(lambda x: sin(pi*(x)/gridShape[dim]+phase), [gridShape[dim]])  
        result = outer(result, temp)        
    return result
示例#4
0
    def expect_2s(self, op, n):
        """Computes the expectation value of a nearest-neighbour two-site operator.

        The operator should be a q[n] x q[n + 1] x q[n] x q[n + 1] array
        such that op[s, t, u, v] = <st|op|uv> or a function of the form
        op(s, t, u, v) = <st|op|uv>.

        Parameters
        ----------
        o : ndarray or callable
            The operator array or function.
        n : int
            The leftmost site number (operator acts on n, n + 1).
        """
        A = self.get_A(n)
        Ap1 = self.get_A(n + 1)
        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]))

        C = tm.calc_C_mat_op_AA(op, AA)
        res = tm.eps_r_op_2s_C12_AA34(self.get_r(n + 1), C, AA)
        return mm.adot(self.get_l(n - 1), res)
示例#5
0
 def expect_2s(self, op, n, AA=None):
     """Computes the expectation value of a nearest-neighbour two-site operator.
     
     The operator should be a q[n] x q[n + 1] x q[n] x q[n + 1] array 
     such that op[s, t, u, v] = <st|op|uv> or a function of the form 
     op(s, t, u, v) = <st|op|uv>.
     
     The state must be up-to-date -- see self.update()!
     
     Parameters
     ----------
     op : ndarray or callable
         The operator array or function.
     n : int
         The leftmost site number (operator acts on n, n + 1).
         
     Returns
     -------
     expval : floating point number
         The expectation value (data type may be complex)
     """
     A = self.A[n]
     Ap1 = self.A[n + 1]
     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]))
         
     C = tm.calc_C_mat_op_AA(op, AA)
     res = tm.eps_r_op_2s_C12_AA34(self.r[n + 1], C, AA)
     return m.adot(self.l[n - 1], res)
示例#6
0
    def calc_B_1s_diss(self,op,n):
        """Applies a single-site operator to a single site and returns
        the parameter tensor for that site after the change with the
        change in the norm of the state projected out.
        
        Parameters
        ----------
        op : ndarray or callable
            The single-site operator. See self.expect_1s().
        n: int
            The site to apply the operator to.
        """
        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))
            
        newAn = sp.zeros_like(self.A[n])
        
        for s in range(self.q[n]):
            for t in range(self.q[n]):
                newAn[s] += self.A[n][t] * op[s, t]
                
        r_nm1 = TDVP.tm.eps_r_noop(self.r[n], newAn, newAn)
        ev = mm.adot(self.l[n - 1], r_nm1)

        newAn -= ev * self.A[n] #norm-fixing
        
        return newAn
示例#7
0
    def calc_B_1s_diss(self, op, n):
        """Applies a single-site operator to a single site and returns
        the parameter tensor for that site after the change with the
        change in the norm of the state projected out.
        
        Parameters
        ----------
        op : ndarray or callable
            The single-site operator. See self.expect_1s().
        n: int
            The site to apply the operator to.
        """
        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        newAn = sp.zeros_like(self.A[n])

        for s in xrange(self.q[n]):
            for t in xrange(self.q[n]):
                newAn[s] += self.A[n][t] * op[s, t]

        r_nm1 = TDVP.tm.eps_r_noop(self.r[n], newAn, newAn)
        ev = mm.adot(self.l[n - 1], r_nm1)

        newAn -= ev * self.A[n]  #norm-fixing

        return newAn
示例#8
0
    def expect_3s(self, op, n):
        """Computes the expectation value of a nearest-neighbour three-site operator.

        The operator should be a q[n] x q[n + 1] x q[n + 2] x q[n] x
        q[n + 1] x q[n + 2] array such that op[s, t, u, v, w, x] =
        <stu|op|vwx> or a function of the form op(s, t, u, v, w, x) =
        <stu|op|vwx>.

        The state must be up-to-date -- see self.update()!

        Parameters
        ----------
        op : ndarray or callable
            The operator array or function.
        n : int
            The leftmost site number (operator acts on n, n + 1, n + 2).

        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """
        A = self.A[n]
        Ap1 = self.A[n + 1]
        Ap2 = self.A[n + 2]
        AAA = tm.calc_AAA(A, Ap1, Ap2)

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

        C = tm.calc_C_3s_mat_op_AAA(op, AAA)
        res = tm.eps_r_op_3s_C123_AAA456(self.r[n + 2], C, AAA)
        return m.adot(self.l[n - 1], res)
示例#9
0
 def expect_1s_diss(self,op,n):
     """Applies a single-site operator to a single site and returns
     the value after the change. In contrast to
     mps_gen.apply_op_1s, this routine does not change the state itself.
     
     Also, this does not perform self.update().
     
     Parameters
     ----------
     op : ndarray or callable
         The single-site operator. See self.expect_1s().
     n: int
         The site to apply the operator to.
     """
     if callable(op):
         op = sp.vectorize(op, otypes=[sp.complex128])
         op = sp.fromfunction(op, (self.q[n], self.q[n]))
         
     newAn = sp.zeros_like(self.A[n])
     
     for s in xrange(self.q[n]):
         for t in xrange(self.q[n]):
             newAn[s] += self.A[n][t] * op[s, t]
             
     return newAn
示例#10
0
 def apply_op_1s(self, op, n, do_update=True):
     """Applies a single-site operator to a single site.
     
     By default, this performs self.update(), which also restores
     state normalization.        
     
     Parameters
     ----------
     op : ndarray or callable
         The single-site operator. See self.expect_1s().
     n: int
         The site to apply the operator to.
     do_update : bool
         Whether to update after applying the operator.
     """
     if callable(op):
         op = sp.vectorize(op, otypes=[sp.complex128])
         op = sp.fromfunction(op, (self.q[n], self.q[n]))
         
     newAn = sp.zeros_like(self.A[n])
     
     for s in xrange(self.q[n]):
         for t in xrange(self.q[n]):
             newAn[s] += self.A[n][t] * op[s, t]
             
     self.A[n] = newAn
     
     if do_update:
         self.update()
示例#11
0
 def expect_2s(self, op, n, AA=None):
     """Computes the expectation value of a nearest-neighbour two-site operator.
     
     The operator should be a q[n] x q[n + 1] x q[n] x q[n + 1] array 
     such that op[s, t, u, v] = <st|op|uv> or a function of the form 
     op(s, t, u, v) = <st|op|uv>.
     
     The state must be up-to-date -- see self.update()!
     
     Parameters
     ----------
     op : ndarray or callable
         The operator array or function.
     n : int
         The leftmost site number (operator acts on n, n + 1).
         
     Returns
     -------
     expval : floating point number
         The expectation value (data type may be complex)
     """
     A = self.A[n]
     Ap1 = self.A[n + 1]
     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]))
         
     C = tm.calc_C_mat_op_AA(op, AA)
     res = tm.eps_r_op_2s_C12_AA34(self.r[n + 1], C, AA)
     return m.adot(self.l[n - 1], res)
示例#12
0
    def apply_op_1s(self, op, n, do_update=True):
        """Applies a single-site operator to a single site.
        
        By default, this performs self.update(), which also restores
        state normalization.        
        
        Parameters
        ----------
        op : ndarray or callable
            The single-site operator. See self.expect_1s().
        n: int
            The site to apply the operator to.
        do_update : bool
            Whether to update after applying the operator.
        """
        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        newAn = sp.zeros_like(self.A[n])

        for s in xrange(self.q[n]):
            for t in xrange(self.q[n]):
                newAn[s] += self.A[n][t] * op[s, t]

        self.A[n] = newAn

        if do_update:
            self.update()
示例#13
0
 def expect_1s(self, op, n):
     """Computes the expectation value of a single-site operator.
     
     The operator should be a q[n] x q[n] matrix or generating function 
     such that op[s, t] or op(s, t) equals <s|op|t>.
     
     The state must be up-to-date -- see self.update()!
     
     Parameters
     ----------
     op : ndarray or callable
         The operator.
     n : int
         The site number (1 <= n <= N).
         
     Returns
     -------
     expval : floating point number
         The expectation value (data type may be complex)
     """        
     if callable(op):
         op = sp.vectorize(op, otypes=[sp.complex128])
         op = sp.fromfunction(op, (self.q[n], self.q[n]))
         
     res = tm.eps_r_op_1s(self.r[n], self.A[n], self.A[n], op)
     return  m.adot(self.l[n - 1], res)
示例#14
0
    def expect_3s(self, op, n):
        """Computes the expectation value of a nearest-neighbour three-site operator.

        The operator should be a q[n] x q[n + 1] x q[n + 2] x q[n] x
        q[n + 1] x q[n + 2] array such that op[s, t, u, v, w, x] =
        <stu|op|vwx> or a function of the form op(s, t, u, v, w, x) =
        <stu|op|vwx>.

        The state must be up-to-date -- see self.update()!

        Parameters
        ----------
        op : ndarray or callable
            The operator array or function.
        n : int
            The leftmost site number (operator acts on n, n + 1, n + 2).

        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """
        A = self.A[n]
        Ap1 = self.A[n + 1]
        Ap2 = self.A[n + 2]
        AAA = tm.calc_AAA(A, Ap1, Ap2)

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

        C = tm.calc_C_3s_mat_op_AAA(op, AAA)
        res = tm.eps_r_op_3s_C123_AAA456(self.r[n + 2], C, AAA)
        return m.adot(self.l[n - 1], res)
示例#15
0
    def expect_2s(self, op, n):
        """Computes the expectation value of a nearest-neighbour two-site operator.

        The operator should be a q[n] x q[n + 1] x q[n] x q[n + 1] array
        such that op[s, t, u, v] = <st|op|uv> or a function of the form
        op(s, t, u, v) = <st|op|uv>.

        Parameters
        ----------
        o : ndarray or callable
            The operator array or function.
        n : int
            The leftmost site number (operator acts on n, n + 1).
        """
        A = self.get_A(n)
        Ap1 = self.get_A(n + 1)
        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]))

        C = tm.calc_C_mat_op_AA(op, AA)
        res = tm.eps_r_op_2s_C12_AA34(self.get_r(n + 1), C, AA)
        return mm.adot(self.get_l(n - 1), res)
示例#16
0
    def expect_1s(self, op, n):
        """Computes the expectation value of a single-site operator.
        
        The operator should be a q[n] x q[n] matrix or generating function 
        such that op[s, t] or op(s, t) equals <s|op|t>.
        
        The state must be up-to-date -- see self.update()!
        
        Parameters
        ----------
        op : ndarray or callable
            The operator.
        n : int
            The site number (1 <= n <= N).
            
        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """
        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        res = tm.eps_r_op_1s(self.r[n], self.A[n], self.A[n], op)
        return m.adot(self.l[n - 1], res)
示例#17
0
    def expect_1s_diss(self, op, n):
        """Applies a single-site operator to a single site and returns
        the value after the change. In contrast to
        mps_gen.apply_op_1s, this routine does not change the state itself.
        
        Also, this does not perform self.update().
        
        Parameters
        ----------
        op : ndarray or callable
            The single-site operator. See self.expect_1s().
        n: int
            The site to apply the operator to.
        """
        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        newAn = sp.zeros_like(self.A[n])

        for s in xrange(self.q[n]):
            for t in xrange(self.q[n]):
                newAn[s] += self.A[n][t] * op[s, t]

        return newAn
示例#18
0
    def expect_1s_1s(self, op1, op2, d):
        """Computes the expectation value of two single site operators acting 
        on two different sites.
        
        The result is < op1_n op2_n+d > with the operators acting on sites
        n and n + d.
        
        See expect_1s().
        
        Requires d > 0.
        
        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.
        d : int
            The distance (number of sites) between the two sites acted on non-trivially.
            
        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """        
        
        assert d > 0, 'd must be greater than 1'
        
        if callable(op1):
            op1 = sp.vectorize(op1, otypes=[sp.complex128])
            op1 = sp.fromfunction(op1, (self.q, self.q))
        
        if callable(op2):
            op2 = sp.vectorize(op2, otypes=[sp.complex128])
            op2 = sp.fromfunction(op2, (self.q, self.q)) 
        
        r_n = tm.eps_r_op_1s(self.r, self.A, self.A, op2)

        for n in xrange(d - 1):
            r_n = tm.eps_r_noop(r_n, self.A, self.A)

        r_n = tm.eps_r_op_1s(r_n, self.A, self.A, op1)
         
        return m.adot(self.l, r_n)
示例#19
0
    def _create_distance_matrix(self, size):
        h, w = size

        def freq(yy, xx):
            f1 = np.minimum(yy, h - yy)
            f2 = np.minimum(xx, w - xx)
            return np.sqrt(f1**2 + f2**2)

        return scipy.fromfunction(freq, (h, w))
示例#20
0
    def expect_1s_1s(self, op1, op2, n1, n2):
        """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).
            
        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """        
        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])) 
        
        r_n = tm.eps_r_op_1s(self.r[n2], self.A[n2], self.A[n2], op2)

        for n in reversed(xrange(n1 + 1, n2)):
            r_n = tm.eps_r_noop(r_n, self.A[n], self.A[n])

        r_n = tm.eps_r_op_1s(r_n, self.A[n1], self.A[n1], op1)
         
        return m.adot(self.l[n1 - 1], r_n)
示例#21
0
    def expect_1s_1s(self, op1, op2, n1, n2):
        """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).
            
        Returns
        -------
        expval : floating point number
            The expectation value (data type may be complex)
        """
        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]))

        r_n = tm.eps_r_op_1s(self.r[n2], self.A[n2], self.A[n2], op2)

        for n in reversed(xrange(n1 + 1, n2)):
            r_n = tm.eps_r_noop(r_n, self.A[n], self.A[n])

        r_n = tm.eps_r_op_1s(r_n, self.A[n1], self.A[n1], op1)

        return m.adot(self.l[n1 - 1], r_n)
def GenerateGaussianRandomArray(gridShape, temp, sigma):
    dimension = len(gridShape)
    if dimension == 1:
        kfactor = fromfunction(lambda kz: exp(-0.5*(sigma*kz)**2),[gridShape[0]/2+1,])
        ktemp = fft.rfft(temp)
        ktemp *= kfactor
        data = fft.irfft(ktemp)
    elif dimension == 2:
        X,Y = gridShape
        kfactor = fromfunction(lambda kx,ky: exp(-0.5*sigma**2*((kx*(kx<X/2)+(X-kx)*(kx>=X/2))**2+ky**2)),[X,Y/2+1])
        ktemp = fft.rfftn(temp)
        ktemp *= kfactor
        data = fft.irfftn(ktemp)
    elif dimension == 3:
        X,Y,Z = gridShape
        kfactor = fromfunction(lambda kx,ky,kz: exp(-0.5*sigma**2*( (kx*(kx<X/2)+(X-kx)*(kx>=X/2))**2 + \
                                                (ky*(ky<Y/2)+(Y-ky)*(ky>=Y/2))**2 + kz**2)),[X,Y,Z/2+1])
        ktemp = fft.rfftn(temp)
        ktemp *= kfactor
        data = fft.irfftn(ktemp)
    return data 
示例#23
0
    def expect_1s_cor(self, op1, op2, n1, n2):
        """Computes the correlation of two single site operators acting on two different sites.

        See expect_1S().

        n1 must be smaller than n2.

        Assumes that the state is normalized.

        Parameters
        ----------
        op1 : function
            The first operator, acting on the first site.
        op2 : function
            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).
        """
        A1 = self.get_A(n1)
        A2 = self.get_A(n2)

        if callable(op1):
            op1 = sp.vectorize(op1, otypes=[sp.complex128])
            op1 = sp.fromfunction(op1, (A1.shape[0], A1.shape[0]))

        if callable(op2):
            op2 = sp.vectorize(op2, otypes=[sp.complex128])
            op2 = sp.fromfunction(op2, (A2.shape[0], A2.shape[0]))

        r_n = tm.eps_r_op_1s(self.get_r(n2), A2, A2, op2)

        for n in reversed(range(n1 + 1, n2)):
            r_n = tm.eps_r_noop(r_n, self.get_A(n), self.get_A(n))

        r_n = tm.eps_r_op_1s(r_n, A1, A1, op1)

        return mm.adot(self.get_l(n1 - 1), r_n)
示例#24
0
    def expect_1s_cor(self, op1, op2, n1, n2):
        """Computes the correlation of two single site operators acting on two different sites.

        See expect_1S().

        n1 must be smaller than n2.

        Assumes that the state is normalized.

        Parameters
        ----------
        op1 : function
            The first operator, acting on the first site.
        op2 : function
            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).
        """
        A1 = self.get_A(n1)
        A2 = self.get_A(n2)

        if callable(op1):
            op1 = sp.vectorize(op1, otypes=[sp.complex128])
            op1 = sp.fromfunction(op1, (A1.shape[0], A1.shape[0]))

        if callable(op2):
            op2 = sp.vectorize(op2, otypes=[sp.complex128])
            op2 = sp.fromfunction(op2, (A2.shape[0], A2.shape[0]))

        r_n = tm.eps_r_op_1s(self.get_r(n2), A2, A2, op2)

        for n in reversed(xrange(n1 + 1, n2)):
            r_n = tm.eps_r_noop(r_n, self.get_A(n), self.get_A(n))

        r_n = tm.eps_r_op_1s(r_n, A1, A1, op1)

        return mm.adot(self.get_l(n1 - 1), r_n)
示例#25
0
    def calc_C(self, 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].
        
        """
        if self.ham 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(1, self.N):
            self.AA[n] = tm.calc_AA(self.A[n], self.A[n + 1])
        
        if self.ham_sites == 3:
            for n in xrange(1, self.N - 1):
                self.AAA[n] = tm.calc_AAA_AA(self.AA[n], self.A[n + 2])
        else:
            self.AAA.fill(None)
        
        for n in xrange(n_low, n_high + 1):
            if callable(self.ham):
                ham_n = lambda *args: self.ham(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:
                ham_n = self.ham[n]
            
            if self.ham_sites == 2:
                self.C[n] = tm.calc_C_mat_op_AA(ham_n, self.AA[n])
            else:
                self.C[n] = tm.calc_C_3s_mat_op_AAA(ham_n, self.AAA[n])                
示例#26
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 range(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
示例#27
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
示例#28
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
示例#29
0
    def apply_op_1s(self, op, n):
        """Applies a one-site operator op to site n.

        Can be used to create excitations.
        """

        if not (0 < n <= self.N):
            raise ValueError("Operators can only be applied to sites 1 to N!")

        newA = sp.zeros_like(self.A[n])

        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        for s in xrange(self.q[n]):
            for t in xrange(self.q[n]):
                newA[s] += self.A[n][t] * op[s, t]

        self.A[n] = newA
示例#30
0
    def apply_op_1s(self, op, n):
        """Applies a one-site operator op to site n.

        Can be used to create excitations.
        """

        if not (0 < n <= self.N):
            raise ValueError("Operators can only be applied to sites 1 to N!")

        newA = sp.zeros_like(self.A[n])

        if callable(op):
            op = sp.vectorize(op, otypes=[sp.complex128])
            op = sp.fromfunction(op, (self.q[n], self.q[n]))

        for s in range(self.q[n]):
            for t in range(self.q[n]):
                newA[s] += self.A[n][t] * op[s, t]

        self.A[n] = newA
示例#31
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)
示例#32
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)
示例#33
0
    def expect_1s(self, op, n):
        """Computes the expectation value of a single-site operator.

        A single-site operator is represented as a function taking three
        integer arguments (n, s, t) where n is the site number and s, t
        range from 0 to q[n] - 1 and define the requested matrix element <s|o|t>.

        Assumes that the state is normalized.

        Parameters
        ----------
        o : ndarray or callable
            The operator.
        n : int
            The site number.
        """
        A = self.get_A(n)

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

        res = tm.eps_r_op_1s(self.get_r(n), A, A, op)
        return mm.adot(self.get_l(n - 1), res)
示例#34
0
    def expect_1s(self, op, n):
        """Computes the expectation value of a single-site operator.

        A single-site operator is represented as a function taking three
        integer arguments (n, s, t) where n is the site number and s, t
        range from 0 to q[n] - 1 and define the requested matrix element <s|o|t>.

        Assumes that the state is normalized.

        Parameters
        ----------
        o : ndarray or callable
            The operator.
        n : int
            The site number.
        """
        A = self.get_A(n)

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

        res = tm.eps_r_op_1s(self.get_r(n), A, A, op)
        return mm.adot(self.get_l(n - 1), res)