def check_environments(self, vl, vm, vr, n):
        # check if the environments of the n-th tensor have consistent dimensions
        is_bug0 = False
        bond = str()
        if vl.shape[0] != vl.shape[1]:
            is_bug0 = True
            bond = 'LEFT'
        if vm.shape[0] != vm.shape[1]:
            is_bug0 = True
            bond = 'MIDDLE'
        if vr.shape[0] != vr.shape[1]:
            is_bug0 = True
            bond = 'RIGHT'
        if is_bug0:
            cprint(
                'EnvError: for the %d-th tensor, the ' % n + bond +
                ' v is not square', 'magenta')

        is_bug = False
        if vl.shape[0] != self.virtual_dim[n]:
            is_bug = True
            bond = 'LEFT'
        if vr.shape[0] != self.virtual_dim[n + 1]:
            is_bug = True
            bond = 'RIGHT'
        if vm.shape[0] != self.mps[n].shape[1]:
            bond = 'MIDDLE'
            is_bug = True
        if is_bug:
            cprint(
                'EnvError: for the %d-th tensor, the ' % n + bond +
                ' v has inconsistent dimension', 'magenta')
        if is_bug0 or is_bug:
            trace_stack()
Esempio n. 2
0
def bound_vec_operator_right2left(tensor,
                                  op=np.zeros(0),
                                  v=np.zeros(0),
                                  normalize=False,
                                  symme=False):
    s = tensor.shape
    if op.size != 0:  # deal with the operator
        tensor1 = absorb_matrix2tensor(tensor, op.T, 1)
    else:  # no operator
        tensor1 = tensor.copy()
    if v.size == 0:  # no input boundary vector v
        tensor = tensor.reshape(s[0], s[1] * s[2]).conj()
        tensor1 = tensor1.reshape(s[0], s[1] * s[2])
        v1 = tensor.dot(tensor1.T)
    else:  # there is an input boundary vector v
        if is_debug:
            if v.shape[0] != s[2]:
                cprint(
                    'BondDimError: the v_right has inconsistent dimension with the tensor',
                    'magenta')
                cprint('v.shape = ' + str(v.shape) + '; T.shape = ' + str(s))
                trace_stack()
        tensor = tensor.reshape(s[0] * s[1], s[2]).conj().dot(v)
        v1 = tensor.reshape(s[0], s[1] * s[2]).dot(
            tensor1.reshape(s[0], s[1] * s[2]).T)
    if normalize:
        v1 = normalize_tensor(v1)[0]
    if symme:
        v1 = (v1 + v1.conj().T) / 2
    return v1
Esempio n. 3
0
def absorb_matrices2tensor_full_fast(tensor, mats):
    # generally, recommend to use the function 'absorb_matrices2tensor'
    # each bond will have a matrix to contract with
    # the matrices must be in the right order
    # contract the 1st bond of mat with tensor
    nb = tensor.ndim
    s = np.array(tensor.shape)
    is_bug = False
    if is_debug:
        for n in range(0, nb):
            if mats[n].shape[1] != s[n]:
                cprint(
                    'Error: the %d-th matrix has inconsistent dimension with the tensor'
                    % n, 'magenta')
                cprint(
                    'T.shape = ' + str(s) + ', mat.shape = ' +
                    str(mats[n].shape), 'magenta')
                is_bug = True
    for n in range(nb - 1, -1, -1):
        tensor = tensor.reshape(np.prod(s[:nb - 1]), s[nb - 1]).dot(mats[n])
        s[-1] = mats[n].shape[1]
        ind = np.append(nb - 1, np.arange(0, nb - 1))
        tensor = tensor.reshape(s).transpose(ind)
        s = s[ind]
    if is_debug and is_bug:
        trace_stack()
    return tensor
 def check_virtual_bond_dimensions(self):
     is_error = False
     for n in range(1, self.length):
         if self.virtual_dim[n] != self.mps[n].shape[0] or self.virtual_dim[
                 n] != self.mps[n - 1].shape[2]:
             cprint(
                 'BondDimError: inconsistent dimension detected for the %d-th virtual bond'
                 % n, 'magenta')
             is_error = True
     if is_error:
         trace_stack(2)
 def norm_mps(self):
     # calculate the norm of an MPS
     if self._debug:
         lc = self.check_orthogonal_center()
         if lc != self.center:
             cprint(
                 'CenterError: center should be at %d but at %d' %
                 self.center, lc, 'magenta')
             trace_stack()
     if self.center < -0.5:
         v = self.contract_v_l0_to_l1(0, self.length)
         norm = v[0, 0]
     else:
         norm = np.linalg.norm(self.mps[self.center].reshape(1, -1))
     return norm
Esempio n. 6
0
def normalize_tensor(tensor, if_flatten=False):
    v = tensor.reshape(-1, )
    norm = np.linalg.norm(v)
    if norm < 1e-30:
        cprint('InfWarning: norm is too small to normalize', 'magenta')
        trace_stack()
        if if_flatten:
            return v, norm
        else:
            return tensor, norm
    else:
        if if_flatten:
            return v/norm, norm
        else:
            return tensor/norm, norm
 def check_orthogonal_center(self, expected_center=-2, if_print=True):
     # Check if MPS has the correct center, or at the expected center
     # if not, find the correct center, or recommend a new center while it is not central orthogonal
     # NOTE: no central-orthogonalization in this function, only recommendation
     if self.center > -0.5:
         left = self.orthogonality[:self.center]
         right = self.orthogonality[self.center + 1:]
         if not (np.prod(left == -1) and np.prod(right == 1)):
             if if_print:
                 cprint(
                     colored('self.center is incorrect. Change it to -1',
                             'magenta'))
                 trace_stack()
             self.center = -1
     if self.center < -0.5:
         left = np.nonzero(self.orthogonality == -1)
         left = left[0][-1]
         right = np.nonzero(self.orthogonality == 1)
         right = right[0][0]
         if np.prod(self.orthogonality[:left + 1]) and np.prod(
                 self.orthogonality[right:]) and left + 2 == right:
             self.center = left + 1
             if if_print:
                 cprint(
                     colored('self.center is corrected to %g' % self.center,
                             'cyan'))
         else:
             if if_print:
                 cprint(
                     colored(
                         'MPS is not central orthogonal. self.center remains -1',
                         'cyan'))
     else:
         left = self.center - 1
     if self.center > -0.5:
         if expected_center > -0.5 and expected_center != self.center:
             cprint('The center is at %d, not the expected position at %d' %
                    (self.center, expected_center))
         recommend_center = self.center
     else:
         # if not central-orthogonal, recommend the tensor after the last left-orthogonal one as the new center
         recommend_center = left + 1
     return recommend_center