Ejemplo n.º 1
0
    def update_single_w_channel_tensor(self, y, n, cl, ci, cj, cc):
        path = self.get_path_1(cl, ci, cj, cc)
        for l in range(self.num_layers):
            if cl == l:
                for i, j, c in product(range(self.layer_size[l]), range(self.layer_size[l]), range(self.channel)):
                    if (not self.flag_contract[l][i][j][c]) and (i != ci or j != cj or c != cc):
                        self.contracted[l+1][i][j][c] = contract_func0(self.ttn_tensor_list[l][i][j][c],
                                                                       self.contracted[l][2*i][2*j][c],
                                                                       self.contracted[l][2*i][2*j+1][c],
                                                                       self.contracted[l][2*i+1][2*j][c],
                                                                       self.contracted[l][2*i+1][2*j+1][c], n)
                        self.flag_contract[l][i][j][c] = True
                        if l == self.layer_comb_channel-1:
                            self.flag_contract[l+1][i][j] = False
                        else:
                            self.flag_contract[l+1][i//2][j//2][c] = False
                self.contracted[cl+1][ci][cj][cc] = contract_func1(self.contracted[cl][2*ci][2*cj][cc],
                                                                   self.contracted[cl][2*ci][2*cj+1][cc],
                                                                   self.contracted[cl][2*ci+1][2*cj][cc],
                                                                   self.contracted[cl][2*ci+1][2*cj+1][cc],n)
                self.flag_contract[cl][ci][cj][cc] = False
                if cl == self.layer_comb_channel-1:
                    self.flag_contract[cl+1][ci][cj] = False
                else:
                    self.flag_contract[cl+1][ci//2][cj//2][cc] = False
            elif l < self.layer_comb_channel:
                for i, j, c in product(range(self.layer_size[l]), range(self.layer_size[l]), range(self.channel)):
                    if not self.flag_contract[l][i][j][c]:
                        if([l,i,j,c] in path) and (l-1==cl):
                            if ci%2==0 and cj%2==0:
                                contracted_list = [self.contracted[l][ci][cj+1][c],self.contracted[l][ci+1][cj][c],self.contracted[l][ci+1][cj+1][c]]
                                edge_list = ['D01', 'D10', 'D11']
                            elif ci%2==0 and cj%2==1:
                                contracted_list = [self.contracted[l][ci][cj-1][c],self.contracted[l][ci+1][cj-1][c],self.contracted[l][ci+1][cj][c]]
                                edge_list = ['D00', 'D10', 'D11']
                            elif ci%2==1 and cj%2==0:
                                contracted_list = [self.contracted[l][ci-1][cj][c],self.contracted[l][ci-1][cj+1][c],self.contracted[l][ci][cj+1][c]]
                                edge_list = ['D00', 'D01', 'D11']
                            else:
                                contracted_list = [self.contracted[l][ci-1][cj-1][c],self.contracted[l][ci-1][cj][c],self.contracted[l][ci][cj-1][c]]
                                edge_list = ['D00', 'D01', 'D10']
                            self.contracted[l+1][i][j][c] = contract_func2(self.ttn_tensor_list[l][i][j][c], contracted_list, edge_list, n)
                            self.flag_contract[l][i][j][c] = False
                            if l == self.layer_comb_channel-1:
                                self.flag_contract[l+1][i][j] = False
                            else:
                                self.flag_contract[l+1][i//2][j//2][c] = False
                        else:
                            self.contracted[l+1][i][j][c] = contract_func0(self.ttn_tensor_list[l][i][j][c],
                                                                           self.contracted[l][2*i][2*j][c],
                                                                           self.contracted[l][2*i][2*j+1][c],
                                                                           self.contracted[l][2*i+1][2*j][c],
                                                                           self.contracted[l][2*i+1][2*j+1][c], n)
                            self.flag_contract[l][i][j][c] = (not ([l,i,j,c] in path))
                            if l == self.layer_comb_channel-1:
                                self.flag_contract[l+1][i][j] = False
                            else:
                                self.flag_contract[l+1][i//2][j//2][c] = False
            elif l == self.layer_comb_channel:
                for i, j in product(range(self.layer_size[l]), range(self.layer_size[l])):
                    if not self.flag_contract[l][i][j]:
                        if([l,i,j] in path) and (l-1==cl):
                            contracted_list = copy.deepcopy(self.contracted[l][i][j])
                            edge_list = ['C'+str(i) for i in range(self.channel)]
                            contracted_list.pop(cc)
                            edge_list.pop(cc)
                            self.contracted[l+1][i][j] = contract_func2(self.ttn_tensor_list[l][i][j], contracted_list, edge_list, n)
                            self.flag_contract[l][i][j] = False
                            if l < self.num_layers-1:
                                self.flag_contract[l+1][i//2][j//2] = False
                        else:
                            self.contracted[l+1][i][j] = contract_func3(self.ttn_tensor_list[l][i][j],
                                                                        self.contracted[l][i][j], n)
                            self.flag_contract[l][i][j] = (not ([l,i,j] in path))
                            if l < self.num_layers-1:
                                self.flag_contract[l+1][i//2][j//2] = False
            elif l > self.layer_comb_channel:
                for i, j in product(range(self.layer_size[l]), range(self.layer_size[l])):
                    if not self.flag_contract[l][i][j]:
                        self.contracted[l+1][i][j] = contract_func0(self.ttn_tensor_list[l][i][j],
                                                                    self.contracted[l][2*i][2*j],
                                                                    self.contracted[l][2*i][2*j+1],
                                                                    self.contracted[l][2*i+1][2*j],
                                                                    self.contracted[l][2*i+1][2*j+1], n)
                        self.flag_contract[l][i][j] = (not ([l,i,j] in path))
                        if l < self.num_layers-1:
                            self.flag_contract[l+1][i//2][j//2] = False

        tempD = tn.zeros_tensor([n, self.bond_inner], labels=['S', 'B'])
        for s, b in product(range(n), range(self.bond_inner)):
            sum1 = 0
            for f in range(self.bond_label):
                sum1 = sum1 + self.contracted[self.num_layers][0][0].data[s,f,b] * y.data[s,f]
            tempD.data[s, b] = sum1

        tensor_environment = tn.contract(self.contracted[cl+1][ci][cj][cc], tempD, ["S"], ["S"])

        bond_in = self.bond_data if cl == 0 else self.bond_inner
        matrix = np.reshape(tensor_environment.data,
                (bond_in*bond_in*bond_in*bond_in, self.bond_inner))
        u, sigma, vt = np.linalg.svd(matrix, 0)
        self.ttn_tensor_list[cl][ci][cj][cc].data = np.reshape(
                np.dot(u, vt), (bond_in,bond_in,bond_in,bond_in,self.bond_inner))
    def update_singletensor(self, c_i, c_j, c_k):

        path_len = 5 - c_i
        path = [[c_i, c_j, c_k]]
        tem_c_j = c_j
        tem_c_k = c_k
        for i in range(1, path_len):
            tem_c_j = tem_c_j // 2
            tem_c_k = tem_c_k // 2
            path.append([c_i + i, tem_c_j, tem_c_k])

        for i in range(1, 5):
            if i == c_i:
                for j, k in product(range(self.layer_units[i]),
                                    range(self.layer_units[i])):
                    if (self.flag_contract[i, j, k] == 0) and ((j != c_j) or
                                                               (k != c_k)):
                        self.contracted[i][j][k] = self.contract_unit(
                            self.tn_layers[i][j][k],
                            self.contracted[i - 1][2 * j][2 * k],
                            self.contracted[(i - 1)][2 * j][2 * k + 1],
                            self.contracted[i - 1][2 * j + 1][2 * k],
                            self.contracted[i - 1][2 * j + 1][2 * k + 1],
                            self.n_train)
                        self.flag_contract[i, j, k] = 1
                        if i < 4:
                            self.flag_contract[i + 1, j // 2, k // 2] = 0
                self.contracted[c_i][c_j][c_k] = self.contract_local(
                    self.contracted[c_i - 1][2 * c_j][2 * c_k],
                    self.contracted[(c_i - 1)][2 * c_j][2 * c_k + 1],
                    self.contracted[c_i - 1][2 * c_j + 1][2 * c_k],
                    self.contracted[c_i - 1][2 * c_j + 1][2 * c_k + 1],
                    self.n_train)
                self.flag_contract[c_i, c_j, c_k] = 0
                if i < 4:
                    self.flag_contract[c_i + 1, c_j // 2, c_k // 2] = 0
            else:
                for j, k in product(range(self.layer_units[i]),
                                    range(self.layer_units[i])):
                    if self.flag_contract[i, j, k] == 0:
                        if ([i, j, k] in path) and ((i - 1) == c_i):
                            if (c_j % 2 == 0) and (c_k % 2 == 0):
                                [lab1, lab2, lab3] = ["2", "3", "4"]
                                tensor1 = self.contracted[c_i][c_j][c_k + 1]
                                tensor2 = self.contracted[c_i][c_j + 1][c_k]
                                tensor3 = self.contracted[c_i][c_j + 1][c_k +
                                                                        1]

                            if (c_j % 2 == 0) and (c_k % 2 == 1):
                                [lab1, lab2, lab3] = ["1", "3", "4"]
                                tensor1 = self.contracted[c_i][c_j][c_k - 1]
                                tensor2 = self.contracted[c_i][c_j + 1][c_k -
                                                                        1]
                                tensor3 = self.contracted[c_i][c_j + 1][c_k]

                            if (c_j % 2 == 1) and (c_k % 2 == 0):
                                [lab1, lab2, lab3] = ["1", "2", "4"]
                                tensor1 = self.contracted[c_i][c_j - 1][c_k]
                                tensor2 = self.contracted[c_i][c_j - 1][c_k +
                                                                        1]
                                tensor3 = self.contracted[c_i][c_j][c_k + 1]

                            if (c_j % 2 == 1) and (c_k % 2 == 1):
                                [lab1, lab2, lab3] = ["1", "2", "3"]
                                tensor1 = self.contracted[c_i][c_j - 1][c_k -
                                                                        1]
                                tensor2 = self.contracted[c_i][c_j - 1][c_k]
                                tensor3 = self.contracted[c_i][c_j][c_k - 1]

                            self.contracted[i][j][k] = self.contract_special(
                                self.tn_layers[i][j][k], tensor1, lab1,
                                tensor2, lab2, tensor3, lab3, self.n_train)
                            self.flag_contract[i, j, k] = 0
                            if i < 4:
                                self.flag_contract[i + 1, j // 2, k // 2] = 0

                        else:
                            # print(i,j,k)
                            self.contracted[i][j][k] = self.contract_unit(
                                self.tn_layers[i][j][k],
                                self.contracted[i - 1][2 * j][2 * k],
                                self.contracted[i - 1][2 * j][2 * k + 1],
                                self.contracted[i - 1][2 * j + 1][2 * k],
                                self.contracted[i - 1][2 * j + 1][2 * k + 1],
                                self.n_train)
                            if ([i, j, k] in path):
                                self.flag_contract[i, j, k] = 0
                            else:
                                self.flag_contract[i, j, k] = 1
                            if i < 4:
                                self.flag_contract[i + 1, j // 2, k // 2] = 0
        if c_i != 4:

            bond = self.contracted[c_i][c_j][c_k].shape[0]

            tempD = tn.zeros_tensor([self.bond_inner, self.n_train],
                                    labels=['m', 'g'])
            for m, g in product(range(self.bond_inner), range(self.n_train)):
                sum1 = 0
                for f in range(self.bond_label):
                    sum1 = sum1 + self.contracted[4][0][0].data[
                        f, m, g] * self.labels.data[g, f]
                tempD.data[m, g] = sum1

            tensor_environment = tn.contract(self.contracted[c_i][c_j][c_k],
                                             tempD, ["down"], ["g"])

        else:
            tensor_environment = tn.contract(self.contracted[4][0][0],
                                             self.labels, "down", "up")

        if c_i == 1:
            matrix = np.reshape(
                tensor_environment.data,
                (self.bond_data * self.bond_data * self.bond_data *
                 self.bond_data, self.bond_inner))
            u, sigma, vt = la.svd(matrix, 0)
            self.tn_layers[c_i][c_j][c_k].data = np.reshape(
                np.dot(u, vt), (self.bond_data, self.bond_data, self.bond_data,
                                self.bond_data, self.bond_inner))
        else:
            if c_i == 4:
                matrix = np.reshape(
                    tensor_environment.data,
                    (self.bond_inner * self.bond_inner * self.bond_inner *
                     self.bond_inner, self.bond_label))
                u, sigma, vt = la.svd(matrix, 0)
                self.tn_layers[c_i][c_j][c_k].data = np.reshape(
                    np.dot(u, vt),
                    (self.bond_inner, self.bond_inner, self.bond_inner,
                     self.bond_inner, self.bond_label))
            else:
                matrix = np.reshape(
                    tensor_environment.data,
                    (self.bond_inner * self.bond_inner * self.bond_inner *
                     self.bond_inner, self.bond_inner))
                u, sigma, vt = la.svd(matrix, 0)
                self.tn_layers[c_i][c_j][c_k].data = np.reshape(
                    np.dot(u, vt),
                    (self.bond_inner, self.bond_inner, self.bond_inner,
                     self.bond_inner, self.bond_inner))

        # compute the training accuracy-------------------------------------------
        j = c_j
        k = c_k
        for i in range(c_i, 5):
            self.contracted[i][j][k] = self.contract_unit(
                self.tn_layers[i][j][k], self.contracted[i - 1][2 * j][2 * k],
                self.contracted[i - 1][2 * j][2 * k + 1],
                self.contracted[i - 1][2 * j + 1][2 * k],
                self.contracted[i - 1][2 * j + 1][2 * k + 1], self.n_train)
            j = j // 2
            k = k // 2

        temp = tn.contract(self.contracted[4][0][0], self.labels, "up", "down")
        temp.trace("up", "down")
        acc = temp.data / self.n_train
        return acc