Esempio n. 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
Esempio n. 2
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]])
Esempio n. 3
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)
Esempio n. 4
0
 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)
Esempio n. 5
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
Esempio n. 6
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, ))
Esempio n. 7
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