Ejemplo n.º 1
0
    def compute_psi2(self):
        merg_psi, idx = contra(self.tensors[self.current_site],
                               self.order_left[self.current_site],
                               self.tensors[self.current_site + 1],
                               self.order_left[self.current_site + 1])
        merg_psi_r, idx_r = contra(self.image_tensors[self.current_site],
                                   self.order_right[self.current_site],
                                   self.image_tensors[self.current_site + 1],
                                   self.order_right[self.current_site + 1])
        merg, idx = contra(merg_psi, idx, merg_psi_r, idx_r)

        if self.current_site == 0:
            psi, idx_psi = contra(merg, idx, self.contraction_psi2[2][0],
                                  self.contraction_psi2[2][1])
        else:
            if self.current_site == self.n - 2:
                psi, idx_psi = contra(
                    merg, idx, self.contraction_psi2[self.current_site - 1][0],
                    self.contraction_psi2[self.current_site - 1][1])
                # Z, idz = contra(Z, idz, merg_l, idm_l)
            else:
                psi_r, idx_r = contra(
                    merg, idx, self.contraction_psi2[self.current_site - 1][0],
                    self.contraction_psi2[self.current_site - 1][1])
                psi, idx_psi = contra(
                    psi_r, idx_r,
                    self.contraction_psi2[self.current_site + 2][0],
                    self.contraction_psi2[self.current_site + 2][1])
                # Z, idz = contra(Z, idz, merg_l, idm_l)
        return psi
Ejemplo n.º 2
0
 def compute_Z(self):
     merg, idm = contra(self.tensors[self.current_site],
                        self.order[self.current_site],
                        self.tensors[self.current_site + 1],
                        self.order[self.current_site + 1])
     merg_l, idm_l = contra(self.tensors[self.current_site],
                            self.order_left[self.current_site],
                            self.tensors[self.current_site + 1],
                            self.order_left[self.current_site + 1])
     merg_m, idm_m = contra(merg, idm, merg_l, idm_l)
     if self.current_site == 0:
         Z, idz = contra(merg_m, idm_m,
                         self.contraction_z[self.current_site + 2][0],
                         self.contraction_z[self.current_site + 2][1])
         # Z, idz = contra(Z, idz, merg_l,idm_l)
     else:
         if self.current_site == self.n - 2:
             Z, idz = contra(merg_m, idm_m,
                             self.contraction_z[self.current_site - 1][0],
                             self.contraction_z[self.current_site - 1][1])
             # Z, idz = contra(Z, idz, merg_l, idm_l)
         else:
             Z_l, idz_l = contra(
                 merg_m, idm_m,
                 self.contraction_z[self.current_site - 1][0],
                 self.contraction_z[self.current_site - 1][1])
             Z, idz = contra(Z_l, idz_l,
                             self.contraction_z[self.current_site + 2][0],
                             self.contraction_z[self.current_site + 2][1])
             # Z, idz = contra(Z, idz, merg_l, idm_l)
     return Z
Ejemplo n.º 3
0
    def contraction_update_all_left2(self):
        # v1=torch.Tensor([0,1])
        # v2=torch.Tensor([1,0])

        self.going_righ = 0
        merg, idm = contra(self.tensors[0], self.order_left[0],
                           self.tensors[0], self.order[0])
        self.contraction_z[0] = ([merg, idm])
        merg_psi, merg_psi_idx = contra(self.tensors[0], self.order_left[0],
                                        self.image_tensors[0],
                                        self.order_right[0])
        self.contraction_psi2[0] = ([merg_psi, merg_psi_idx])

        for i in range(1, self.n - 2):
            merg, idm = contra(merg, idm, self.tensors[i], self.order_left[i])
            merg, idm = contra(merg, idm, self.tensors[i], self.order[i])
            self.contraction_z[i] = ([merg, idm])

            merg_psi, merg_psi_idx = contra(merg_psi, merg_psi_idx,
                                            self.tensors[i],
                                            self.order_left[i])
            merg_psi, merg_psi_idx = contra(merg_psi, merg_psi_idx,
                                            self.image_tensors[i],
                                            self.order_right[i])
            self.contraction_psi2[i] = ([merg_psi, merg_psi_idx])
Ejemplo n.º 4
0
    def contraction_update_all_left(self):
        v1 = torch.Tensor([0, 1]).cuda()
        v2 = torch.Tensor([1, 0]).cuda()

        self.going_righ = 0
        merg, idm = contra(self.tensors[0], self.order_left[0],
                           self.tensors[0], self.order[0])
        self.contraction_z[0] = ([merg, idm])
        merg_psi = []
        for j in range(self.m):
            if self.image[0, j] == 1:  #n*m
                mergv, idv = contra(self.tensors[0], self.order_left[0], v1,
                                    [0])
            else:
                mergv, idv = contra(self.tensors[0], self.order_left[0], v2,
                                    [0])
            merg_psi.append(mergv)
        self.contraction_psi[0] = ([merg_psi, idv])

        for i in range(1, self.n - 2):
            merg, idm = contra(merg, idm, self.tensors[i], self.order_left[i])
            merg, idm = contra(merg, idm, self.tensors[i], self.order[i])
            self.contraction_z[i] = ([merg, idm])

            merg_psi = []
            for j in range(0, self.m):
                if self.image[i, j] == 1:  # n*m
                    mergv, idvm = contra(self.contraction_psi[i - 1][0][j],
                                         idv, self.tensors[i],
                                         self.order_left[i])
                    mergv, idvm = contra(mergv, idvm, v1, [2 * i])
                else:
                    mergv, idvm = contra(self.contraction_psi[i - 1][0][j],
                                         idv, self.tensors[i],
                                         self.order_left[i])
                    mergv, idvm = contra(mergv, idvm, v2, [2 * i])
                merg_psi.append(mergv)
            idv = idvm
            self.contraction_psi[i] = ([merg_psi, idvm])
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
d1 = 30
d2 = 30
r = 10
learning_rate = 0.1
loops = 30
his_loss = torch.zeros(1, loops)
A = torch.rand(d1, d2).cuda()
E = torch.rand(d1, d2).cuda()
M = torch.rand(d1, r).cuda()
N = torch.rand(r, d2).cuda()
A = A / A.norm()
E = E / E.norm()
M = M / M.norm()
N = N / N.norm()
t1 = time.time()
for loop in range(loops):
    A0 = (contra(M, [1, 2], N, [2, 3]))[0]
    loss = (contra((A - A0), [1, 2], E, [1, 2]))[0]

    grad_M = 2 * loss * contra(E, [0, 2], N, [1, 2])[0]

    grad_N = 2 * loss * contra(M, [1, 2], E, [1, 3])[0]

    M = M + learning_rate * grad_M
    N = N + learning_rate * grad_N
    his_loss[0, loop] = loss**2

t2 = time.time()
print(his_loss, t2 - t1)
Ejemplo n.º 6
0
    def train(self, loops):
        for loop in range(loops):
            self.going_righ = 0
            for i in np.arange(self.n - 2, 0, -1):

                self.current_site = i
                self.merged_tensor, self.merged_idx = contra(
                    self.tensors[self.current_site],
                    self.order_left[self.current_site],
                    self.tensors[self.current_site + 1],
                    self.order_left[self.current_site + 1])
                self.Z = self.compute_Z()
                self.psi = self.compute_psi()
                dmerge = self.gradient_descent
                # nll=0
                # for k in range(self.m):
                #     nll=nll+(torch.log(self.psi[k] *self.psi[k] /self.Z))
                # nll=nll/self.m
                # print nll,i
                self.tensors[self.current_site], self.tensors[
                    self.current_site + 1] = svd_update(
                        self.tensors[self.current_site],
                        self.order[self.current_site],
                        self.tensors[self.current_site + 1],
                        self.order[self.current_site + 1], dmerge,
                        self.going_righ, 0.0002, self.max_bond)
                self.contraction_updat_twosite()

            self.going_righ = 1
            for i in range(self.n - 2):
                self.current_site = i
                self.merged_tensor, self.merged_idx = contra(
                    self.tensors[self.current_site],
                    self.order_left[self.current_site],
                    self.tensors[self.current_site + 1],
                    self.order_left[self.current_site + 1])
                self.Z = self.compute_Z()
                self.psi = self.compute_psi()
                # nll = 0
                # for k in range(self.m):
                #     nll = nll + ( torch.log(self.psi[k] *self.psi[k]  / self.Z))
                # nll=nll/self.m
                # print nll,i
                dmerge = self.gradient_descent
                self.tensors[self.current_site], self.tensors[
                    self.current_site + 1] = svd_update(
                        self.tensors[self.current_site],
                        self.order[self.current_site],
                        self.tensors[self.current_site + 1],
                        self.order[self.current_site + 1], dmerge,
                        self.going_righ, 0.0002, self.max_bond)
                self.contraction_updat_twosite()
            for j in range(len(self.links)):
                self.Z = self.compute_Z()
                self.psi = self.compute_psi()
                k0 = self.links[j][0]
                k1 = self.links[j][1]
                dmerge = self.gradient_descent5(k0, k1)
                self.tensors[k0], self.tensors[k1] = svd_update(
                    self.tensors[k0], self.order[k0], self.tensors[k1],
                    self.order[k1], dmerge, self.going_righ, 0.0002,
                    self.max_bond)
                self.contraction_update_all_left()
            nll = 0
            for k in range(self.m):
                nll = nll + (torch.log(self.psi[k] * self.psi[k] / self.Z))
            nll = nll / self.m
            print nll
            if nll > self.nll_history[-1] + 0.002:
                self.nll_history.append(nll)
            else:
                break
Ejemplo n.º 7
0
    def gradient_descent5(self, j, k):
        self.current_site = j
        self.merged_tensor, self.merged_idx = contra(self.tensors[j],
                                                     self.order_left[j],
                                                     self.tensors[k],
                                                     self.order_left[k])
        merged_idx2 = self.merged_idx[:]
        for l in range(len(self.merged_idx)):
            if self.merged_idx[l] % 2 == 1:
                merged_idx2[l] = merged_idx2[l] - 8 * self.n

        mer_l, mer_l_idx = contra(self.tensors[0], self.order_left[0],
                                  self.tensors[0], self.order[0])
        for i in range(1, j):
            mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i],
                                      self.order_left[i])
            mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i],
                                      self.order[i])

        mer_r, mer_r_idx = contra(self.tensors[self.n - 1],
                                  self.order_left[self.n - 1],
                                  self.tensors[self.n - 1],
                                  self.order[self.n - 1])
        for i in np.arange(self.n - 2, k, -1):
            mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i],
                                      self.order_left[i])
            mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i],
                                      self.order[i])

        mer_m, mer_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1],
                                  self.tensors[j + 1], self.order[j + 1])
        for i in range(j + 2, k):
            mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i],
                                      self.order_left[i])
            mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i],
                                      self.order[i])

        dZ, dZ_idx = contra(mer_l, mer_l_idx, self.merged_tensor, merged_idx2)
        dZ, dZ_idx = contra(dZ, dZ_idx, mer_r, mer_r_idx)
        dZ, dZ_idx = contra(dZ, dZ_idx, mer_m, mer_m_idx)

        dpsi = []
        dPsi = []
        v1 = torch.Tensor([0, 1]).cuda()
        v2 = torch.Tensor([1, 0]).cuda()
        for jl in range(self.m):
            if self.image[0, jl] == 1:
                psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0],
                                          v1, [0])
            else:
                psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0],
                                          v2, [0])
            dpsi.append(psi_l)
        for i in range(1, j):
            for jl in range(self.m):
                dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx,
                                              self.tensors[i],
                                              self.order_left[i])
                if self.image[j, jl] == 1:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1,
                                               [2 * i])
                else:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2,
                                               [2 * i])
                dpsi[jl] = psi_l
            psi_l_idx = psi_l_idx2[:]
        for i in range(j + 1, k):
            for jl in range(self.m):
                dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx,
                                              self.tensors[i],
                                              self.order_left[i])
                if self.image[j, jl] == 1:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1,
                                               [2 * i])
                else:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2,
                                               [2 * i])
                dpsi[jl] = psi_l
            psi_l_idx = psi_l_idx2[:]
        for i in range(k + 1, self.n):
            for jl in range(self.m):
                dpsi[jl], psi_l_idx2 = contra(dpsi[jl], psi_l_idx,
                                              self.tensors[i],
                                              self.order_left[i])
                if self.image[j, jl] == 1:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v1,
                                               [2 * i])
                else:
                    psi_l, psi_l_idx2 = contra(dpsi[jl], psi_l_idx2, v2,
                                               [2 * i])
                dpsi[jl] = psi_l
            psi_l_idx = psi_l_idx2[:]
        dPsi.append(dpsi + [psi_l_idx])
        dmerge = torch.zeros((self.merged_tensor).size()).cuda()

        for im1 in [1, 2]:
            for im2 in [1, 2]:
                dpsi = torch.zeros((dPsi[0][0]).size()).cuda()
                im = (self.image[self.current_site, :]
                      == im1) * (self.image[self.current_site + 1, :] == im2)
                for jl in range(self.m):
                    if im[jl] == 1:
                        dpsi = 2 * dPsi[0][jl] / self.psi[jl] + dpsi
                    dmerge = tensor_slide(dmerge, self.merged_idx,
                                          [2 - im1, 2 - im2], [j * 2, k * 2],
                                          dpsi, (dPsi[0][-1]))
        dmerge = tensor_add(dmerge / self.n, self.merged_idx, -2 * dZ / self.Z,
                            dZ_idx)

        gnorm = torch.norm(dmerge) / 20
        if (gnorm < 1.0):  # % & & self.bond_dims(self.current_bond) <= 50;
            dmerge = dmerge / gnorm
        dmerge = self.merged_tensor + self.learning_rate * dmerge

        return dmerge
Ejemplo n.º 8
0
    def gradient_descent(self):
        dpsi = []
        dPsi = []
        merged_idx2 = self.merged_idx[:]
        for k in range(len(self.merged_idx)):
            if self.merged_idx[k] % 2 == 1:
                merged_idx2[k] = merged_idx2[k] - 8 * self.n

        if self.current_site == 0:

            dZ, dZ_idx = contra(self.merged_tensor, merged_idx2,
                                self.contraction_z[self.current_site + 2][0],
                                self.contraction_z[self.current_site + 2][1])
            for j in range(self.m):
                dpsi.append(self.contraction_psi[self.current_site + 2][0][j])
            dpsi_idx = self.contraction_psi[self.current_site + 2][1]
            dPsi.append(dpsi + [dpsi_idx])
        else:
            if self.current_site == self.n - 2:
                dZ, dZ_idx = contra(
                    self.merged_tensor, merged_idx2,
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                for j in range(self.m):
                    dpsi.append(self.contraction_psi[self.current_site -
                                                     1][0][j])
                dpsi_idx = self.contraction_psi[self.current_site - 1][1]
                dPsi.append(dpsi + [dpsi_idx])
            else:
                merg_Z, idz = contra(
                    self.merged_tensor, merged_idx2,
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                dZ, dZ_idx = contra(
                    merg_Z, idz, self.contraction_z[self.current_site + 2][0],
                    self.contraction_z[self.current_site + 2][1])
                for j in range(self.m):
                    merg_psi, dpsi_idx = contra(
                        self.contraction_psi[self.current_site - 1][0][j],
                        self.contraction_psi[self.current_site - 1][1],
                        self.contraction_psi[self.current_site + 2][0][j],
                        self.contraction_psi[self.current_site + 2][1])
                    dpsi.append(merg_psi)
                dPsi.append(dpsi + [dpsi_idx])
        dmerge = torch.zeros((self.merged_tensor).size()).cuda()

        for im1 in [1, 2]:
            for im2 in [1, 2]:
                dpsi = torch.zeros((dPsi[0][0]).size()).cuda()
                im = (self.image[self.current_site, :]
                      == im1) * (self.image[self.current_site + 1, :] == im2)
                for j in range(self.m):
                    if im[j] == 1:
                        dpsi = 2 * dPsi[0][j] / self.psi[j] + dpsi
                    dmerge = tensor_slide(
                        dmerge, self.merged_idx, [2 - im1, 2 - im2],
                        [self.current_site * 2, self.current_site * 2 + 2],
                        dpsi, (dPsi[0][-1]))
        dmerge = tensor_add(dmerge / self.n, self.merged_idx, -2 * dZ / self.Z,
                            dZ_idx)

        gnorm = torch.norm(dmerge) / 20
        if (gnorm < 1.0):  #% & & self.bond_dims(self.current_bond) <= 50;
            dmerge = dmerge / gnorm
        dmerge = self.merged_tensor + self.learning_rate * dmerge

        return dmerge
Ejemplo n.º 9
0
    def compute_psi(self):
        Psi = []
        v1 = torch.Tensor([0, 1]).cuda()
        v2 = torch.Tensor([1, 0]).cuda()
        if self.current_site == 0:
            for j in range(self.m):
                if self.image[0, j] == 1:  # n*m
                    mergv, idvm = contra(self.tensors[0], self.order_left[0],
                                         v1, [0])
                    mergv, idvm = contra(mergv, idvm, self.tensors[1],
                                         self.order_left[1])
                    if self.image[1, j] == 1:
                        mergv, idvm = contra(mergv, idvm, v1, [2])
                    else:
                        mergv, idvm = contra(mergv, idvm, v2, [2])
                else:
                    mergv, idvm = contra(self.tensors[0], self.order_left[0],
                                         v2, [0])
                    mergv, idvm = contra(mergv, idvm, self.tensors[1],
                                         self.order_left[1])
                    if self.image[1, j] == 1:
                        mergv, idvm = contra(mergv, idvm, v1, [2])
                    else:
                        mergv, idvm = contra(mergv, idvm, v2, [2])

                psi, id = contra(mergv, idvm, self.contraction_psi[2][0][j],
                                 self.contraction_psi[2][1])
                Psi.append(psi)
        else:
            if self.current_site == self.n - 2:
                for j in range(self.m):
                    if self.image[self.n - 2, j] == 1:  # n*m
                        mergv, idvm = contra(self.tensors[self.n - 2],
                                             self.order_left[self.n - 2], v1,
                                             [2 * self.n - 4])
                        mergv, idvm = contra(mergv, idvm,
                                             self.tensors[self.n - 1],
                                             self.order_left[self.n - 1])
                        if self.image[self.n - 1, j] == 1:
                            mergv, idvm = contra(mergv, idvm, v1,
                                                 [2 * self.n - 2])
                        else:
                            mergv, idvm = contra(mergv, idvm, v2,
                                                 [2 * self.n - 2])
                    else:
                        mergv, idvm = contra(self.tensors[self.n - 2],
                                             self.order_left[self.n - 2], v2,
                                             [2 * self.n - 4])
                        mergv, idvm = contra(mergv, idvm,
                                             self.tensors[self.n - 1],
                                             self.order_left[self.n - 1])
                        if self.image[self.n - 1, j] == 1:
                            mergv, idvm = contra(mergv, idvm, v1,
                                                 [2 * self.n - 2])
                        else:
                            mergv, idvm = contra(mergv, idvm, v2,
                                                 [2 * self.n - 2])

                    psi, id = contra(mergv, idvm,
                                     self.contraction_psi[self.n - 3][0][j],
                                     self.contraction_psi[self.n - 3][1])
                    Psi.append(psi)

            else:
                for j in range(self.m):
                    if self.image[self.current_site, j] == 1:  # n*m
                        mergv, idvm = contra(
                            self.tensors[self.current_site],
                            self.order_left[self.current_site], v1,
                            [2 * self.current_site])
                        mergv, idvm = contra(
                            mergv, idvm, self.tensors[self.current_site + 1],
                            self.order_left[self.current_site + 1])
                        if self.image[self.current_site + 1, j] == 1:
                            mergv, idvm = contra(mergv, idvm, v1,
                                                 [2 * self.current_site + 2])
                        else:
                            mergv, idvm = contra(mergv, idvm, v2,
                                                 [2 * self.current_site + 2])
                    else:
                        mergv, idvm = contra(
                            self.tensors[self.current_site],
                            self.order_left[self.current_site], v2,
                            [2 * self.current_site])
                        mergv, idvm = contra(
                            mergv, idvm, self.tensors[self.current_site + 1],
                            self.order_left[self.current_site + 1])
                        if self.image[self.current_site + 1, j] == 1:
                            mergv, idvm = contra(mergv, idvm, v1,
                                                 [2 * self.current_site + 2])
                        else:
                            mergv, idvm = contra(mergv, idvm, v2,
                                                 [2 * self.current_site + 2])

                    mergv, idvm = contra(
                        mergv, idvm,
                        self.contraction_psi[self.current_site - 1][0][j],
                        self.contraction_psi[self.current_site - 1][1])
                    psi, id = contra(
                        mergv, idvm,
                        self.contraction_psi[self.current_site + 2][0][j],
                        self.contraction_psi[self.current_site + 2][1])
                    Psi.append(psi)

        return Psi
Ejemplo n.º 10
0
    def contraction_updat_twosite(self):
        v1 = torch.Tensor([0, 1]).cuda()
        v2 = torch.Tensor([1, 0]).cuda()
        if self.going_righ == 0:
            if self.current_site == self.n - 2:
                merg, idm = contra(self.tensors[self.n - 1],
                                   self.order[self.n - 1],
                                   self.tensors[self.n - 1],
                                   self.order_left[self.n - 1])
                # self.contraction_z[self.current_site+1]=merg
                merg_psi = []
                for j in range(self.m):
                    if self.image[self.n - 1, j] == 1:  # n*m
                        mergv, idvm = contra(self.tensors[self.n - 1],
                                             self.order_left[self.n - 1], v1,
                                             [self.n * 2 - 2])
                    else:
                        mergv, idvm = contra(self.tensors[self.n - 1],
                                             self.order_left[self.n - 1], v2,
                                             [self.n * 2 - 2])
                    merg_psi.append(mergv)

            else:

                merg, idm = contra(
                    self.tensors[self.current_site + 1],
                    self.order_left[self.current_site + 1],
                    self.contraction_z[self.current_site + 2][0],
                    self.contraction_z[self.current_site + 2][1])
                merg, idm = contra(merg, idm,
                                   self.tensors[self.current_site + 1],
                                   self.order[self.current_site + 1])

                merg_psi = []
                for j in range(0, self.m):
                    if self.image[self.current_site + 1, j] == 1:  # n*m
                        mergv, idvm = contra(
                            self.tensors[self.current_site + 1],
                            self.order_left[self.current_site + 1],
                            self.contraction_psi[self.current_site + 2][0][j],
                            self.contraction_psi[self.current_site + 2][1])
                        mergv, idvm = contra(mergv, idvm, v1,
                                             [2 * self.current_site + 2])
                    else:
                        mergv, idvm = contra(
                            self.tensors[self.current_site + 1],
                            self.order_left[self.current_site + 1],
                            self.contraction_psi[self.current_site + 2][0][j],
                            self.contraction_psi[self.current_site + 2][1])
                        mergv, idvm = contra(mergv, idvm, v2,
                                             [2 * self.current_site + 2])
                    merg_psi.append(mergv)

            self.contraction_psi[self.current_site + 1] = ([merg_psi, idvm])
            self.contraction_z[self.current_site + 1] = ([merg, idm])

        if self.going_righ == 1:
            if self.current_site == 0:
                merg, idm = contra(self.tensors[0], self.order[0],
                                   self.tensors[0], self.order_left[0])
                # self.contraction_z[self.current_site+1]=merg
                merg_psi = []
                for j in range(self.m):
                    if self.image[0, j] == 1:  # n*m
                        mergv, idvm = contra(self.tensors[0],
                                             self.order_left[0], v1, [0])
                    else:
                        mergv, idvm = contra(self.tensors[0],
                                             self.order_left[0], v2, [0])
                    merg_psi.append(mergv)

            else:

                merg, idm = contra(
                    self.tensors[self.current_site],
                    self.order_left[self.current_site],
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                merg, idm = contra(merg, idm, self.tensors[self.current_site],
                                   self.order[self.current_site])

                merg_psi = []
                for j in range(0, self.m):
                    if self.image[self.current_site, j] == 1:  # n*m
                        mergv, idvm = contra(
                            self.tensors[self.current_site],
                            self.order_left[self.current_site],
                            self.contraction_psi[self.current_site - 1][0][j],
                            self.contraction_psi[self.current_site - 1][1])
                        mergv, idvm = contra(mergv, idvm, v1,
                                             [2 * self.current_site])
                    else:
                        mergv, idvm = contra(
                            self.tensors[self.current_site],
                            self.order_left[self.current_site],
                            self.contraction_psi[self.current_site - 1][0][j],
                            self.contraction_psi[self.current_site - 1][1])
                        mergv, idvm = contra(mergv, idvm, v2,
                                             [2 * self.current_site])
                    merg_psi.append(mergv)

                self.contraction_psi[self.current_site] = ([merg_psi, idvm])
                self.contraction_z[self.current_site] = ([merg, idm])
Ejemplo n.º 11
0
    def gradient_descent2(self):
        dpsi = []
        dPsi = []
        merged_idx2 = self.merged_idx[:]
        for k in range(len(self.merged_idx)):
            if self.merged_idx[k] % 2 == 1:
                merged_idx2[k] = merged_idx2[k] - 8 * self.n
        merge_psi, merge_psi_idx = contra(
            self.image_tensors[self.current_site],
            self.order_right[self.current_site],
            self.image_tensors[self.current_site + 1],
            self.order_right[self.current_site + 1])
        if self.current_site == 0:

            dZ, dZ_idx = contra(self.merged_tensor, merged_idx2,
                                self.contraction_z[self.current_site + 2][0],
                                self.contraction_z[self.current_site + 2][1])
            dPsi, dPsi_idx = contra(
                merge_psi, merge_psi_idx,
                self.contraction_psi2[self.current_site + 2][0],
                self.contraction_psi2[self.current_site + 2][1])

        else:
            if self.current_site == self.n - 2:
                dZ, dZ_idx = contra(
                    self.merged_tensor, merged_idx2,
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                dPsi, dPsi_idx = contra(
                    merge_psi, merge_psi_idx,
                    self.contraction_psi2[self.current_site - 1][0],
                    self.contraction_psi2[self.current_site - 1][1])

            else:
                merg_Z, idz = contra(
                    self.merged_tensor, merged_idx2,
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                dZ, dZ_idx = contra(
                    merg_Z, idz, self.contraction_z[self.current_site + 2][0],
                    self.contraction_z[self.current_site + 2][1])
                merg_Psi, idpsi = contra(
                    merge_psi, merge_psi_idx,
                    self.contraction_psi2[self.current_site - 1][0],
                    self.contraction_psi2[self.current_site - 1][1])
                dPsi, dPsi_idx = contra(
                    merg_Psi, idpsi,
                    self.contraction_psi2[self.current_site + 2][0],
                    self.contraction_psi2[self.current_site + 2][1])

        # for im1 in [1,2]:
        #     for im2 in [1,2]:
        #         dpsi=torch.zeros((dPsi[0][0]).size()).cuda()
        #         im=(self.image[self.current_site,:]==im1)*(self.image[self.current_site+1,:]==im2)
        #         for j in range(self.m):
        #             if im[j]==1:
        #                 dpsi=2*dPsi[0][j]/self.psi[j]+dpsi
        #             dmerge=tensor_slide(dmerge,self.merged_idx,[2-im1,2-im2],[self.current_site*2,self.current_site*2+2],dpsi,(dPsi[0][-1]))
        psi_1 = 1.0 / self.psi
        dPsi, dPsi_idx = contra(dPsi, dPsi_idx, psi_1, [-1])
        dmerge = tensor_add(2 * dPsi, dPsi_idx, -2 * 4 * self.m * dZ / self.Z,
                            dZ_idx)

        gnorm = torch.norm(dmerge) / 80
        if (gnorm < 1.0):  #% & & self.bond_dims(self.current_bond) <= 50;
            dmerge = dmerge / gnorm
        dmerge = tensor_add(self.merged_tensor, self.merged_idx,
                            self.learning_rate * dmerge, dPsi_idx)

        return dmerge
Ejemplo n.º 12
0
    def gradient_descent25(self, j, k):
        self.current_site = j
        self.merged_tensor, self.merged_idx = contra(self.tensors[j],
                                                     self.order_left[j],
                                                     self.tensors[k],
                                                     self.order_left[k])
        merged_idx2 = self.merged_idx[:]
        psi_merg, psi_merg_idx = contra(self.image_tensors[j],
                                        self.order_right[j],
                                        self.image_tensors[k],
                                        self.order_right[k])
        for l in range(len(self.merged_idx)):
            if self.merged_idx[l] % 2 == 1:
                merged_idx2[l] = merged_idx2[l] - 8 * self.n

        mer_l, mer_l_idx = contra(self.tensors[0], self.order_left[0],
                                  self.tensors[0], self.order[0])
        psi_l, psi_l_idx = contra(self.tensors[0], self.order_left[0],
                                  self.image_tensors[0], self.order_right[0])
        for i in range(1, j):
            mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i],
                                      self.order_left[i])
            mer_l, mer_l_idx = contra(mer_l, mer_l_idx, self.tensors[i],
                                      self.order[i])

            psi_l, psi_l_idx = contra(psi_l, psi_l_idx, self.tensors[i],
                                      self.order_left[i])
            psi_l, psi_l_idx = contra(psi_l, psi_l_idx, self.image_tensors[i],
                                      self.order_right[i])

        mer_r, mer_r_idx = contra(self.tensors[self.n - 1],
                                  self.order_left[self.n - 1],
                                  self.tensors[self.n - 1],
                                  self.order[self.n - 1])

        psi_r, psi_r_idx = contra(self.tensors[self.n - 1],
                                  self.order_left[self.n - 1],
                                  self.image_tensors[self.n - 1],
                                  self.order_right[self.n - 1])
        for i in np.arange(self.n - 2, k, -1):
            mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i],
                                      self.order_left[i])
            mer_r, mer_r_idx = contra(mer_r, mer_r_idx, self.tensors[i],
                                      self.order[i])

            psi_r, psi_r_idx = contra(psi_r, psi_r_idx, self.tensors[i],
                                      self.order_left[i])
            psi_r, psi_r_idx = contra(psi_r, psi_r_idx, self.image_tensors[i],
                                      self.order_right[i])

        mer_m, mer_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1],
                                  self.tensors[j + 1], self.order[j + 1])
        psi_m, psi_m_idx = contra(self.tensors[j + 1], self.order_left[j + 1],
                                  self.image_tensors[j + 1],
                                  self.order_right[j + 1])
        for i in range(j + 2, k):
            mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i],
                                      self.order_left[i])
            mer_m, mer_m_idx = contra(mer_m, mer_m_idx, self.tensors[i],
                                      self.order[i])

            psi_m, psi_m_idx = contra(psi_m, psi_m_idx, self.tensors[i],
                                      self.order_left[i])
            psi_m, psi_m_idx = contra(psi_m, psi_m_idx, self.image_tensors[i],
                                      self.order_right[i])

        dZ, dZ_idx = contra(mer_l, mer_l_idx, self.merged_tensor, merged_idx2)
        dZ, dZ_idx = contra(dZ, dZ_idx, mer_r, mer_r_idx)
        dZ, dZ_idx = contra(dZ, dZ_idx, mer_m, mer_m_idx)

        dpsi, dpsi_idx = contra(psi_l, psi_l_idx, psi_merg, psi_merg_idx)
        dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_r, psi_r_idx)
        dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_m, psi_m_idx)

        psi_1 = 1.0 / self.psi
        dpsi, dpsi_idx = contra(dpsi, dpsi_idx, psi_1, [-1])
        dmerge = tensor_add(2 * dpsi / self.m, dpsi_idx, -2 * 4 * dZ / self.Z,
                            dZ_idx)

        gnorm = torch.norm(dmerge) / 80
        if (gnorm < 1.0):  # % & & self.bond_dims(self.current_bond) <= 50;
            dmerge = dmerge / gnorm
        dmerge = tensor_add(self.merged_tensor, self.merged_idx,
                            self.learning_rate * dmerge, dpsi_idx)

        return dmerge
Ejemplo n.º 13
0
    def contraction_updat_twosite2(self):
        if self.going_righ == 0:
            if self.current_site == self.n - 2:
                merg, idm = contra(self.tensors[self.n - 1],
                                   self.order[self.n - 1],
                                   self.tensors[self.n - 1],
                                   self.order_left[self.n - 1])
                # self.contraction_z[self.current_site+1]=merg
                merg_psi, idm_psi = contra(self.image_tensors[self.n - 1],
                                           self.order_right[self.n - 1],
                                           self.tensors[self.n - 1],
                                           self.order_left[self.n - 1])

            else:

                merg, idm = contra(
                    self.tensors[self.current_site + 1],
                    self.order_left[self.current_site + 1],
                    self.contraction_z[self.current_site + 2][0],
                    self.contraction_z[self.current_site + 2][1])
                merg, idm = contra(merg, idm,
                                   self.tensors[self.current_site + 1],
                                   self.order[self.current_site + 1])

                merg_psi, idm_psi = contra(
                    self.tensors[self.current_site + 1],
                    self.order_left[self.current_site + 1],
                    self.contraction_psi2[self.current_site + 2][0],
                    self.contraction_psi2[self.current_site + 2][1])
                merg_psi, idm_psi = contra(
                    merg_psi, idm_psi,
                    self.image_tensors[self.current_site + 1],
                    self.order_right[self.current_site + 1])

            self.contraction_psi2[self.current_site +
                                  1] = ([merg_psi, idm_psi])
            self.contraction_z[self.current_site + 1] = ([merg, idm])

        if self.going_righ == 1:
            if self.current_site == 0:
                merg, idm = contra(self.tensors[0], self.order[0],
                                   self.tensors[0], self.order_left[0])
                # self.contraction_z[self.current_site+1]=merg
                merg_psi, idm_psi = contra(self.image_tensors[0],
                                           self.order_right[0],
                                           self.tensors[0], self.order_left[0])

            else:

                merg, idm = contra(
                    self.tensors[self.current_site],
                    self.order_left[self.current_site],
                    self.contraction_z[self.current_site - 1][0],
                    self.contraction_z[self.current_site - 1][1])
                merg, idm = contra(merg, idm, self.tensors[self.current_site],
                                   self.order[self.current_site])

                merg_psi, idm_psi = contra(
                    self.tensors[self.current_site],
                    self.order_left[self.current_site],
                    self.contraction_psi2[self.current_site - 1][0],
                    self.contraction_psi2[self.current_site - 1][1])
                merg_psi, idm_psi = contra(
                    merg_psi, idm_psi, self.image_tensors[self.current_site],
                    self.order_right[self.current_site])

                self.contraction_psi2[self.current_site] = ([
                    merg_psi, idm_psi
                ])
                self.contraction_z[self.current_site] = ([merg, idm])