Beispiel #1
0
def act_umpo_on_mps(mps, mpo, if_conjugate=False):
    mps1 = empty_list(mps.__len__())
    if if_conjugate:  # act on product state (evolve)
        mps1[0] = copy.deepcopy(mpo[0])
        for n in range(1, mps.__len__() - 1):
            mps1[n] = T_module.cont([mpo[n], mps[n - 1]],
                                    [[-1, -3, 1, -4], [-2, 1, -5]])
            s = mps1[n].shape
            mps1[n] = mps1[n].reshape(s[0] * s[1], s[2], s[3] * s[4])
        mps1[-1] = T_module.cont([mpo[-1], mps[-2], mps[-1]],
                                 [[-1, -3, 2, 3], [-2, 2, 1], [1, 3, -4]])
        s = mps1[-1].shape
        mps1[-1] = mps1[-1].reshape(s[0] * s[1], s[2], s[3])
    else:  # act on mps (disentangle)
        mps1[0] = T_module.cont(
            [mps[0].squeeze(), mps[1], mpo[0].squeeze(), mpo[1]],
            [[3, 1], [1, 4, -3], [3, 2], [2, 4, -1, -2]])
        mps1[0] = mps1[0].reshape(1, mpo[1].shape[2],
                                  mpo[1].shape[3] * mps[1].shape[2])
        for n in range(2, mps.__len__() - 1):
            mps1[n - 1] = T_module.cont([mps[n], mpo[n]],
                                        [[-2, 1, -5], [-1, 1, -3, -4]])
            s = mps1[n - 1].shape
            mps1[n - 1] = mps1[n - 1].reshape(s[0] * s[1], s[2], s[3] * s[4])
        mps1[-2] = T_module.cont([mps[-1].squeeze(), mpo[-1]],
                                 [[-2, 1], [-1, 1, -3, -4]])
        s = mps1[-2].shape
        mps1[-2] = mps1[-2].reshape(s[0] * s[1] * s[2], s[3])
        mps1[-2], lm, mps1[-1] = np.linalg.svd(mps1[-2],
                                               full_matrices=False,
                                               compute_uv=True)
        mps1[-2] = mps1[-2].reshape(s[0] * s[1], s[2], lm.size)
        mps1[-1] = np.diag(lm).dot(mps1[-1]).reshape(lm.size, s[3], 1)
    return mps1
 def reshape_combine_two_bonds_z2(self, nb):
     # reshape nb and nb+1 together
     data = dict()
     for key in self.data:
         dim0 = self.data[key].shape[:nb]
         dim1 = self.data[key].shape[nb + 2:]
         dim_now = self.data[key].shape[nb] * self.data[key].shape[nb + 1]
         tmp = self.data[key].reshape(dim0 + (dim_now, ) + dim1)
         key_num = [int(x) for x in key]
         key_new = key[:nb] + str(
             (key_num[nb] + key_num[nb + 1]) % 2) + key[nb + 2:]
         if key_new not in data:
             s = list(tmp.shape)
             s[nb] *= 2
             data[key_new] = np.zeros(s)
         if (key_num[nb] == 0 and key_num[nb + 1] == 0) or \
                 (key_num[nb] == 0 and key_num[nb + 1] == 1):
             data[key_new] = tm.operate_tensor_slice(
                 data[key_new], nb, ':' + str(dim_now), tmp)
         else:
             data[key_new] = tm.operate_tensor_slice(
                 data[key_new], nb,
                 str(dim_now) + ':', tmp)
     self.data = data
     self.ndim -= 1
     self.shape[nb] = self.shape[nb] * self.shape[nb + 1]
     self.shape.pop(nb + 1)
Beispiel #3
0
 def update_virtual_vecs_train(self, which_t, which_side):
     if (which_side is 'left') or (which_side is 'both'):
         tmp = tm.khatri(self.vecsLeft[which_t], self.vecsImages[:, which_t, :].squeeze())
         self.vecsLeft[which_t + 1] = np.tensordot(
             self.mps.mps[which_t], tmp, ([0, 1], [0, 1]))
     if (which_side is 'right') or (which_side is 'both'):
         tmp = tm.khatri(self.vecsRight[which_t], self.vecsImages[:, which_t, :].squeeze())
         self.vecsRight[which_t - 1] = np.tensordot(
             self.mps.mps[which_t], tmp, ([2, 1], [0, 1]))
Beispiel #4
0
 def env_tensor(self, nt, way):
     s = self.mps.mps[nt].shape
     env = tm.khatri(tm.khatri(
         self.vecsLeft[nt], self.vecsImages[:, nt, :].squeeze()).reshape(
         self.mps.virtual_dim[nt] * self.d, self.numVecSample), self.vecsRight[nt])
     if way is 'mera':
         env = env.dot(np.ones((self.numVecSample, )))
     elif way is 'gradient':
         weight = self.mps.mps[nt].reshape(1, -1).dot(env)
         env = env.dot(1 / weight)
     return env.reshape(s)
 def permutation_transformation(data, if_inverse=False):
     ind_con = [list(range(1, data.ndim + 1))]
     u = list()
     for n in range(0, data.ndim):
         order = list(range(0, data.shape[n], 2)) + list(
             range(1, data.shape[n], 2))
         u.append(tm.bond_permutation_transformation(order))
         if if_inverse:
             ind_con.append([n + 1, -n - 1])
         else:
             ind_con.append([-n - 1, n + 1])
     return tm.cont([data] + u, ind_con)
 def update_tensor_decision_mps_svd_threshold_algo(self,
                                                   nt,
                                                   time_r=5,
                                                   threshold=0.9):
     self.update_tensor_decision_mps_svd(nt)
     env = 0
     d0 = self.v_ctr_train[0].shape[0]
     d1 = self.vecsImages[0][:, nt].shape[0]
     for t in range(0, time_r):
         for n in self.remaining_samples_train:
             v1 = tm.absorb_vectors2tensors(
                 self.tensors[nt],
                 (self.v_ctr_train[n], self.vecsImages[n][:, nt]), (0, 1))
             norm = np.linalg.norm(v1)
             fid = self.fun_fidelity(v1 / norm)
             fid_now = fid[self.classes.index(self.LabelNow[n])]
             fid = [fid[nn] / fid_now for nn in range(0, self.num_classes)]
             fid.pop(self.classes.index(self.LabelNow[n]))
             if max(fid) > threshold:
                 env += np.kron(
                     np.kron(self.v_ctr_train[n], self.vecsImages[n][:,
                                                                     nt]),
                     self.vLabel[self.classes.index(self.LabelNow[n])])
         u, self.lm[nt], v = np.linalg.svd(
             (env / np.linalg.norm(env.reshape(-1, ))).reshape(
                 d0 * d1, self.chi),
             full_matrices=False)
         self.tensors[nt] = u.dot(v).reshape([d0, d1, self.chi])
         self.lm[nt] /= np.linalg.norm(self.lm[nt])
 def update_tensor_decision_mps_gradient_algo(self,
                                              nt,
                                              time_r=5,
                                              threshold=0,
                                              step=0.2):
     self.update_tensor_decision_mps_svd(nt)
     for t in range(0, time_r):
         d_tensor = np.zeros(self.tensors[nt].shape)
         for n in self.remaining_samples_train:
             v1 = tm.absorb_vectors2tensors(
                 self.tensors[nt],
                 (self.v_ctr_train[n], self.vecsImages[n][:, nt]), (0, 1))
             norm = np.linalg.norm(v1)
             fid = self.fun_fidelity(v1 / norm)
             fid_now = fid[self.classes.index(self.LabelNow[n])]
             fid = [fid[nn] / fid_now for nn in range(0, self.num_classes)]
             fid.pop(self.classes.index(self.LabelNow[n]))
             if max(fid) > threshold:
                 tmp = np.kron(np.kron(self.v_ctr_train[n], self.vecsImages[n][:, nt]),
                               self.vLabel[self.classes.index(self.LabelNow[n])]) \
                       / (fid_now * norm)
                 d_tensor += tmp.reshape(self.tensors[nt].shape)
         d_tensor -= self.tensors[nt]
         norm = np.linalg.norm(d_tensor.reshape(-1, ))
         if norm > 1e-10:
             d_tensor /= norm
         self.tensors[nt] = self.tensors[nt] + step * d_tensor
         self.tensors[nt] /= np.linalg.norm(self.tensors[nt].reshape(-1, ))
Beispiel #8
0
    def __init__(self, dims, state_type='pure', ini='random', operators=None):
        self.dims = dims
        self.dim_tot = int(np.prod(self.dims))
        self.l = len(self.dims)

        self.is_vec = True  # If self.v is saved as a vector or tensor
        self.state_type = state_type
        if type(ini) is np.ndarray:
            self.v = ini
        elif ini is 'random':
            if state_type is 'pure':
                self.v = np.random.randn(self.dim_tot, )
                self.v = tm.normalize_tensor(self.v)[0]
            else:
                self.v = np.random.randn(self.dim_tot, self.dim_tot)
                self.v = self.v + self.v.transpose((1, 0))
        else:
            if state_type is 'pure':
                self.v = np.ones((self.dim_tot, 1)) / (self.dim_tot**0.5)
            else:
                self.v = np.eye(self.dim_tot)
        if operators is None:
            op = spin_operators('half')
            self.operators = [
                op['id'], op['sx'], op['sy'], op['sz'], op['su'], op['sd']
            ]
        else:
            self.operators = operators
Beispiel #9
0
 def initial_ipeps(self):
     dim = (self.d, ) + (self.chi, ) * self.nVirtual
     if self.iniWay is 'random':
         tensor = tm.symmetrical_rand_peps_tensor(self.d, self.chi,
                                                  self.nVirtual)
         if self.stateType is 'mixed':
             bond = (self.d0, self.d0) + (self.chi, ) * self.nVirtual
             tensor = tensor.reshape(bond)
             ind = (1, 0) + tuple(range(2, self.nVirtual + 2))
             tensor = (tensor + tensor.transpose(ind)) / 2
             bond = (self.d, ) + (self.chi, ) * self.nVirtual
             tensor = tensor.reshape(bond)
         for n in range(0, self.nTensor):
             self.tensors[n] = tensor.copy()
     elif self.iniWay is 'ones':
         for n in range(0, self.nTensor):
             self.tensors[n] = np.ones(dim)
     elif self.iniWay is 'id':
         if self.stateType is 'mixed':
             if self._is_debug:
                 if abs(self.d0**2 - self.d) > 1e-10:
                     bf.print_error('For mixed state, d should be as d0^2. '
                                    'Check self.d or self.stateType')
             for n in range(0, self.nTensor):
                 self.tensors[n] = np.eye(
                     self.d0).reshape((self.d, ) + (1, ) * self.nVirtual)
         else:
             bf.print_error('Initial way "id" is only for thermal states')
Beispiel #10
0
    def one_bond_so_transformation(self, nt1, vb1, nt2, vb2):
        # Super-orthogonal transformation on one virtual bond
        # vb does NOT count the physical bond
        if self._is_debug:
            if self.pos_lm[nt1][vb1] != self.pos_lm[nt2][vb2]:
                bf.print_error(
                    'In one_bond_so_transformation, the two virtual bonds must'
                    'correspond to the same lambda')
        m1 = self.bond_env_matrix_simple(nt1, vb1)
        m2 = self.bond_env_matrix_simple(nt2, vb2)

        flag = False
        if self._is_debug:
            _lm = self.lm[self.pos_lm[nt1][vb1]].copy()
            flag = (self.chi == self.tensors[nt1].shape[vb1 + 1])
        u1, u2, self.lm[self.pos_lm[nt1]
                        [vb1]] = tm.transformation_from_env_mats(
                            m1,
                            m2,
                            self.lm[self.pos_lm[nt1][vb1]],
                            self.chi,
                            norm_way=1)[:3]
        if self._is_debug and flag:
            _tmp = u1.dot(np.diag(self.lm[self.pos_lm[nt1][vb1]])).dot(u2.T)
            err = np.linalg.norm(tm.off_diagonal_mat(_tmp).reshape(-1, ))
            if err > 1e-10:
                print(
                    'Warning of the transformations from environment: not diagonal (%g)'
                    % err)
            _tmp = np.diag(_tmp)
            _tmp = _tmp / np.linalg.norm(_tmp)
            err = np.linalg.norm(_tmp - self.lm[self.pos_lm[nt1][vb1]])
            if err > 1e-10:
                print(
                    'Warning of the transformations from environment: not recover lm (%g)'
                    % err)
            print(self.lm[self.pos_lm[nt1][vb1]])
        self.tensors[nt1] = tm.absorb_matrix2tensor(self.tensors[nt1], u1,
                                                    vb1 + 1)
        self.tensors[nt2] = tm.absorb_matrix2tensor(self.tensors[nt2], u2,
                                                    vb2 + 1)
        self.tensors[nt1] /= max(abs(self.tensors[nt1].reshape(-1, 1)))
        self.tensors[nt2] /= max(abs(self.tensors[nt2].reshape(-1, 1)))
        # self.lm[self.pos_lm[nt1][vb1]] = tm.normalize_tensor(self.lm[self.pos_lm[nt1][vb1]])[0]
        return m1, m2
Beispiel #11
0
 def multiple_images2vecs(self, theta_max=np.pi/2):
     # Put the data of images in self.tmp!!!
     # The pixels should have been normalized to [0, 1)
     s = self.tmp.shape
     self.tmp *= theta_max
     self.vecsImages = np.zeros((self.d, ) + s)
     for nd in range(1, self.d+1):
         self.vecsImages[nd-1, :, :] = (np.sqrt(tm.combination(self.d-1, nd-1)) * (
                 np.cos(self.tmp)**(self.d-nd)) * (np.sin(self.tmp)**(nd-1)))
Beispiel #12
0
 def map_to_vectors(self, x, d=None, theta_max=np.pi / 2):
     if d is None:
         d = self.d
     x *= theta_max
     y = np.zeros((self.d, ) + x.shape)
     for nd in range(1, self.d + 1):
         y[nd - 1, :, :] = (np.sqrt(tm.combination(d - 1, nd - 1)) *
                            (np.cos(x)**(d - nd)) * (np.sin(x)**(nd - 1)))
     return y
Beispiel #13
0
 def update_effective_ops_kagome(self):
     # Only use mps[0] assuming left and right parts are symmetrical
     op_ind = [1, 3, 4, 5]  # x, z, u, d
     for p in [0, 1]:  # iterate on two physical bonds
         for n in range(op_ind.__len__()):
             tmp = self.update_by_given_effective_ops(
                 self.tensors[1], [self.operators[op_ind[n]]], [p])
             self.effective_ops[n + p * 4] = tm.cont(
                 [self.tensors[1].conj(), tmp],
                 [[1, 2, 3, 4, -1], [1, 2, 3, 4, -2]])
Beispiel #14
0
 def images2vecs(self, theta_max=np.pi / 2):
     # The pixels should have been normalized to [0, 1)
     s = self.images.shape
     self.numVecSample = s[1]
     self.images *= theta_max
     self.vecsImages = np.zeros((self.d, ) + s)
     for nd in range(1, self.d + 1):
         self.vecsImages[nd - 1, :, :] = (
             np.sqrt(tm.combination(self.d - 1, nd - 1)) *
             (np.cos(self.images)**(self.d - nd)) *
             (np.sin(self.images)**(nd - 1)))
Beispiel #15
0
 def update_tensor_gradient(self, nt, step):
     # for n in self.mps.mps:
     #     print(n)
     # input()
     self.mps.correct_orthogonal_center(nt)
     env = self.env_tensor((nt, 'all', 'gradient'))
     env = tm.normalize_tensor(env)[0]
     # env /= np.linalg.norm(env.reshape(-1, ))
     self.mps.mps[nt] = self.mps.mps[nt] * (1 - step) + step * env.reshape(
         self.mps.mps[nt].shape)
     self.mps.mps[nt] /= np.linalg.norm(self.mps.mps[nt].reshape(-1, ))
Beispiel #16
0
 def fidelity_mps_image(self, mps_ref, ni):
     # Calculate the fidelity between an MPS and one image
     fid = 0
     length = mps_ref.__len__()
     v0 = np.ones((1, ))
     image = self.vecsImages[ni]
     for n in range(0, self.length):
         v0 = tm.absorb_vectors2tensors(mps_ref[n], (v0, image[:, n]), (0, 1))
         norm = np.linalg.norm(v0)
         v0 /= norm
         fid -= np.log(norm) / length
     return fid
Beispiel #17
0
 def compute_fidelities(self, mps):
     fid = np.zeros((self.numVecSample, 1))
     vecs = np.ones((1, self.numVecSample))
     for nt in range(self.length):
         s = mps[nt].shape
         vecs = np.tensordot(mps[nt],
                             tm.khatri(vecs, self.vecsImages[:, nt, :]),
                             ([0, 1], [0, 1]))
         norm = np.linalg.norm(vecs, axis=0)
         vecs /= norm.repeat(s[2]).reshape(self.numVecSample, s[2]).T
         fid -= np.log(norm.reshape(self.numVecSample, 1))
     return fid / self.length
Beispiel #18
0
 def update_by_given_effective_ops(psi, ops, bonds):
     indexes = bf.empty_list(1 + bonds.__len__())
     indexes[0] = list(range(psi.ndim))
     x = 1
     for n in range(psi.ndim):
         if n in bonds:
             indexes[0][n] = x
             indexes[bonds.index(n) + 1] = [-n - 1, x]
             x += 1
         else:
             indexes[0][n] = -n - 1
     return tm.cont([psi] + ops, indexes)
Beispiel #19
0
 def update_virtual_vecs_train(self, which_t, which_side):
     if (which_side is 'left') or (which_side is 'both'):
         tmp = tm.khatri(self.vecsLeft[which_t],
                         self.vecsImages[:, which_t, :])
         self.vecsLeft[which_t + 1] = np.tensordot(self.mps.mps[which_t],
                                                   tmp, ([0, 1], [0, 1]))
         norm = np.linalg.norm(self.vecsLeft[which_t + 1], axis=0)
         self.norms[which_t, :] = norm
         self.vecsLeft[which_t + 1] /= norm.repeat(
             self.mps.virtual_dim[which_t + 1]).reshape(
                 self.numVecSample, self.mps.virtual_dim[which_t + 1]).T
     if (which_side is 'right') or (which_side is 'both'):
         tmp = tm.khatri(self.vecsRight[which_t],
                         self.vecsImages[:, which_t, :])
         self.vecsRight[which_t - 1] = np.tensordot(self.mps.mps[which_t],
                                                    tmp, ([2, 1], [0, 1]))
         norm = np.linalg.norm(self.vecsRight[which_t - 1], axis=0)
         self.norms[which_t, :] = norm
         self.vecsRight[which_t - 1] /= norm.repeat(
             self.mps.virtual_dim[which_t]).reshape(
                 self.numVecSample, self.mps.virtual_dim[which_t]).T
Beispiel #20
0
 def absorb_lm(self, nt, if_sqrt, which_vb):
     # which_vb does NOT count physical bond
     tensor = self.tensors[nt].copy()
     if if_sqrt:
         if which_vb is 'all':
             tensor = tm.absorb_matrices2tensor(tensor, [
                 np.diag(np.sqrt(self.lm[self.pos_lm[nt][n]]))
                 for n in range(0, self.nVirtual)
             ], [n + 1 for n in range(0, self.nVirtual)])
         elif type(which_vb) is int:
             tensor = tm.absorb_matrix2tensor(
                 tensor,
                 np.diag(np.sqrt(self.lm[self.pos_lm[nt][which_vb]])),
                 which_vb + 1)
         else:
             tensor = tm.absorb_matrices2tensor(tensor, [
                 np.diag(np.sqrt(self.lm[self.pos_lm[nt][n]]))
                 for n in which_vb
             ], [n + 1 for n in which_vb])
     else:
         if which_vb is 'all':
             tensor = tm.absorb_matrices2tensor(tensor, [
                 np.diag(self.lm[self.pos_lm[nt][n]])
                 for n in range(0, self.nVirtual)
             ], [n + 1 for n in range(0, self.nVirtual)])
         elif type(which_vb) is int:
             tensor = tm.absorb_matrix2tensor(
                 tensor, np.diag(self.lm[self.pos_lm[nt][which_vb]]),
                 which_vb + 1)
         else:
             tensor = tm.absorb_matrices2tensor(
                 tensor,
                 [np.diag(self.lm[self.pos_lm[nt][n]])
                  for n in which_vb], [n + 1 for n in which_vb])
     return tensor
Beispiel #21
0
 def bond_env_matrix_simple(self, nt, vb, is_symme=True, is_normalize=True):
     # the nb-th bond matrix of the nt-th tensor (including the phys bond)
     bonds = list(range(0, self.nVirtual))
     bonds.remove(vb)
     tmp = self.absorb_lm(nt, False, bonds)
     bonds = list(range(0, self.nVirtual + 1))
     bonds.remove(vb + 1)
     tmp = np.tensordot(tmp, tmp, (bonds, bonds))
     if is_symme:
         tmp = (tmp + tmp.conj().T) / 2
     if is_normalize:
         tmp = tm.normalize_tensor(tmp)[0]
     return tmp
Beispiel #22
0
 def compute_bond_vectors(self, nb=0):
     # Contract the samples to the MPS but left the nb-th physical bond empty
     # The bond vectors are normalized
     vecsL = np.ones((1, self.numVecSample))
     for nt in range(0, nb):
         s = self.mps.mps[nt].shape
         tmp = tm.khatri(vecsL, self.vecsImages[:, nt, :].squeeze())
         vecsL = np.tensordot(self.mps.mps[nt], tmp, ([0, 1], [0, 1]))
         norm = np.linalg.norm(vecsL, axis=0)
         vecsL /= norm.repeat(s[2]).reshape(self.numVecSample, s[2]).T
     vecsR = np.ones((1, self.numVecSample))
     for nt in range(self.length - 1, nb, -1):
         s = self.mps.mps[nt].shape
         tmp = tm.khatri(vecsR, self.vecsImages[:, nt, :].squeeze())
         vecsR = np.tensordot(self.mps.mps[nt], tmp, ([2, 1], [0, 1]))
         norm = np.linalg.norm(vecsR, axis=0)
         vecsR /= norm.repeat(s[2]).reshape(self.numVecSample, s[2]).T
     s = self.mps.mps[nb].shape
     tmp = np.tensordot(self.mps.mps[nb], tm.khatri(vecsL, vecsR),
                        ([0, 2], [0, 1]))
     norm = np.linalg.norm(tmp, axis=0)
     tmp /= norm.repeat(s[2]).reshape(self.numVecSample, s[2]).T
     return tmp
Beispiel #23
0
    def observation_kagome(self, j1, j2, hx, hz):
        # compatible to one-site iDMRG and one-site deep iDMRG
        z = np.linalg.norm(self.tensors[0].reshape(-1, ))
        tmp = self.tensors[0].reshape((self.d, ) * 3 + (self.chi, ) * 3) / z
        mag = dict()
        mag['x'] = np.zeros((3, ))
        mag['z'] = np.zeros((3, ))
        for n in range(3):
            ind = list(range(6))
            ind.pop(n)
            rho = np.tensordot(tmp.conj(), tmp, [ind, ind])
            mag['x'][n] = np.trace(rho.dot(self.operators[1]))
            mag['z'][n] = np.trace(rho.dot(self.operators[3]))

        energy = np.zeros(self.rho.__len__(), )
        j_coup = [j1, j1, j2]
        for n in range(self.rho.__len__()):
            h = j_coup[n] * (
                np.kron(self.operators[4], self.operators[5]) / 2 +
                np.kron(self.operators[5], self.operators[4]) / 2 +
                np.kron(self.operators[3], self.operators[3]))
            energy[n] = np.trace(self.rho[n].dot(h))
        energy_site = np.sum(energy) - hx * (
            mag['x'][0] / 2 + mag['x'][1] + mag['x'][2] / 2) - hz * (
                mag['z'][0] / 2 + mag['z'][1] + mag['z'][2] / 2)
        energy_site /= 2

        lm = list()
        lm.append(
            np.linalg.svd(self.tensors[0].transpose(0, 3, 1, 2, 4, 5).reshape(
                self.d * self.chi, self.d * self.d * self.chi * self.chi),
                          compute_uv=False))
        lm.append(
            np.linalg.svd(self.tensors[0].transpose(1, 4, 0, 2, 3, 5).reshape(
                self.d * self.chi, self.d * self.d * self.chi * self.chi),
                          compute_uv=False))
        lm.append(
            np.linalg.svd(self.tensors[0].transpose(2, 5, 0, 1, 3, 4).reshape(
                self.d * self.chi, self.d * self.d * self.chi * self.chi),
                          compute_uv=False))
        ent = [tm.entanglement_entropy(x) for x in lm]
        return energy, mag, energy_site, ent
Beispiel #24
0
 def analyse_dataset(self):
     # Total number of samples
     self.dataInfo['NumTotalTrain'] = self.labels.__len__()
     # Order the samples and labels
     order = np.argsort(self.labels)
     self.images = bf.sort_vecs(self.images, order, which=1)
     self.labels = np.array(sorted(self.labels))
     # Total number of classes
     self.dataInfo['NumClass'] = int(self.labels[-1] + 1)
     # Detailed information
     self.dataInfo['nStart'] = np.zeros((self.dataInfo['NumClass'], ), dtype=int)
     self.dataInfo['nClassNum'] = np.zeros((self.dataInfo['NumClass'],), dtype=int)
     self.dataInfo['nStart'][0] = 0
     for n in range(1, self.dataInfo['NumClass']):
         x = tm.arg_find_array(self.labels[self.dataInfo['nStart'][n-1] + 1:] == n,
                               1, 'first')
         self.dataInfo['nClassNum'][n-1] = x + 1
         self.dataInfo['nStart'][n] = x + self.dataInfo['nStart'][n-1] + 1
     self.dataInfo['nClassNum'][-1] = \
         self.dataInfo['NumTotalTrain'] - self.dataInfo['nStart'][-1]
Beispiel #25
0
 def rho_two_body_nlm_simple(self, n_lm):
     nt1 = self.lm_ten_bond[n_lm, 0, 0]
     vb1 = self.lm_ten_bond[n_lm, 0, 1]
     nt2 = self.lm_ten_bond[n_lm, 1, 0]
     vb2 = self.lm_ten_bond[n_lm, 1, 1]
     if self._is_debug:
         if n_lm != self.pos_lm[nt2][vb2]:
             bf.print_error(
                 'In rho_two_body_simple, the two virtual bonds must'
                 'correspond to the same lambda')
     bonds = list(range(0, self.nVirtual))
     bonds.remove(vb1)
     tmp1 = self.absorb_lm(nt1, False, bonds)
     tmp2 = self.absorb_lm(nt2, False, 'all')
     if self.stateType is 'pure':
         bonds = list(range(1, self.nVirtual + 1))
         bonds.remove(vb1 + 1)
         tmp1 = np.tensordot(tmp1.conj(), tmp1, (bonds, bonds))
         bonds = list(range(1, self.nVirtual + 1))
         bonds.remove(vb2 + 1)
         tmp2 = np.tensordot(tmp2.conj(), tmp2, (bonds, bonds))
     elif self.stateType is 'mixed':
         s = tmp1.shape
         bonds = list(range(1, self.nVirtual + 2))
         bonds.remove(vb1 + 2)
         tmp1 = tmp1.reshape((self.d0, self.d0) + s[1:])
         tmp1 = np.tensordot(tmp1.conj(), tmp1, (bonds, bonds))
         s = tmp2.shape
         bonds = list(range(1, self.nVirtual + 2))
         bonds.remove(vb2 + 2)
         tmp2 = tmp2.reshape((self.d0, self.d0) + s[1:])
         tmp2 = np.tensordot(tmp2.conj(), tmp2, (bonds, bonds))
     rho = tm.cont([tmp1, tmp2], [[-1, 1, -3, 2], [-2, 1, -4, 2]])
     rho = rho.reshape(self.d0 * self.d0, self.d0 * self.d0)
     rho = (rho + rho.conj().T) / 2
     rho /= np.trace(rho)
     return rho
Beispiel #26
0
import os
import sys
import numpy as np
import library.Parameters as pm
import library.HamiltonianModule as hm
import library.TensorBasicModule as tm
import library.BasicFunctions as bf
import scipy.linalg as la
import pickle
import math
import os.path as opath
import time
import torch
import library.TNmachineLearning as TNML
from library.MPSClass import MpsOpenBoundaryClass
from algorithms.DeepMPSfinite import act_umpo_on_mps

num = 4
mps = tm.mps_ghz_state(num)
a = MpsOpenBoundaryClass(num, 2, 2)
mpd = tm.mpd_of_ghz(num)
mps = act_umpo_on_mps(mps, mpd)
a.input_mps(mps, if_deepcopy=False)
a.correct_orthogonal_center(a.length - 1)
a.check_mps_norm1()

f0 = a.fidelity_log_by_spins_up()
print(f0)
Beispiel #27
0
 def update_v_ctr_test(self, nt):
     for n in self.remaining_samples_test:
         self.v_ctr_test[n] = tm.absorb_vectors2tensors(
             self.tensors[nt], (self.v_ctr_test[n], self.vecsTest[:, nt, n]), (0, 1))
         self.v_ctr_test[n] /= np.linalg.norm(self.v_ctr_test[n])
Beispiel #28
0
 def update_v_ctr_train(self, nt):
     for n in self.remaining_samples_train:
         self.v_ctr_train[n] = tm.absorb_vectors2tensors(
             self.tensors[nt], (self.v_ctr_train[n], self.vecsImages[n][:, nt]), (0, 1))
         self.v_ctr_train[n] /= np.linalg.norm(self.v_ctr_train[n])
Beispiel #29
0
    def update_bath_onsite_kagome(self, j1, j2, hx, hz):
        # baths on the two branches
        op1 = tm.cont(
            [self.tensors[1].conj(), self.tensors[1], self.bath_op_onsite],
            [[4, 5, 1, 3, -1], [4, 5, 2, 3, -2], [1, 2]])
        op2 = tm.cont(
            [self.tensors[1].conj(), self.tensors[1], self.bath_op_onsite],
            [[4, 5, 2, 1, -1], [4, 5, 2, 3, -2], [1, 3]])
        self.bath_op_onsite += op1 + op2

        opp = [self.operators[5], self.operators[4],
               self.operators[3]]  # sd, su, sz on the physical site
        opb = [
            self.effective_ops[2], self.effective_ops[3], self.effective_ops[1]
        ]  # su, sd, sz on the 1st bath site
        for n in range(3):
            # 1st physical - 1st bath
            self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
                [[2, 4, 1, 6, -1], [3, 4, 5, 6, -2], [1, 5], [2, 3]])
            # 2nd physical - 1st bath
            self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
                [[3, 2, 5, 1, -1], [3, 4, 5, 6, -2], [1, 6], [2, 4]])
            # 1st physical - 2nd bath
            # self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
            #     [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
            #     [[2, 6, 3, 1, -1], [5, 6, 3, 4, -2], [1, 4], [2, 5]])

        opp = [self.operators[5], self.operators[4],
               self.operators[3]]  # sd, su, sz on the physical site
        opb = [
            self.effective_ops[6], self.effective_ops[7], self.effective_ops[5]
        ]  # su, sd, sz on the 2nd bath site
        for n in range(3):
            # 1st physical - 2nd bath
            self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
                [[2, 4, 1, 6, -1], [3, 4, 5, 6, -2], [1, 5], [2, 3]])
            # 2nd physical - 2nd bath
            self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
                [[3, 2, 5, 1, -1], [3, 4, 5, 6, -2], [1, 6], [2, 4]])
            # self.bath_op_onsite += j2 * (0.5 + 0.5 * (n == 2)) * tm.cont(
            #     [self.tensors[1].conj(), self.tensors[1], opb[n], opp[n]],
            #     [[5, 2, 1, 4, -1], [5, 6, 3, 4, -2], [1, 3], [2, 6]])
            # 2nd physical - 2nd bath

        op1 = [self.operators[4], self.operators[5],
               self.operators[3]]  # su, sd, sz on the 1st physical site
        op2 = [self.operators[5], self.operators[4],
               self.operators[3]]  # sd, su, sz on the 2nd physical site
        for n in range(3):
            self.bath_op_onsite += j1 * (0.5 + 0.5 * (n == 2)) * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], op1[n], op2[n]],
                [[1, 2, 3, 4, -1], [5, 6, 3, 4, -2], [1, 5], [2, 6]])

        if abs(hx) > 1e-15:
            op1 = self.operators[1]  # sx
            self.bath_op_onsite -= hx * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], op1],
                [[1, 5, 2, 3, -1], [4, 5, 2, 3, -2], [1, 4]])
            self.bath_op_onsite -= hx * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], op1],
                [[4, 1, 2, 3, -1], [4, 5, 2, 3, -2], [1, 5]])
        if abs(hz) > 1e-15:
            op1 = self.operators[3]  # sz
            self.bath_op_onsite -= hz * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], op1],
                [[1, 5, 2, 3, -1], [4, 5, 2, 3, -2], [1, 4]])
            self.bath_op_onsite -= hz * tm.cont(
                [self.tensors[1].conj(), self.tensors[1], op1],
                [[4, 1, 2, 3, -1], [4, 5, 2, 3, -2], [1, 5]])
        self.bath_op_onsite = (self.bath_op_onsite +
                               self.bath_op_onsite.conj().T) / 2
Beispiel #30
0
 def update_env_tree_dmrg(self, ne, decomp='qr'):
     # ne: which environment (0, 1, 2, 3)
     self.calculate_orthogonal_tensor(ne, decomp)
     s = self.tensors[ne + 1].shape
     d0 = np.round(np.sqrt(s[0]))
     tensor = self.tensors[ne + 1].reshape([d0, d0] + s[1:])
     tensor = self.evolve_central_tensor(tensor,
                                         self.model_related['h2_gate'].T,
                                         [0, 1])  # [0, 1, 2, 3, 4, 5]
     tensor1 = tensor.conj()
     if ne == 3:
         tensor1 = self.evolve_central_tensor(
             tensor1, self.model_related['hbath'][3].T,
             [1, 5])  # [1, 5, 0, 2, 3, 4]
         tensor1 = self.evolve_central_tensor(
             tensor1, self.model_related['hbath'][2].T,
             [1, 5])  # [1, 4, 5, 0, 2, 3]
         tensor1 = tensor1.transpose(3, 0, 4, 5, 1, 2)
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][0],
                                             [0, 2],
                                             if_permute_back=True)
         self.env[ne] = tm.cont(
             [tensor, tensor1, self.model_related['tensor_gate'][0]],
             [[6, 4, 1, -3, 2, 3], [5, 4, 1, -1, 2, 3], [5, -2, 6]])
     elif ne == 2:
         tensor1 = self.evolve_central_tensor(
             tensor1, self.model_related['hbath'][3].T,
             [1, 5])  # [1, 5, 0, 2, 3, 4]
         tensor1 = self.evolve_central_tensor(
             tensor1, self.model_related['hbath'][2].T,
             [1, 5])  # [1, 4, 5, 0, 2, 3]
         tensor1 = self.evolve_central_tensor(
             tensor1, self.model_related['hbath'][1].T,
             [3, 5])  # [0, 3, 1, 4, 5, 2]
         tensor1 = tensor1.transpose(0, 2, 5, 1, 3, 4)
         self.env[ne] = tm.cont(
             [tensor, tensor1, self.model_related['tensor_gate'][0]],
             [[6, 4, -3, 3, 1, 2], [5, 4, -1, 3, 1, 2], [5, -2, 6]])
     elif ne == 1:
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][0],
                                             [0, 2])  # [0, 2, 1, 3, 4, 5]
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][1],
                                             [0, 3])  # [0, 3, 2, 1, 4, 5]
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][2],
                                             [0, 4])  # [0, 4, 3, 2, 1, 5]
         tensor = tensor.transpose(0, 4, 3, 2, 1, 5)
         self.env[ne] = tm.cont(
             [tensor, tensor1, self.model_related['tensor_gate'][1]],
             [[4, 6, 1, 2, 3, -3], [4, 5, 1, 2, 3, -1], [5, -2, 6]])
     elif ne == 0:
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][0],
                                             [0, 2])  # [0, 2, 1, 3, 4, 5]
         tensor = self.evolve_central_tensor(tensor,
                                             self.model_related['hbath'][1],
                                             [0, 3])  # [0, 3, 2, 1, 4, 5]
         tensor = tensor.transpose(0, 3, 2, 1, 4, 5)
         tensor1 = self.evolve_central_tensor(
             tensor1,
             self.model_related['hbath'][3].T, [1, 5],
             if_permute_back=True)
         self.env[ne] = tm.cont(
             [tensor, tensor1, self.model_related['tensor_gate'][1]],
             [[4, 6, 1, 2, -3, 3], [4, 5, 1, 2, -1, 3], [5, -2, 6]])
     self.env[ne] = (self.env[ne] + self.env[ne].transpose(2, 1, 0)) / 2
     self.env[ne] /= np.linalg.norm(self.env[ne].reshape(-1, ))