Exemplo n.º 1
0
 def inter_change(ori_mat):
     matshape = ori_mat.shape
     len_mat = int(np.prod(np.array(matshape[:-1])))
     ori_mat = ori_mat.reshape(len_mat, 2)
     change_mat = copy.deepcopy(ori_mat)
     change_mat[:, 0], change_mat[:, 1] = ori_mat[:, 1], ori_mat[:, 0]
     return change_mat.reshape(matshape)
Exemplo n.º 2
0
 def qnmat_add(self, mat_l, mat_r):
     lshape, rshape = mat_l.shape, mat_r.shape
     lena = int(np.prod(np.array(lshape)) / 2)
     lenb = int(np.prod(np.array(rshape)) / 2)
     matl = mat_l.reshape(lena, 2)
     matr = mat_r.reshape(lenb, 2)
     lr1 = np.add.outer(matl[:, 0], matr[:, 0]).flatten()
     lr2 = np.add.outer(matl[:, 1], matr[:, 1]).flatten()
     lr = np.zeros((len(lr1), 2))
     lr[:, 0] = lr1
     lr[:, 1] = lr2
     shapel = list(mat_l.shape)
     del shapel[-1]
     shaper = list(mat_r.shape)
     del shaper[-1]
     lr = lr.reshape(shapel + shaper + [2])
     return lr
Exemplo n.º 3
0
 def check_lortho(self, rtol=1e-5, atol=1e-8):
     """
     check L-orthogonal
     """
     tensm = asxp(
         self.array.reshape([np.prod(self.shape[:-1]), self.shape[-1]]))
     s = tensm.T.conj() @ tensm
     return xp.allclose(s, xp.eye(s.shape[0]), rtol=rtol, atol=atol)
Exemplo n.º 4
0
 def check_rortho(self, rtol=1e-5, atol=1e-8):
     """
     check R-orthogonal
     """
     tensm = asxp(
         self.array.reshape([self.shape[0],
                             np.prod(self.shape[1:])]))
     s = tensm @ tensm.T.conj()
     return xp.allclose(s, xp.eye(s.shape[0]), rtol=rtol, atol=atol)
Exemplo n.º 5
0
def Csvd(
    cstruct: np.ndarray,
    qnbigl,
    qnbigr,
    nexciton,
    QR=False,
    system=None,
    full_matrices=True,
    ddm=False,
):
    """
    block svd the coefficient matrix (l, sigmal, sigmar, r) or (l,sigma,r)
    according to the quantum number
    ddm is the direct diagonalization the reduced density matrix
    """

    Gamma = cstruct.reshape((np.prod(qnbigl.shape), np.prod(qnbigr.shape)))
    localqnl = qnbigl.ravel()
    localqnr = qnbigr.ravel()

    Uset = []  # corresponds to nonzero svd value
    Uset0 = []  # corresponds to zero svd value
    Vset = []
    Vset0 = []
    Sset = []
    SUset0 = []
    SVset0 = []
    qnlset = []
    qnlset0 = []
    qnrset = []
    qnrset0 = []

    if not ddm:
        # different combination
        if cstruct.ndim == 4:  # density matrix
            combine = [[x, nexciton - x] for x in range(nexciton + 1)]
        else:
            min0 = min(np.min(localqnl), np.min(localqnr))
            max0 = max(np.max(localqnl), np.max(localqnr))
            combine = [[x, nexciton - x] for x in range(min0, max0 + 1)]
    else:
        # ddm is for diagonlize the reduced density matrix for multistate
        combine = [[x, x] for x in range(nexciton + 1)]

    for nl, nr in combine:
        lset = np.where(localqnl == nl)[0]
        rset = np.where(localqnr == nr)[0]
        if len(lset) == 0 or len(rset) == 0:
            continue
        # Gamma_block = Gamma[np.ix_(lset,rset)]
        Gamma_block = Gamma.ravel().take((lset *
                                          Gamma.shape[1]).reshape(-1, 1) +
                                         rset)

        if not ddm:
            if not QR:
                try:
                    U, S, Vt = scipy.linalg.svd(
                        Gamma_block,
                        full_matrices=full_matrices,
                        lapack_driver="gesdd",
                    )
                except:
                    # print "Csvd converge failed"
                    U, S, Vt = scipy.linalg.svd(
                        Gamma_block,
                        full_matrices=full_matrices,
                        lapack_driver="gesvd",
                    )
                dim = S.shape[0]
                Sset.append(S)
            else:
                if full_matrices:
                    mode = "full"
                else:
                    mode = "economic"
                if system == "R":
                    U, Vt = scipy.linalg.rq(Gamma_block, mode=mode)
                elif system == "L":
                    U, Vt = scipy.linalg.qr(Gamma_block, mode=mode)
                else:
                    assert False
                dim = min(Gamma_block.shape)

            Uset, Uset0, qnlset, qnlset0, SUset0 = blockappend(
                Uset,
                Uset0,
                qnlset,
                qnlset0,
                SUset0,
                U,
                nl,
                dim,
                lset,
                Gamma.shape[0],
                full_matrices=full_matrices,
            )
            Vset, Vset0, qnrset, qnrset0, SVset0 = blockappend(
                Vset,
                Vset0,
                qnrset,
                qnrset0,
                SVset0,
                Vt.T,
                nr,
                dim,
                rset,
                Gamma.shape[1],
                full_matrices=full_matrices,
            )
        else:
            S, U = scipy.linalg.eigh(Gamma_block)
            # numerical error for eigenvalue < 0
            for ss in range(len(S)):
                if S[ss] < 0:
                    S[ss] = 0.0
            S = np.sqrt(S)
            dim = S.shape[0]
            Sset.append(S)
            Uset, Uset0, qnlset, qnlset0, SUset0 = blockappend(
                Uset,
                Uset0,
                qnlset,
                qnlset0,
                SUset0,
                U,
                nl,
                dim,
                lset,
                Gamma.shape[0],
                full_matrices=False,
            )

    if not ddm:
        if full_matrices:
            Uset = np.concatenate(Uset + Uset0, axis=1)
            Vset = np.concatenate(Vset + Vset0, axis=1)
            qnlset = qnlset + qnlset0
            qnrset = qnrset + qnrset0
            if not QR:
                # not sorted
                SUset = np.concatenate(Sset + SUset0)
                SVset = np.concatenate(Sset + SVset0)
                return Uset, SUset, qnlset, Vset, SVset, qnrset
            else:
                return Uset, qnlset, Vset, qnrset
        else:
            Uset = np.concatenate(Uset, axis=1)
            Vset = np.concatenate(Vset, axis=1)
            if not QR:
                Sset = np.concatenate(Sset)
                # sort the singular value in descending order
                order = np.argsort(Sset)[::-1]
                Uset_order = Uset[:, order]
                Vset_order = Vset[:, order]
                Sset_order = Sset[order]
                qnlset_order = np.array(qnlset)[order].tolist()
                qnrset_order = np.array(qnrset)[order].tolist()
                return (
                    Uset_order,
                    Sset_order,
                    qnlset_order,
                    Vset_order,
                    Sset_order,
                    qnrset_order,
                )
            else:
                return Uset, qnlset, Vset, qnrset
    else:
        Uset = np.concatenate(Uset, axis=1)
        Sset = np.concatenate(Sset)
        return Uset, Sset, qnlset
Exemplo n.º 6
0
    def x_svd(self, xstruct, xqnbigl, xqnbigr, nexciton, direction, percent=0):
        Gamma = xstruct.reshape(
            np.prod(xqnbigl.shape) // 2,
            np.prod(xqnbigr.shape) // 2)

        localXqnl = xqnbigl.ravel()
        localXqnr = xqnbigr.ravel()
        list_locall = []
        list_localr = []
        for i in range(0, len(localXqnl), 2):
            list_locall.append([localXqnl[i], localXqnl[i + 1]])
        for i in range(0, len(localXqnr), 2):
            list_localr.append([localXqnr[i], localXqnr[i + 1]])
        localXqnl = copy.deepcopy(list_locall)
        localXqnr = copy.deepcopy(list_localr)
        xuset = []
        xuset0 = []
        xvset = []
        xvset0 = []
        xsset = []
        xsuset0 = []
        xsvset0 = []
        xqnlset = []
        xqnlset0 = []
        xqnrset = []
        xqnrset0 = []
        if self.spectratype == "abs":
            combine = [[[y, 0], [nexciton - y, 0]]
                       for y in range(nexciton + 1)]
        elif self.spectratype == "emi":
            combine = [[[0, y], [0, nexciton - y]]
                       for y in range(nexciton + 1)]
        for nl, nr in combine:
            lset = np.where(self.condition(np.array(localXqnl), [nl]))[0]
            rset = np.where(self.condition(np.array(localXqnr), [nr]))[0]
            if len(lset) != 0 and len(rset) != 0:
                Gamma_block = Gamma.ravel().take(
                    (lset * Gamma.shape[1]).reshape(-1, 1) + rset)
                try:
                    U, S, Vt = \
                        scipy.linalg.svd(Gamma_block, full_matrices=True,
                                         lapack_driver='gesdd')
                except:
                    U, S, Vt = \
                        scipy.linalg.svd(Gamma_block, full_matrices=True,
                                         lapack_driver='gesvd')

                dim = S.shape[0]

                xsset.append(S)
                # U part quantum number
                xuset.append(
                    svd_qn.blockrecover(lset, U[:, :dim], Gamma.shape[0]))
                xqnlset += [nl] * dim
                xuset0.append(
                    svd_qn.blockrecover(lset, U[:, dim:], Gamma.shape[0]))
                xqnlset0 += [nl] * (U.shape[0] - dim)
                xsuset0.append(np.zeros(U.shape[0] - dim))
                # V part quantum number
                VT = Vt.T
                xvset.append(
                    svd_qn.blockrecover(rset, VT[:, :dim], Gamma.shape[1]))
                xqnrset += [nr] * dim
                xvset0.append(
                    svd_qn.blockrecover(rset, VT[:, dim:], Gamma.shape[1]))
                xqnrset0 += [nr] * (VT.shape[0] - dim)
                xsvset0.append(np.zeros(VT.shape[0] - dim))
        xuset = np.concatenate(xuset + xuset0, axis=1)
        xvset = np.concatenate(xvset + xvset0, axis=1)
        xsuset = np.concatenate(xsset + xsuset0)
        xsvset = np.concatenate(xsset + xsvset0)
        xqnlset = xqnlset + xqnlset0
        xqnrset = xqnrset + xqnrset0
        bigl_shape = list(xqnbigl.shape)
        del bigl_shape[-1]
        bigr_shape = list(xqnbigr.shape)
        del bigr_shape[-1]
        if direction == "left":
            x, xdim, xqn, compx = update_cv(xvset,
                                            xsvset,
                                            xqnrset,
                                            xuset,
                                            nexciton,
                                            self.m_max,
                                            self.spectratype,
                                            percent=percent)
            if (self.method == "1site") and (len(bigr_shape + [xdim]) == 3):
                return np.moveaxis(
                    x.reshape(bigr_shape + [1] + [xdim]), -1, 0),\
                    xdim, xqn, compx.reshape(bigl_shape + [xdim])
            else:
                return np.moveaxis(x.reshape(bigr_shape + [xdim]), -1, 0),\
                    xdim, xqn, compx.reshape(bigl_shape + [xdim])
        elif direction == "right":
            x, xdim, xqn, compx = update_cv(xuset,
                                            xsuset,
                                            xqnlset,
                                            xvset,
                                            nexciton,
                                            self.m_max,
                                            self.spectratype,
                                            percent=percent)
            if (self.method == "1site") and (len(bigl_shape + [xdim]) == 3):
                return x.reshape([1] + bigl_shape + [xdim]), xdim, xqn, \
                    np.moveaxis(compx.reshape(bigr_shape + [xdim]), -1, 0)
            else:
                return x.reshape(bigl_shape + [xdim]), xdim, xqn, \
                    np.moveaxis(compx.reshape(bigr_shape + [xdim]), -1, 0)
Exemplo n.º 7
0
 def l_combine_shape(self):
     return np.prod(self.original_shape[:-1]), self.original_shape[-1]
Exemplo n.º 8
0
 def r_combine_shape(self):
     return self.original_shape[0], np.prod(self.original_shape[1:])
Exemplo n.º 9
0
 def pdim_prod(self):
     return np.prod(self.pdim)