Ejemplo n.º 1
0
def update_cv(vset,
              sset,
              qnset,
              compset,
              nexciton,
              Mmax,
              spectratype,
              percent=0):
    sidx = select_Xbasis(qnset,
                         sset,
                         range(nexciton + 1),
                         Mmax,
                         spectratype,
                         percent=percent)
    xdim = len(sidx)
    x = np.zeros((vset.shape[0], xdim), dtype=vset.dtype)
    xqn = []
    if compset is not None:
        compx = np.zeros((compset.shape[0], xdim), dtype=compset.dtype)
    else:
        compx = None

    for idim in range(xdim):
        x[:, idim] = vset[:, sidx[idim]].copy()
        if (compset is not None) and (sidx[idim] < compset.shape[1]):
            compx[:, idim] = compset[:, sidx[idim]].copy() * sset[sidx[idim]]
        xqn.append(qnset[sidx[idim]])
    if compx is not None:
        compx = Matrix(compx)
    return Matrix(x), xdim, xqn, compx
Ejemplo n.º 2
0
def updatemps(vset, sset, qnset, compset, nexciton, Mmax, percent=0):
    """
    select basis to construct new mps, and complementary mps
    vset, compset is the column vector
    """
    sidx = select_basis(qnset,
                        sset,
                        range(nexciton + 1),
                        Mmax,
                        percent=percent)
    mpsdim = len(sidx)
    # need to set value column by column. better in CPU
    ms = np.zeros((vset.shape[0], mpsdim), dtype=vset.dtype)

    if compset is not None:
        compmps = np.zeros((compset.shape[0], mpsdim), dtype=compset.dtype)
    else:
        compmps = None

    mpsqn = []
    stot = 0.0
    for idim in range(mpsdim):
        ms[:, idim] = vset[:, sidx[idim]].copy()
        if (compset is not None) and sidx[idim] < compset.shape[1]:
            compmps[:, idim] = compset[:, sidx[idim]].copy() * sset[sidx[idim]]
        mpsqn.append(qnset[sidx[idim]])
        stot += sset[sidx[idim]]**2

    # print("discard:", 1.0 - stot)
    if compmps is not None:
        compmps = asxp(compmps)

    return asxp(ms), mpsdim, mpsqn, compmps
Ejemplo n.º 3
0
def cvec2cmat(cshape, c, qnmat, nexciton, nroots=1):
    # recover good quantum number vector c to matrix format
    if nroots == 1:
        cstruct = np.zeros(cshape, dtype=c.dtype)
        np.place(cstruct, qnmat == nexciton, c)
    else:
        cstruct = []
        for ic in c:
            icstruct = np.zeros(cshape, dtype=ic.dtype)
            np.place(icstruct, qnmat == nexciton, ic)
            cstruct.append(icstruct)

    return cstruct
Ejemplo n.º 4
0
def cvec2cmat(cshape, c, qnmat, nexciton, nroots=1):
    # recover good quantum number vector c to matrix format
    if nroots == 1:
        cstruct = np.zeros(cshape, dtype=c.dtype)
        np.place(cstruct, qnmat == nexciton, c)
    else:
        cstruct = []
        if type(c) is not list:
            assert c.ndim == 2
            c = [c[:, iroot] for iroot in range(c.shape[1])]
        for ic in c:
            icstruct = np.zeros(cshape, dtype=ic.dtype)
            np.place(icstruct, qnmat == nexciton, ic)
            cstruct.append(icstruct)

    return cstruct
Ejemplo n.º 5
0
def blockrecover(indices, U, dim):
    """
    recover the block element to its original position
    """
    resortU = np.zeros([dim, U.shape[1]], dtype=U.dtype)
    resortU[indices, :] = U

    return resortU
Ejemplo n.º 6
0
 def _array2mt(self, array, idx):
     if isinstance(array, Matrix):
         mt = array.astype(self.dtype)
     else:
         mt = Matrix(array, dtype=self.dtype)
     if self.use_dummy_qn:
         mt.sigmaqn = np.zeros(mt.pdim_prod, dtype=np.int)
     else:
         mt.sigmaqn = self._get_sigmaqn(idx)
     return mt
Ejemplo n.º 7
0
 def dag2mat(self, xshape, x, dag_qnmat, direction):
     if self.spectratype == "abs":
         up_exciton, down_exciton = 1, 0
     else:
         up_exciton, down_exciton = 0, 1
     xdag = np.zeros(xshape, dtype=x.dtype)
     mask = self.condition(dag_qnmat, [down_exciton, up_exciton])
     np.place(xdag, mask, x)
     shape = list(xdag.shape)
     if xdag.ndim == 3:
         if direction == 'left':
             xdag = xdag.reshape(shape + [1])
         else:
             xdag = xdag.reshape([1] + shape)
     return xdag
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def blockappend(
    vset,
    vset0,
    qnset,
    qnset0,
    svset0,
    v,
    n,
    dim,
    indice,
    shape,
    full_matrices=True,
):
    vset.append(blockrecover(indice, v[:, :dim], shape))
    qnset += [n] * dim
    if full_matrices:
        vset0.append(blockrecover(indice, v[:, dim:], shape))
        qnset0 += [n] * (v.shape[0] - dim)
        svset0.append(np.zeros(v.shape[0] - dim))

    return vset, vset0, qnset, qnset0, svset0
Ejemplo n.º 10
0
def select_basis(vset, sset, qnset, compset, Mmax, percent=0):
    """
    select basis to construct new mps, and complementary mps
    vset, compset is the column vector
    """
    # allowed qn subsection
    qnlist = set(qnset)
    # convert to dict
    basdic = dict()
    for i in range(len(qnset)):
        # clean quantum number outside qnlist
        if qnset[i] in qnlist:
            basdic[i] = [qnset[i], sset[i]]

    # each good quantum number block equally get percent/nblocks
    def block_select(basdic, qn, n):
        block_basdic = {i: basdic[i] for i in basdic if basdic[i][0] == qn}
        sort_block_basdic = sorted(block_basdic.items(),
                                   key=lambda x: x[1][1],
                                   reverse=True)
        nget = min(n, len(sort_block_basdic))
        # print(qn, "block # of retained basis", nget)
        sidx = [i[0] for i in sort_block_basdic[0:nget]]
        for idx in sidx:
            del basdic[idx]

        return sidx

    nbasis = min(len(basdic), Mmax)
    # print("# of selected basis", nbasis)
    sidx = []

    # equally select from each quantum number block
    if percent != 0:
        nbas_block = int(nbasis * percent / len(qnlist))
        for iqn in qnlist:
            sidx += block_select(basdic, iqn, nbas_block)

    # others
    nbasis = nbasis - len(sidx)

    sortbasdic = sorted(basdic.items(), key=lambda x: x[1][1], reverse=True)
    sidx += [i[0] for i in sortbasdic[0:nbasis]]

    assert len(sidx) == len(set(sidx))  # there must be no duplicated

    mpsdim = len(sidx)
    # need to set value column by column. better in CPU
    ms = np.zeros((vset.shape[0], mpsdim), dtype=vset.dtype)

    if compset is not None:
        compmps = np.zeros((compset.shape[0], mpsdim), dtype=compset.dtype)
    else:
        compmps = None

    mpsqn = []
    stot = 0.0
    for idim in range(mpsdim):
        ms[:, idim] = vset[:, sidx[idim]].copy()
        if (compset is not None) and sidx[idim] < compset.shape[1]:
            compmps[:, idim] = compset[:, sidx[idim]].copy() * sset[sidx[idim]]
        mpsqn.append(qnset[sidx[idim]])
        stot += sset[sidx[idim]]**2

    # print("discard:", 1.0 - stot)
    if compmps is not None:
        compmps = asxp(compmps)

    return asxp(ms), mpsdim, mpsqn, compmps
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
def zeros(shape, dtype=None):
    if dtype is None:
        dtype = backend.real_dtype
    return Matrix(np.zeros(shape), dtype=dtype)
Ejemplo n.º 13
0
def check_property(mp):
    electron_occupation = np.zeros((mol_list.mol_num))
    electron_occupation[mol_list.mol_num // 2] = 1
    assert mp.norm == pytest.approx(1)
    assert np.allclose(mp.e_occupations, electron_occupation)
    assert np.allclose(mp.ph_occupations, np.zeros((mol_list.ph_modes_num)))