Ejemplo n.º 1
0
    def trans(ci1, aindex, bindex, nea, neb):
        if aindex is None or bindex is None:
            return None

        t1 = numpy.zeros((cistring.num_strings(norb,nea),
                          cistring.num_strings(norb,neb)))
        for i in range(norb):
            signa = aindex[:,i,1]
            signb = bindex[:,i,1]
            maska = numpy.where(signa!=0)[0]
            maskb = numpy.where(signb!=0)[0]
            ida = aindex[maska,i,0]
            idb = bindex[maskb,i,0]
            citmp = pyscf.lib.take_2d(fcivec, maska, maskb)
            citmp = numpy.einsum('i,j,ij->ij', signa[maska], signb[maskb], citmp)
            #: t1[ida.reshape(-1,1),idb] += citmp
            pyscf.lib.takebak_2d_(t1, citmp, ida, idb)
        for i in range(norb):
            signa = aindex[:,i,1]
            signb = bindex[:,i,1]
            maska = numpy.where(signa!=0)[0]
            maskb = numpy.where(signb!=0)[0]
            ida = aindex[maska,i,0]
            idb = bindex[maskb,i,0]
            citmp = pyscf.lib.take_2d(t1, ida, idb)
            citmp = numpy.einsum('i,j,ij->ij', signa[maska], signb[maskb], citmp)
            #: ci1[maska.reshape(-1,1), maskb] += citmp
            pyscf.lib.takebak_2d_(ci1, citmp, maska, maskb)
Ejemplo n.º 2
0
def get_init_guess(norb, nelec, nroots, hdiag):
    '''Initial guess is the single Slater determinant
    '''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)

    # The "nroots" lowest determinats based on energy expectation value.
    ci0 = []
    try:
        addrs = numpy.argpartition(hdiag, nroots-1)[:nroots]
    except AttributeError:
        addrs = numpy.argsort(hdiag)[:nroots]
    for addr in addrs:
        x = numpy.zeros((na*nb))
        x[addr] = 1
        ci0.append(x.ravel())

    # Add noise
    ci0[0][0 ] += 1e-5
    ci0[0][-1] -= 1e-5
    return ci0
Ejemplo n.º 3
0
def get_init_guess(norb, nelec, nroots, hdiag):
    '''Initial guess is the single Slater determinant
    '''
    neleca, nelecb = _unpack_nelec(nelec)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    return _get_init_guess(na, nb, nroots, hdiag)
Ejemplo n.º 4
0
def exdiagH(h1e, g2e, norb, nelec, writefile=True):
    '''
        exactly diagonalize the hamiltonian.
    '''
    h2e = direct_spin1.absorb_h1e(h1e, g2e, norb, nelec, .5)
    if isinstance(nelec, (int, np.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    naa = cistring.num_strings(norb, neleca)
    nbb = cistring.num_strings(norb, nelecb)
    ndim = naa*nbb
    eyebas = np.eye(ndim, ndim)
    def hop(c):
        hc = direct_spin1.contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)
    Hmat = []
    for i in range(ndim):
        hc = hop(eyebas[i].copy())
        Hmat.append(hc)

    Hmat = np.asarray(Hmat)
#    Hmat = Hmat.T.copy()
    ew, ev = nl.eigh(Hmat.T)
    if writefile:
        np.savetxt("cards/eignE.dat", ew, fmt="%10.10f")
        np.savetxt("cards/eignV.dat", ev, fmt="%10.10f")
    return ew, ev
Ejemplo n.º 5
0
def contract_2e_hubbard(u, fcivec, norb, nelec, opt=None):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    u_aa, u_ab, u_bb = u

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb))
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    fcivec = fcivec.reshape(na,nb)
    fcinew = numpy.zeros_like(fcivec)

    if u_aa != 0:  # u * n_alpha^+ n_alpha
        for i in range(norb):
            maska = (strsa & (1<<i)) > 0
            fcinew[maska] += u_aa * fcivec[maska]
    if u_ab != 0:  # u * (n_alpha^+ n_beta + n_beta^+ n_alpha)
        for i in range(norb):
            maska = (strsa & (1<<i)) > 0
            maskb = (strsb & (1<<i)) > 0
            fcinew[maska[:,None]&maskb] += 2*u_ab * fcivec[maska[:,None]&maskb]
    if u_bb != 0:  # u * n_beta^+ n_beta
        for i in range(norb):
            maskb = (strsb & (1<<i)) > 0
            fcinew[:,maskb] += u_bb * fcivec[:,maskb]
    return fcinew
Ejemplo n.º 6
0
def from_fcivec(ci0, norb, nelec, frozen=0):
    '''Extract CISD coefficients from FCI coefficients'''
    if frozen is not 0:
        raise NotImplementedError
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    norba = norbb = norb
    nocc = nocca, noccb = neleca, nelecb
    nvira = norba - nocca
    nvirb = norbb - noccb
    t1addra, t1signa = cisd.tn_addrs_signs(norba, nocca, 1)
    t1addrb, t1signb = cisd.tn_addrs_signs(norbb, noccb, 1)

    na = cistring.num_strings(norba, nocca)
    nb = cistring.num_strings(norbb, noccb)
    ci0 = ci0.reshape(na,nb)
    c0 = ci0[0,0]
    c1a = (ci0[t1addra,0] * t1signa).reshape(nocca,nvira)
    c1b = (ci0[0,t1addrb] * t1signb).reshape(noccb,nvirb)

    c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra[:,None],t1addrb])
    c2ab = c2ab.reshape(nocca,nvira,noccb,nvirb).transpose(0,2,1,3)
    t2addra, t2signa = cisd.tn_addrs_signs(norba, nocca, 2)
    t2addrb, t2signb = cisd.tn_addrs_signs(norbb, noccb, 2)
    c2aa = (ci0[t2addra,0] * t2signa).reshape(nocca*(nocca-1)//2, nvira*(nvira-1)//2)
    c2aa = _unpack_4fold(c2aa, nocca, nvira)
    c2bb = (ci0[0,t2addrb] * t2signb).reshape(noccb*(noccb-1)//2, nvirb*(nvirb-1)//2)
    c2bb = _unpack_4fold(c2bb, noccb, nvirb)

    return amplitudes_to_cisdvec(c0, (c1a,c1b), (c2aa,c2ab,c2bb))
Ejemplo n.º 7
0
def make_rdm12e(fcivec, nsite, nelec):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)

    ci0 = fcivec.reshape(na,nb,-1)
    rdm1 = numpy.zeros((nsite,nsite))
    rdm2 = numpy.zeros((nsite,nsite,nsite,nsite))
    for str0 in range(na):
        t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:])
        for a, i, str1, sign in link_indexa[str0]:
            t1[i,a,:] += sign * ci0[str1,:]

        for k, tab in enumerate(link_indexb):
            for a, i, str1, sign in tab:
                t1[i,a,k] += sign * ci0[str0,str1]

        rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1)
        # i^+ j|0> => <0|j^+ i, so swap i and j
        #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1)
        tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T)
        rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3)
    rdm1, rdm2 = pyscf.fci.rdm.reorder_rdm(rdm1, rdm2, True)
    return rdm1, rdm2
Ejemplo n.º 8
0
def _make_rdm2_abba(fcivec, norb, nelec):
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelecb = nelec // 2
    else:
        neleca, nelecb = nelec
    if nelecb == norb or neleca == 0: # no intermediate determinants
        return numpy.zeros((norb,norb,norb,norb))
    acre_index = cistring.gen_cre_str_index(range(norb), neleca-1)
    bdes_index = cistring.gen_des_str_index(range(norb), nelecb+1)
    instra = cistring.num_strings(norb, neleca-1)
    nb = cistring.num_strings(norb, nelecb)
    dm1 = numpy.empty((norb,norb))
    dm2 = numpy.empty((norb,norb,norb,norb))
    fn = _ctypes.dlsym(librdm._handle, 'FCIdm2_abba_kern')
    librdm.FCIspindm12_drv(ctypes.c_void_p(fn),
                           dm1.ctypes.data_as(ctypes.c_void_p),
                           dm2.ctypes.data_as(ctypes.c_void_p),
                           fcivec.ctypes.data_as(ctypes.c_void_p),
                           fcivec.ctypes.data_as(ctypes.c_void_p),
                           ctypes.c_int(norb),
                           ctypes.c_int(instra), ctypes.c_int(nb),
                           ctypes.c_int(neleca), ctypes.c_int(nelecb),
                           acre_index.ctypes.data_as(ctypes.c_void_p),
                           bdes_index.ctypes.data_as(ctypes.c_void_p))
    return dm2
Ejemplo n.º 9
0
def get_init_guess(norb, nelec, nroots, hdiag):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)

    init_strs = []
    iroot = 0
    for addr in numpy.argsort(hdiag):
        addra = addr // nb
        addrb = addr % nb
        if (addrb,addra) not in init_strs:  # avoid initial guess linear dependency
            init_strs.append((addra,addrb))
            iroot += 1
            if iroot >= nroots:
                break
    ci0 = []
    for addra,addrb in init_strs:
        x = numpy.zeros((na,nb))
        if addra == addrb == 0:
            x[addra,addrb] = 1
        else:
            x[addra,addrb] = x[addrb,addra] = numpy.sqrt(.5)
        ci0.append(x.ravel())
    return ci0
Ejemplo n.º 10
0
def contract_2e(eri, fcivec, norb, nelec, opt=None):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    link_indexa = cistring.gen_linkstr_index(range(norb), neleca)
    link_indexb = cistring.gen_linkstr_index(range(norb), nelecb)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    fcivec = fcivec.reshape(na,nb)
    t1 = numpy.zeros((norb,norb,na,nb))
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            t1[a,i,str1] += sign * fcivec[str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            t1[a,i,:,str1] += sign * fcivec[:,str0]
    t1 = numpy.dot(eri.reshape(norb*norb,-1), t1.reshape(norb*norb,-1))
    t1 = t1.reshape(norb,norb,na,nb)
    fcinew = numpy.zeros_like(fcivec)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            fcinew[str1] += sign * t1[a,i,str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            fcinew[:,str1] += sign * t1[a,i,:,str0]
    return fcinew
Ejemplo n.º 11
0
def contract_2e(eri, fcivec, norb, nelec, opt=None):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    link_indexa = cistring.gen_linkstr_index(range(norb), neleca)
    link_indexb = cistring.gen_linkstr_index(range(norb), nelecb)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    ci0 = fcivec.reshape(na,nb)
    t1 = numpy.zeros((norb,norb,na,nb))
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            t1[a,i,str1] += sign * ci0[str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            t1[a,i,:,str1] += sign * ci0[:,str0]

    t1 = lib.einsum('bjai,aiAB->bjAB', eri.reshape([norb]*4), t1)

    fcinew = numpy.zeros_like(ci0)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            fcinew[str1] += sign * t1[a,i,str0]
    for str0, tab in enumerate(link_indexb):
        for a, i, str1, sign in tab:
            fcinew[:,str1] += sign * t1[a,i,:,str0]
    return fcinew.reshape(fcivec.shape)
Ejemplo n.º 12
0
    def trans(ci1, aindex, bindex, nea, neb):
        if aindex is None or bindex is None:
            return None

        t1 = numpy.zeros((cistring.num_strings(norb,nea),
                          cistring.num_strings(norb,neb)))
        for i in range(norb):
            signa = aindex[:,i,1]
            signb = bindex[:,i,1]
            maska = numpy.where(signa!=0)[0]
            maskb = numpy.where(signb!=0)[0]
            addra = aindex[maska,i,0]
            addrb = bindex[maskb,i,0]
            citmp = lib.take_2d(fcivec, maska, maskb)
            citmp *= signa[maska].reshape(-1,1)
            citmp *= signb[maskb]
            #: t1[addra.reshape(-1,1),addrb] += citmp
            lib.takebak_2d(t1, citmp, addra, addrb)
        for i in range(norb):
            signa = aindex[:,i,1]
            signb = bindex[:,i,1]
            maska = numpy.where(signa!=0)[0]
            maskb = numpy.where(signb!=0)[0]
            addra = aindex[maska,i,0]
            addrb = bindex[maskb,i,0]
            citmp = lib.take_2d(t1, addra, addrb)
            citmp *= signa[maska].reshape(-1,1)
            citmp *= signb[maskb]
            #: ci1[maska.reshape(-1,1), maskb] += citmp
            lib.takebak_2d(ci1, citmp, maska, maskb)
Ejemplo n.º 13
0
def make_rdm12e(fcivec, nsite, nelec):
    '''1-electron and 2-electron density matrices
    dm_pq = <|p^+ q|>
    dm_{pqrs} = <|p^+ r^+ q s|>  (note 2pdm is ordered in chemist notation)
    '''
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa = cistring.gen_linkstr_index(range(nsite), neleca)
    link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)

    ci0 = fcivec.reshape(na,nb,-1)
    rdm1 = numpy.zeros((nsite,nsite))
    rdm2 = numpy.zeros((nsite,nsite,nsite,nsite))
    for str0 in range(na):
        t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:])
        for a, i, str1, sign in link_indexa[str0]:
            t1[i,a,:] += sign * ci0[str1,:]

        for k, tab in enumerate(link_indexb):
            for a, i, str1, sign in tab:
                t1[i,a,k] += sign * ci0[str0,str1]

        rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1)
        # i^+ j|0> => <0|j^+ i, so swap i and j
        #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1)
        tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T)
        rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3)
    rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True)
    return rdm1, rdm2
Ejemplo n.º 14
0
def ft_rdm1s(h1e, g2e, norb, nelec, T, m=50, nsamp=40, Tmin=10e-4):
    '''rdm of spin a and b at temperature T
    '''
    if T < Tmin:
       e, c = kernel(h1e, g2e, norb, nelec)
       rdma, rdmb = direct_spin1.make_rdm1s(c, norb, nelec)
       return rdma, rdmb

    h2e = direct_spin1.absorb_h1e(h1e, g2e, norb, nelec, .5)
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    def vecgen(n1=na, n2=nb):
        ci0 = numpy.random.randn(n1, n2)
#        ci0[0, 0] = 1.
        return ci0.reshape(-1)
    def hop(c):
        hc = direct_spin1.contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)
    def qud(v1, v2):
        dma, dmb = direct_spin1.trans_rdm1s(v1, v2, norb, nelec)
        return dma, dmb

#    rdma, rdmb = flan.ht_rdm1s(qud, hop, vecgen, T, norb, m, nsamp)
    rdma, rdmb = flan.ftlan_rdm1s(qud, hop, vecgen, T, norb, m, nsamp)
    return rdma, rdmb
Ejemplo n.º 15
0
def kernal_hubbard(t, u, norb, nelec):
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelec//2
        nelecb = nelec - neleca
    else:
        neleca, nelecb = nelec

    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    def mk_tridiag(t, norb):
        tmat = numpy.ones(norb-1) * (-t)
        res = numpy.diag(tmat, -1) + numpy.diag(tmat, 1)
        res[0, norb-1] = -t
        res[norb-1, 0] = -t
        return res
    f1e = mk_tridiag(t, norb)
    print f1e
    U = (0., u, 0.)
    def hop(c):
        hc = contract_2e_hubbard(U, c, norb, nelec)\
             +contract_1e(f1e, c, norb, nelec)
        return hc.reshape(-1)
    ci0 = numpy.random.random((na, nb))
    hdiag = make_hdiag_hubbard(f1e, u, norb, nelec)
    print "hdiag:,\n", hdiag
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)
    e, c = pyscf.lib.davidson(hop, ci0.reshape(-1), precond)
    return e
Ejemplo n.º 16
0
def kernel(h1e, eri, norb, nelec, ecore=0, verbose=logger.NOTE):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
    namax = cistring.num_strings(norb, neleca)
    nbmax = cistring.num_strings(norb, nelecb)

    myci = SelectedCI()

    strsa = [int('1'*neleca, 2)]
    strsb = [int('1'*nelecb, 2)]
    ci_strs = (strsa, strsb)
    ci0 = numpy.ones((1,1))
    ci0, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)

    def all_linkstr_index(ci_strs):
        cd_indexa = cre_des_linkstr(ci_strs[0], norb, neleca)
        dd_indexa = des_des_linkstr(ci_strs[0], norb, neleca)
        cd_indexb = cre_des_linkstr(ci_strs[1], norb, nelecb)
        dd_indexb = des_des_linkstr(ci_strs[1], norb, nelecb)
        return cd_indexa, dd_indexa, cd_indexb, dd_indexb

    def hop(c):
        hc = contract_2e(h2e, (c, ci_strs), norb, nelec, link_index)
        return hc.reshape(-1)
    precond = lambda x, e, *args: x/(hdiag-e+1e-4)

    e_last = 0
    tol = 1e-2
    conv = False
    for icycle in range(norb):
        tol = max(tol*1e-2, myci.float_tol)
        link_index = all_linkstr_index(ci_strs)
        hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
        e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=tol,
                              verbose=verbose)
        print('icycle %d  ci.shape %s  E = %.15g' %
              (icycle, (len(ci_strs[0]), len(ci_strs[1])), e))
        if ci0.shape == (namax,nbmax) or abs(e-e_last) < myci.float_tol*10:
            conv = True
            break
        ci1, ci_strs = enlarge_space(myci, (ci0, ci_strs), h2e, norb, nelec)
        if ci1.size < ci0.size*1.02:
            conv = True
            break
        e_last = e
        ci0 = ci1

    link_index = all_linkstr_index(ci_strs)
    hdiag = make_hdiag(h1e, eri, ci_strs, norb, nelec)
    e, ci0 = lib.davidson(hop, ci0.reshape(-1), precond, tol=myci.conv_tol,
                          verbose=verbose)

    na = len(ci_strs[0])
    nb = len(ci_strs[1])
    return e+ecore, (ci0.reshape(na,nb), ci_strs)
Ejemplo n.º 17
0
def from_fci(fcivec, ci_strs, norb, nelec):
    fcivec, nelec, ci_strs = _unpack(fcivec, nelec, ci_strs)
    addrsa = [cistring.str2addr(norb, nelec[0], x) for x in ci_strs[0]]
    addrsb = [cistring.str2addr(norb, nelec[1], x) for x in ci_strs[1]]
    na = cistring.num_strings(norb, nelec[0])
    nb = cistring.num_strings(norb, nelec[1])
    fcivec = fcivec.reshape(na,nb)
    civec = lib.take_2d(fcivec, addrsa, addrsb)
    return _as_SCIvector(civec, ci_strs)
Ejemplo n.º 18
0
def to_fci(civec_strs, norb, nelec):
    ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec)
    addrsa = [cistring.str2addr(norb, nelec[0], x) for x in ci_strs[0]]
    addrsb = [cistring.str2addr(norb, nelec[1], x) for x in ci_strs[1]]
    na = cistring.num_strings(norb, nelec[0])
    nb = cistring.num_strings(norb, nelec[1])
    ci0 = numpy.zeros((na,nb))
    lib.takebak_2d(ci0, ci_coeff, addrsa, addrsb)
    return ci0
Ejemplo n.º 19
0
def make_shape(nsite, nelec, nphonon):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)
    return (na,nb)+(nphonon+1,)*nsite
Ejemplo n.º 20
0
def initguess_triplet(norb, nelec, binstring):
    '''Generate a triplet initial guess for FCI solver
    '''
    neleca, nelecb = _unpack(nelec)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    addr = cistring.str2addr(norb, neleca, int(binstring,2))
    ci0 = numpy.zeros((na,nb))
    ci0[addr,0] = numpy.sqrt(.5)
    ci0[0,addr] =-numpy.sqrt(.5)
    return ci0
Ejemplo n.º 21
0
def initguess_triplet(norb, nelec, binstring):
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelecb = nelec//2
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    addr = cistring.str2addr(norb, neleca, int(binstring,2))
    ci0 = numpy.zeros((na,nb))
    ci0[addr,0] = numpy.sqrt(.5)
    ci0[0,addr] =-numpy.sqrt(.5)
    return ci0
Ejemplo n.º 22
0
def contract_2e_hubbard(u, fcivec, norb, nelec, opt=None):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    u_aa, u_ab, u_bb = u

    strsa = cistring.gen_strings4orblist(range(norb), neleca)
    strsb = cistring.gen_strings4orblist(range(norb), nelecb)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    fcivec = fcivec.reshape(na,nb)
    t1a = numpy.zeros((norb,na,nb))
    t1b = numpy.zeros((norb,na,nb))
    fcinew = numpy.zeros_like(fcivec)

    for addr, s in enumerate(strsa):
        for i in range(norb):
            if s & (1<<i):
                t1a[i,addr] += fcivec[addr]
    for addr, s in enumerate(strsb):
        for i in range(norb):
            if s & (1<<i):
                t1b[i,:,addr] += fcivec[:,addr]

    if u_aa != 0:
        # u * n_alpha^+ n_alpha
        for addr, s in enumerate(strsa):
            for i in range(norb):
                if s & (1<<i):
                    fcinew[addr] += t1a[i,addr] * u_aa
    if u_ab != 0:
        # u * n_alpha^+ n_beta
        for addr, s in enumerate(strsa):
            for i in range(norb):
                if s & (1<<i):
                    fcinew[addr] += t1b[i,addr] * u_ab
        # u * n_beta^+ n_alpha
        for addr, s in enumerate(strsb):
            for i in range(norb):
                if s & (1<<i):
                    fcinew[:,addr] += t1a[i,:,addr] * u_ab
    if u_bb != 0:
        # u * n_beta^+ n_beta
        for addr, s in enumerate(strsb):
            for i in range(norb):
                if s & (1<<i):
                    fcinew[:,addr] += t1b[i,:,addr] * u_bb
    return fcinew
Ejemplo n.º 23
0
def kernel_ft(h1e, g2e, norb, nelec, T, m=50, nsamp=40):
    '''E at temperature T
    '''
    h2e = absorb_h1e(h1e, g2e, norb, nelec, .5)
    neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    def vecgen(n1=na, n2=nb):
        ci0 = numpy.random.rand(n1, n2)
        return ci0.reshape(-1)
    def hop(c):
        hc = contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)

    E = ftlan_E(hop, vecgen, T, m, nsamp)
    return E
Ejemplo n.º 24
0
def pspace(h1e, eri, norb, nelec, hdiag, np=400):
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelec//2
    else:
        neleca, nelecb = nelec
        assert(neleca == nelecb)
    h1e = numpy.ascontiguousarray(h1e)
    eri = pyscf.ao2mo.restore(1, eri, norb)
    na = cistring.num_strings(norb, neleca)
    addr = numpy.argsort(hdiag)[:np]
# symmetrize addra/addrb
    addra = addr // na
    addrb = addr % na
    stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra],
                       dtype=numpy.long)
    strb = numpy.array([cistring.addr2str(norb,neleca,ib) for ib in addrb],
                       dtype=numpy.long)
    np = len(addr)
    h0 = numpy.zeros((np,np))
    libfci.FCIpspace_h0tril(h0.ctypes.data_as(ctypes.c_void_p),
                            h1e.ctypes.data_as(ctypes.c_void_p),
                            eri.ctypes.data_as(ctypes.c_void_p),
                            stra.ctypes.data_as(ctypes.c_void_p),
                            strb.ctypes.data_as(ctypes.c_void_p),
                            ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i,i] = hdiag[addr[i]]
    h0 = pyscf.lib.hermi_triu_(h0)
    return addr, h0
Ejemplo n.º 25
0
def pspace(h1e, eri, norb, nelec, hdiag, np=400):
    '''pspace Hamiltonian to improve Davidson preconditioner. See, CPL, 169, 463
    '''
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    h1e = numpy.ascontiguousarray(h1e)
    eri = pyscf.ao2mo.restore(1, eri, norb)
    nb = cistring.num_strings(norb, nelecb)
    addr = numpy.argsort(hdiag)[:np]
    addra = addr // nb
    addrb = addr % nb
    stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra],
                       dtype=numpy.uint64)
    strb = numpy.array([cistring.addr2str(norb,nelecb,ib) for ib in addrb],
                       dtype=numpy.uint64)
    np = len(addr)
    h0 = numpy.zeros((np,np))
    libfci.FCIpspace_h0tril(h0.ctypes.data_as(ctypes.c_void_p),
                            h1e.ctypes.data_as(ctypes.c_void_p),
                            eri.ctypes.data_as(ctypes.c_void_p),
                            stra.ctypes.data_as(ctypes.c_void_p),
                            strb.ctypes.data_as(ctypes.c_void_p),
                            ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i,i] = hdiag[addr[i]]
    h0 = pyscf.lib.hermi_triu_(h0)
    return addr, h0
Ejemplo n.º 26
0
def cre_a(ci0, norb, neleca_nelecb, ap_id):
    r'''Construct (N+1)-electron wavefunction by adding an alpha electron in
    the N-electron wavefunction.

    ... math::

        |N+1\rangle = \hat{a}^+_p |N\rangle

    Args:
        ci0 : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        (neleca,nelecb) : (int,int)
            Number of (alpha, beta) electrons of the input CI function
        ap_id : int
            Orbital index (0-based), for the creation operator

    Returns:
        2D array, row for alpha strings and column for beta strings. Note it
        has different number of rows to the input CI coefficients.
    '''
    neleca, nelecb = neleca_nelecb
    if neleca >= norb:
        return numpy.zeros((0, ci0.shape[1]))
    cre_index = cistring.gen_cre_str_index(range(norb), neleca)
    na_ci1 = cistring.num_strings(norb, neleca+1)
    ci1 = numpy.zeros((na_ci1, ci0.shape[1]))

    entry_has_ap = (cre_index[:,:,0] == ap_id)
    addr_ci0 = numpy.any(entry_has_ap, axis=1)
    addr_ci1 = cre_index[entry_has_ap,2]
    sign = cre_index[entry_has_ap,3]
    ci1[addr_ci1] = sign.reshape(-1,1) * ci0[addr_ci0]
    return ci1
Ejemplo n.º 27
0
def des_b(ci0, norb, neleca_nelecb, ap_id):
    r'''Construct (N-1)-electron wavefunction by removing a beta electron from
    N-electron wavefunction.

    Args:
        ci0 : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        (neleca,nelecb) : (int,int)
            Number of (alpha, beta) electrons of the input CI function
        ap_id : int
            Orbital index (0-based), for the annihilation operator

    Returns:
        2D array, row for alpha strings and column for beta strings. Note it
        has different number of columns to the input CI coefficients.
    '''
    neleca, nelecb = neleca_nelecb
    if nelecb <= 0:
        return numpy.zeros((ci0.shape[0], 0))
    des_index = cistring.gen_des_str_index(range(norb), nelecb)
    nb_ci1 = cistring.num_strings(norb, nelecb-1)
    ci1 = numpy.zeros((ci0.shape[0], nb_ci1))

    entry_has_ap = (des_index[:,:,1] == ap_id)
    addr_ci0 = numpy.any(entry_has_ap, axis=1)
    addr_ci1 = des_index[entry_has_ap,2]
    sign = des_index[entry_has_ap,3]
    # This sign prefactor accounts for interchange of operators with alpha and beta spins
    if neleca % 2 == 1:
        sign *= -1
    ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign
    return ci1
Ejemplo n.º 28
0
def cre_b(ci0, norb, nelec, ap_id):
    r'''Construct (N+1)-electron wavefunction by adding a beta electron in
    the N-electron wavefunction.

    Args:
        ci0 : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        nelec : int or 2-item list
            Number of electrons, or 2-item list for (alpha, beta) electrons
        ap_id : int
            Orbital index (0-based), for the creation operator

    Returns:
        2D array, row for alpha strings and column for beta strings. Note it
        has different number of columns to the input CI coefficients.
    '''
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelecb = nelec // 2
    else:
        neleca, nelecb = nelec
    cre_index = cistring.gen_cre_str_index(range(norb), nelecb)
    nb_ci1 = cistring.num_strings(norb, nelecb+1)
    ci1 = numpy.zeros((ci0.shape[0], nb_ci1))

    entry_has_ap = (cre_index[:,:,0] == ap_id)
    addr_ci0 = numpy.any(entry_has_ap, axis=1)
    addr_ci1 = cre_index[entry_has_ap,2]
    sign = cre_index[entry_has_ap,3]
    # This sign prefactor accounts for interchange of operators with alpha and beta spins
    if neleca % 2 == 1:
        sign *= -1
    ci1[:,addr_ci1] = ci0[:,addr_ci0] * sign
    return ci1
Ejemplo n.º 29
0
def pspace(h1e, eri, norb, nelec, hdiag, np=400):
    '''pspace Hamiltonian to improve Davidson preconditioner. See, CPL, 169, 463
    '''
    neleca, nelecb = _unpack_nelec(nelec)
    h1e = numpy.ascontiguousarray(h1e)
    eri = ao2mo.restore(1, eri, norb)
    nb = cistring.num_strings(norb, nelecb)
    if hdiag.size < np:
        addr = numpy.arange(hdiag.size)
    else:
        try:
            addr = numpy.argpartition(hdiag, np-1)[:np]
        except AttributeError:
            addr = numpy.argsort(hdiag)[:np]
    addra, addrb = divmod(addr, nb)
    stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra],
                       dtype=numpy.uint64)
    strb = numpy.array([cistring.addr2str(norb,nelecb,ib) for ib in addrb],
                       dtype=numpy.uint64)
    np = len(addr)
    h0 = numpy.zeros((np,np))
    libfci.FCIpspace_h0tril(h0.ctypes.data_as(ctypes.c_void_p),
                            h1e.ctypes.data_as(ctypes.c_void_p),
                            eri.ctypes.data_as(ctypes.c_void_p),
                            stra.ctypes.data_as(ctypes.c_void_p),
                            strb.ctypes.data_as(ctypes.c_void_p),
                            ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i,i] = hdiag[addr[i]]
    h0 = lib.hermi_triu(h0)
    return addr, h0
Ejemplo n.º 30
0
def get_init_guess(norb, nelec, nroots, hdiag):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)

    ci0 = []
    iroot = 0
    for addr in numpy.argsort(hdiag):
        x = numpy.zeros((na*nb))
        x[addr] = 1
        ci0.append(x.ravel())
        iroot += 1
        if iroot >= nroots:
            break
    return ci0
Ejemplo n.º 31
0
def des_b(ci0, norb, neleca_nelecb, ap_id):
    r'''Construct (N-1)-electron wavefunction by removing a beta electron from
    N-electron wavefunction.

    Args:
        ci0 : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        (neleca,nelecb) : (int,int)
            Number of (alpha, beta) electrons of the input CI function
        ap_id : int
            Orbital index (0-based), for the annihilation operator

    Returns:
        2D array, row for alpha strings and column for beta strings. Note it
        has different number of columns to the input CI coefficients.
    '''
    neleca, nelecb = neleca_nelecb
    if ci0.ndim == 1:
        ci0 = ci0.reshape(cistring.num_strings(norb, neleca),
                          cistring.num_strings(norb, nelecb))
    if nelecb <= 0:
        return numpy.zeros((ci0.shape[0], 0))
    des_index = cistring.gen_des_str_index(range(norb), nelecb)
    nb_ci1 = cistring.num_strings(norb, nelecb - 1)
    ci1 = numpy.zeros((ci0.shape[0], nb_ci1))

    entry_has_ap = (des_index[:, :, 1] == ap_id)
    addr_ci0 = numpy.any(entry_has_ap, axis=1)
    addr_ci1 = des_index[entry_has_ap, 2]
    sign = des_index[entry_has_ap, 3]
    # This sign prefactor accounts for interchange of operators with alpha and beta spins
    if neleca % 2 == 1:
        sign *= -1
    ci1[:, addr_ci1] = ci0[:, addr_ci0] * sign
    return ci1
Ejemplo n.º 32
0
def guess_wfnsym(ci, norb, nelec, orbsym):
    '''Guess the wavefunction symmetry based on the non-zero elements in the
    given CI coefficients.

    Args:
        ci : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        nelec : int or 2-item list
            Number of electrons, or 2-item list for (alpha, beta) electrons
        orbsym : list of int
            The irrep ID for each orbital.

    Returns:
        Irrep ID
    '''
    neleca, nelecb = _unpack(nelec)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    if isinstance(ci, numpy.ndarray) and ci.ndim <= 2:
        assert (ci.size == na * nb)
        idx = numpy.argmax(ci)
    else:
        assert (ci[0].size == na * nb)
        idx = ci[0].argmax()
    stra = cistring.addr2str(norb, neleca, idx // nb)
    strb = cistring.addr2str(norb, nelecb, idx % nb)

    airrep = 0
    birrep = 0
    for i in range(norb):
        if (stra & (1 << i)):
            airrep ^= orbsym[i]
        if (strb & (1 << i)):
            birrep ^= orbsym[i]
    return airrep ^ birrep
Ejemplo n.º 33
0
def cre_b(ci0, norb, neleca_nelecb, ap_id):
    r'''Construct (N+1)-electron wavefunction by adding a beta electron in
    the N-electron wavefunction.

    Args:
        ci0 : 2D array
            CI coefficients, row for alpha strings and column for beta strings.
        norb : int
            Number of orbitals.
        (neleca,nelecb) : (int,int)
            Number of (alpha, beta) electrons of the input CI function
        ap_id : int
            Orbital index (0-based), for the creation operator

    Returns:
        2D array, row for alpha strings and column for beta strings. Note it
        has different number of columns to the input CI coefficients.
    '''
    neleca, nelecb = neleca_nelecb
    if nelecb >= norb:
        return numpy.zeros_like(ci0)
    if ci0.ndim == 1:
        ci0 = ci0.reshape(cistring.num_strings(norb, neleca),
                          cistring.num_strings(norb, nelecb))
    cre_index = cistring.gen_cre_str_index(range(norb), nelecb)
    nb_ci1 = cistring.num_strings(norb, nelecb + 1)
    ci1 = numpy.zeros((ci0.shape[0], nb_ci1), dtype=ci0[0, 0].__class__)

    entry_has_ap = (cre_index[:, :, 0] == ap_id)
    addr_ci0 = numpy.any(entry_has_ap, axis=1)
    addr_ci1 = cre_index[entry_has_ap, 2]
    sign = cre_index[entry_has_ap, 3].astype(complex)
    # This sign prefactor accounts for interchange of operators with alpha and beta spins
    if neleca % 2 == 1:
        sign *= -1
    ci1[:, addr_ci1] = ci0[:, addr_ci0] * sign
    return ci1
Ejemplo n.º 34
0
Archivo: ucisd.py Proyecto: MSwenne/BEP
def from_fcivec(ci0, norb, nelec, frozen=0):
    '''Extract CISD coefficients from FCI coefficients'''
    if frozen is not 0:
        raise NotImplementedError
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    norba = norbb = norb
    nocc = nocca, noccb = neleca, nelecb
    nvira = norba - nocca
    nvirb = norbb - noccb
    t1addra, t1signa = cisd.tn_addrs_signs(norba, nocca, 1)
    t1addrb, t1signb = cisd.tn_addrs_signs(norbb, noccb, 1)

    na = cistring.num_strings(norba, nocca)
    nb = cistring.num_strings(norbb, noccb)
    ci0 = ci0.reshape(na, nb)
    c0 = ci0[0, 0]
    c1a = (ci0[t1addra, 0] * t1signa).reshape(nocca, nvira)
    c1b = (ci0[0, t1addrb] * t1signb).reshape(noccb, nvirb)

    c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra[:, None],
                                                            t1addrb])
    c2ab = c2ab.reshape(nocca, nvira, noccb, nvirb).transpose(0, 2, 1, 3)
    t2addra, t2signa = cisd.tn_addrs_signs(norba, nocca, 2)
    t2addrb, t2signb = cisd.tn_addrs_signs(norbb, noccb, 2)
    c2aa = (ci0[t2addra, 0] * t2signa).reshape(nocca * (nocca - 1) // 2,
                                               nvira * (nvira - 1) // 2)
    c2aa = _unpack_4fold(c2aa, nocca, nvira)
    c2bb = (ci0[0, t2addrb] * t2signb).reshape(noccb * (noccb - 1) // 2,
                                               nvirb * (nvirb - 1) // 2)
    c2bb = _unpack_4fold(c2bb, noccb, nvirb)

    return amplitudes_to_cisdvec(c0, (c1a, c1b), (c2aa, c2ab, c2bb))
Ejemplo n.º 35
0
 def __init__(self, mc, state=None):
     self.__dict__.update (mc.__dict__)
     nmo = mc.mo_coeff.shape[-1]
     self.ngorb = np.count_nonzero (mc.uniq_var_indices (nmo, mc.ncore, mc.ncas, mc.frozen))
     self.nroots = mc.fcisolver.nroots
     neleca, nelecb = _unpack_nelec (mc.nelecas)
     self.spin_states = [neleca - nelecb,] * self.nroots
     self.na_states = [cistring.num_strings (mc.ncas, neleca),] * self.nroots
     self.nb_states = [cistring.num_strings (mc.ncas, nelecb),] * self.nroots
     if isinstance (mc.fcisolver, StateAverageMixFCISolver):
         self.nroots = p0 = 0
         for solver in mc.fcisolver.fcisolvers:
             self.nroots += solver.nroots
             nea, neb = mc.fcisolver._get_nelec (solver, (neleca, nelecb))
             self.spin_states[p0:self.nroots] = (nea - neb for x in range (solver.nroots))
             self.na_states[p0:self.nroots] = (cistring.num_strings (mc.ncas, nea) for x in range (solver.nroots))
             self.nb_states[p0:self.nroots] = (cistring.num_strings (mc.ncas, neb) for x in range (solver.nroots))
             p0 = self.nroots
     self.nci = sum ([na * nb for na, nb in zip (self.na_states, self.nb_states)])
     if state is not None:
         self.state = state
     elif hasattr (mc, 'nuc_grad_state'):
         self.state = mc.nuc_grad_state
     else:
         self.state = None
     self.eris = None
     self.weights = np.array ([1])
     try:
         self.e_states = np.asarray (mc.e_states)
     except AttributeError as e:
         self.e_states = np.asarray (mc.e_tot)
     if isinstance (mc, StateAverageMCSCFSolver):
         self.weights = np.asarray (mc.weights)
     assert (len (self.weights) == self.nroots), '{} {} {}'.format (mc.fcisolver.__class__, self.weights, self.nroots)
     lagrange.Gradients.__init__(self, mc, self.ngorb+self.nci)
     self.max_cycle = mc.max_cycle_macro
Ejemplo n.º 36
0
def kernel(h1e, eri, norb, nelec, ecore=0):
    h2e = absorb_h1e(h1e, eri, norb, nelec, .5)

    na = cistring.num_strings(norb, nelec // 2)
    ci0 = numpy.zeros((na, na))
    ci0[0, 0] = 1

    def hop(c):
        hc = contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)

    hdiag = make_hdiag(h1e, eri, norb, nelec)
    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
    e, c = lib.davidson(hop, ci0.reshape(-1), precond)
    return e + ecore
Ejemplo n.º 37
0
def from_fcivec(ci0, norb, nelec, frozen=0):
    from pyscf.ci.gcisd import t2strs
    if frozen is not 0:
        raise NotImplementedError
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    norba = norbb = norb
    nocc = nocca, noccb = neleca, nelecb
    nvira = norba - nocca
    nvirb = norbb - noccb
    t1addra, t1signa = cisd.t1strs(norba, nocca)
    t1addrb, t1signb = cisd.t1strs(norbb, noccb)

    na = cistring.num_strings(norba, nocca)
    nb = cistring.num_strings(norbb, noccb)
    ci0 = ci0.reshape(na, nb)
    c0 = ci0[0, 0]
    c1a = ((ci0[t1addra, 0] * t1signa).reshape(nvira, nocca).T)[::-1]
    c1b = ((ci0[0, t1addrb] * t1signb).reshape(nvirb, noccb).T)[::-1]

    c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra][:,
                                                                     t1addrb])
    c2ab = c2ab.reshape(nvira, nocca, nvirb, noccb).transpose(1, 3, 0, 2)
    c2ab = c2ab[::-1, ::-1]
    t2addra, t2signa = t2strs(norba, nocca)
    c2aa = (ci0[t2addra, 0] * t2signa).reshape(nvira * (nvira - 1) // 2, -1).T
    c2aa = _unpack_4fold(c2aa[::-1], nocca, nvira)
    t2addrb, t2signb = t2strs(norbb, noccb)
    c2bb = (ci0[0, t2addrb] * t2signb).reshape(nvirb * (nvirb - 1) // 2, -1).T
    c2bb = _unpack_4fold(c2bb[::-1], noccb, nvirb)

    return amplitudes_to_cisdvec(c0, (c1a, c1b), (c2aa, c2ab, c2bb))
Ejemplo n.º 38
0
def make_rdm12(fcivec, norb, nelec, opt=None):
    link_index = cistring.gen_linkstr_index(range(norb), nelec)
    na = cistring.num_strings(norb, nelec)

    rdm1 = numpy.zeros((norb, norb), dtype=numpy.complex128)
    rdm2 = numpy.zeros((norb, norb, norb, norb), dtype=numpy.complex128)
    t1 = numpy.zeros((na, norb, norb), dtype=numpy.complex128)
    for str0, tab in enumerate(link_index):
        for a, i, str1, sign in link_index[str0]:
            t1[str1, i, a] += sign * fcivec[str0]

    rdm1 += numpy.einsum('m,mij->ij', fcivec.conj(), t1)
    #i^+ j|0> => <0|j^+ i, so swap i and j
    rdm2 += numpy.einsum('mij,mkl->jikl', t1.conj(), t1)

    return reorder_rdm(rdm1, rdm2)
Ejemplo n.º 39
0
def setUpModule():
    global ci_strs, ci_coeff, civec_strs, eri, h1, spin0_ci_strs, spin0_ci_coeff
    global norb, nelec
    norb = 6
    nelec = 6
    na = cistring.num_strings(norb, nelec // 2)
    ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b1101]]
    numpy.random.seed(12)
    ci_coeff = (numpy.random.random(
        (len(ci_strs[0]), len(ci_strs[1]))) - .2)**3
    civec_strs = selected_ci._as_SCIvector(ci_coeff, ci_strs)
    nn = norb * (norb + 1) // 2
    eri = (numpy.random.random(nn * (nn + 1) // 2) - .2)**3
    h1 = numpy.random.random((norb, norb))
    h1 = h1 + h1.T

    spin0_ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b10101]]
    spin0_ci_coeff = ci_coeff + ci_coeff.T
Ejemplo n.º 40
0
def make_rdm12(civec, norb, nelec, link_index=None, reorder=True):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    assert (neleca == nelecb)

    if link_index is None:
        link_index = cistring.gen_linkstr_index(range(norb), neleca)
    na = cistring.num_strings(norb, neleca)
    t1 = numpy.zeros((norb, na))
    t2 = numpy.zeros((norb, norb, na))
    #:for str0, tab in enumerate(link_index):
    #:    for a, i, str1, sign in tab:
    #:        if a == i:
    #:            t1[i,str1] += civec[str0]
    #:        else:
    #:            t2[a,i,str1] += civec[str0]
    link1 = link_index[link_index[:, :,
                                  0] == link_index[:, :,
                                                   1]].reshape(na, -1, 4)
    link2 = link_index[link_index[:, :, 0] != link_index[:, :, 1]].reshape(
        na, -1, 4)
    t1[link1[:, :, 1], link1[:, :, 2]] = civec[:, None]
    t2[link2[:, :, 0], link2[:, :, 1], link2[:, :, 2]] = civec[:, None]

    idx = numpy.arange(norb)
    dm2 = numpy.zeros([norb] * 4)
    # Assign to dm2[i,j,i,j]
    dm2[idx[:, None], idx, idx[:, None],
        idx] += 2 * numpy.einsum('ijp,p->ij', t2, civec)
    # Assign to dm2[i,j,j,i]
    dm2[idx[:, None], idx, idx,
        idx[:, None]] += 2 * numpy.einsum('ijp,ijp->ij', t2, t2)
    # Assign to dm2[i,i,j,j]
    dm2[idx[:, None], idx[:, None], idx,
        idx] += 4 * numpy.einsum('ip,jp->ij', t1, t1)

    dm1 = numpy.einsum('ijkk->ij', dm2) / (neleca + nelecb)

    if reorder:
        dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True)
    return dm1, dm2
Ejemplo n.º 41
0
def contract_2e(eri, fcivec, norb, nelec, opt=None):

    link_indexa = cistring.gen_linkstr_index_o0(range(norb), nelec)
    na = cistring.num_strings(norb, nelec)

    ci0 = fcivec
    t1 = numpy.zeros((norb, norb, na), dtype=numpy.complex128)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            t1[a, i, str1] += sign * ci0[str0]

    t1 = numpy.dot(eri.reshape(norb * norb, -1), t1.reshape(norb * norb, -1))
    t1 = t1.reshape(norb, norb, na)
    fcinew = numpy.zeros_like(ci0, dtype=numpy.complex128)
    for str0, tab in enumerate(link_indexa):
        for a, i, str1, sign in tab:
            fcinew[str1] += sign * t1[a, i, str0]

    return fcinew.reshape(fcivec.shape)
Ejemplo n.º 42
0
def _guess_nelec_f (fci, norb, nelec, norb_f, h1, h2):
    # Pick electron distribution by the lowest-energy single determinant
    nelec = direct_spin1._unpack_nelec (nelec)
    hdiag = fci.make_hdiag (h1, h2, norb, nelec)
    ndetb = cistring.num_strings (norb, nelec[1])
    addr_dp = np.divmod (np.argmin (hdiag), ndetb)
    str_dp = [cistring.addr2str (norb, n, c) for n,c in zip (nelec, addr_dp)]
    nelec_f = []
    for n in norb_f:
        ndet = 2**n
        c = np.zeros ((ndet, ndet))
        det = np.array ([str_dp[0] % ndet, str_dp[1] % ndet], dtype=np.integer)
        str_dp = [str_dp[0] // ndet, str_dp[1] // ndet]
        ne = [0,0]
        for spin in range (2):
            for iorb in range (n):
                ne[spin] += int (bool ((det[spin] & (1 << iorb))))
        nelec_f.append (ne)
    return nelec_f
Ejemplo n.º 43
0
def kernel(h1e, g2e, norb, nelec):

    na = cistring.num_strings(norb, nelec)

    h2e = absorb_h1e(h1e, g2e, norb, nelec, .5)

    def hop(c):
        hc = contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)

    hdiag = make_hdiag(h1e, g2e, norb, nelec)
    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)

    ci0 = numpy.random.random(na)
    ci0 /= numpy.linalg.norm(ci0)

    #e, c = pyscf.lib.davidson(hop, ci0, precond, max_space=100)
    e, c = pyscf.lib.davidson(hop, ci0, precond)
    return e, c
Ejemplo n.º 44
0
def make_rdm12(fcivec, norb, nelec, opt=None):
    link_index = cistring.gen_linkstr_index(range(norb), nelec // 2)
    na = cistring.num_strings(norb, nelec // 2)
    fcivec = fcivec.reshape(na, na)

    rdm1 = numpy.zeros((norb, norb))
    rdm2 = numpy.zeros((norb, norb, norb, norb))
    for str0, tab in enumerate(link_index):
        t1 = numpy.zeros((na, norb, norb))
        for a, i, str1, sign in link_index[str0]:
            t1[:, i, a] += sign * fcivec[str1, :]

        for k, tab in enumerate(link_index):
            for a, i, str1, sign in tab:
                t1[k, i, a] += sign * fcivec[str0, str1]

        rdm1 += numpy.einsum('m,mij->ij', fcivec[str0], t1)
        # i^+ j|0> => <0|j^+ i, so swap i and j
        rdm2 += numpy.einsum('mij,mkl->jikl', t1, t1)
    return reorder_rdm(rdm1, rdm2)
Ejemplo n.º 45
0
def kernel(h1e, g2e, norb, nelec):

    h2e = direct_spin1.absorb_h1e(h1e, g2e, norb, nelec, .5)
    if isinstance(nelec, (int, numpy.integer)):
        neleca = nelec // 2
    else:
        neleca = nelec[0]

    na = cistring.num_strings(norb, neleca)
    ci0 = numpy.zeros((na, na))
    ci0[0, 0] = 1

    def hop(c):
        hc = direct_spin1.contract_2e(h2e, c, norb, nelec)
        return hc.reshape(-1)

    hdiag = direct_spin1.make_hdiag(h1e, g2e, norb, nelec)
    precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
    e, c = pyscf.lib.davidson(hop, ci0.reshape(-1), precond)
    return e, c
Ejemplo n.º 46
0
    def kernel_ref(h1e, eri, norb, nelec, ecore=0, **kwargs):
        if isinstance(nelec, (int, numpy.integer)):
            nelecb = nelec // 2
            neleca = nelec - nelecb
        else:
            neleca, nelecb = nelec
        h2e = direct_spin1.absorb_h1e(h1e, eri, norb, nelec, .5)
        h2e = ao2mo.restore(1, h2e, norb)
        na = cistring.num_strings(norb, neleca)
        ci0 = numpy.zeros(na)
        ci0[0] = 1

        link_index = cistring.gen_linkstr_index(range(norb), neleca)

        def hop(c):
            return contract_2e_ref(h2e, c, norb, nelec, link_index)

        hdiag = make_hdiag(h1e, eri, norb, nelec)
        precond = lambda x, e, *args: x / (hdiag - e + 1e-4)
        e, c = lib.davidson(hop, ci0.reshape(-1), precond, **kwargs)
        return e + ecore
Ejemplo n.º 47
0
def fci_simple(mol, m, lam=1.0):
    norb = m.mo_coeff.shape[1]
    nelec = mol.nelectron
    f = m.get_fock()
    hprime = f + lam * (m.get_hcore() - f)
    h1e = reduce(numpy.dot, (m.mo_coeff.T, hprime, m.mo_coeff))
    eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False)
    eri = lam * eri.reshape(norb, norb, norb, norb)
    h2e = fci_slow.absorb_h1e(h1e, eri, norb, nelec, .5)
    na = cistring.num_strings(norb, nelec // 2)
    N = na * na
    assert (N < 2000)
    H = numpy.zeros((N, N))
    I = numpy.identity(N)
    for i in range(N):
        hc = fci_slow.contract_2e(h2e, I[:, i], norb, nelec)
        hc.reshape(-1)
        H[:, i] = hc

    e, v = numpy.linalg.eigh(H)
    #print(e[0] + mol.energy_nuc())
    return e[0] + mol.energy_nuc()
Ejemplo n.º 48
0
def make_rdm1(civec, norb, nelec, link_index=None):
    if isinstance(nelec, (int, numpy.integer)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    assert (neleca == nelecb)

    if link_index is None:
        link_index = cistring.gen_linkstr_index(range(norb), neleca)
    na = cistring.num_strings(norb, neleca)
    t1 = numpy.zeros((norb, na))
    #:for str0, tab in enumerate(link_index):
    #:    for a, i, str1, sign in tab:
    #:        if a == i:
    #:            t1[i,str1] += civec[str0]
    link1 = link_index[link_index[:, :,
                                  0] == link_index[:, :,
                                                   1]].reshape(na, -1, 4)
    t1[link1[:, :, 1], link1[:, :, 2]] = civec[:, None]

    dm1 = numpy.diag(numpy.einsum('ip,p->i', t1, civec)) * 2
    return dm1
Ejemplo n.º 49
0
def pspace(h1e, eri, norb, nelec, hdiag=None, np=400):
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    h1e_a = numpy.ascontiguousarray(h1e[0])
    h1e_b = numpy.ascontiguousarray(h1e[1])
    g2e_aa = ao2mo.restore(1, eri[0], norb)
    g2e_ab = ao2mo.restore(1, eri[1], norb)
    g2e_bb = ao2mo.restore(1, eri[2], norb)
    if hdiag is None:
        hdiag = make_hdiag(h1e, eri, norb, nelec)
    if hdiag.size < np:
        addr = numpy.arange(hdiag.size)
    else:
        try:
            addr = numpy.argpartition(hdiag, np-1)[:np]
        except AttributeError:
            addr = numpy.argsort(hdiag)[:np]
    nb = cistring.num_strings(norb, nelecb)
    addra = addr // nb
    addrb = addr % nb
    stra = cistring.addrs2str(norb, neleca, addra)
    strb = cistring.addrs2str(norb, nelecb, addrb)
    np = len(addr)
    h0 = numpy.zeros((np,np))
    libfci.FCIpspace_h0tril_uhf(h0.ctypes.data_as(ctypes.c_void_p),
                                h1e_a.ctypes.data_as(ctypes.c_void_p),
                                h1e_b.ctypes.data_as(ctypes.c_void_p),
                                g2e_aa.ctypes.data_as(ctypes.c_void_p),
                                g2e_ab.ctypes.data_as(ctypes.c_void_p),
                                g2e_bb.ctypes.data_as(ctypes.c_void_p),
                                stra.ctypes.data_as(ctypes.c_void_p),
                                strb.ctypes.data_as(ctypes.c_void_p),
                                ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i,i] = hdiag[addr[i]]
    h0 = lib.hermi_triu(h0)
    return addr, h0
Ejemplo n.º 50
0
def to_fci(cisdvec, norb, nelec):
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    nocc = neleca
    nvir = norb - nocc
    c0 = cisdvec[0]
    c1 = cisdvec[1:nocc * nvir + 1].reshape(nocc, nvir)
    c2 = cisdvec[nocc * nvir + 1:].reshape(nocc, nocc, nvir, nvir)
    t1addr, t1sign = t1strs(norb, nocc)

    na = cistring.num_strings(norb, nocc)
    fcivec = numpy.zeros((na, na))
    fcivec[0, 0] = c0
    c1 = c1[::-1].T.ravel()
    fcivec[0, t1addr] = fcivec[t1addr, 0] = c1 * t1sign
    c2ab = c2[::-1, ::-1].transpose(2, 0, 3, 1).reshape(nocc * nvir, -1)
    c2ab = numpy.einsum('i,j,ij->ij', t1sign, t1sign, c2ab)
    lib.takebak_2d(fcivec, c2ab, t1addr, t1addr)

    if nocc > 1 and nvir > 1:
        hf_str = int('1' * nocc, 2)
        for a in range(nocc, norb):
            for b in range(nocc, a):
                for i in reversed(range(1, nocc)):
                    for j in reversed(range(i)):
                        c2aa = c2[i, j, a - nocc,
                                  b - nocc] - c2[j, i, a - nocc, b - nocc]
                        str1 = hf_str ^ (1 << j) | (1 << b)
                        c2aa *= cistring.cre_des_sign(b, j, hf_str)
                        c2aa *= cistring.cre_des_sign(a, i, str1)
                        str1 ^= (1 << i) | (1 << a)
                        addr = cistring.str2addr(norb, nocc, str1)
                        fcivec[0, addr] = fcivec[addr, 0] = c2aa
    return fcivec
Ejemplo n.º 51
0
def pspace(h1e, eri, norb, nelec, hdiag, np=400):
    '''pspace Hamiltonian to improve Davidson preconditioner. See, CPL, 169, 463
    '''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
    h1e = numpy.ascontiguousarray(h1e)
    eri = pyscf.ao2mo.restore(1, eri, norb)
    nb = cistring.num_strings(norb, nelecb)
    if hdiag.size < np:
        addr = numpy.arange(hdiag.size)
    else:
        try:
            addr = numpy.argpartition(hdiag, np - 1)[:np]
        except AttributeError:
            addr = numpy.argsort(hdiag)[:np]
    addra, addrb = divmod(addr, nb)
    stra = numpy.array([cistring.addr2str(norb, neleca, ia) for ia in addra],
                       dtype=numpy.uint64)
    strb = numpy.array([cistring.addr2str(norb, nelecb, ib) for ib in addrb],
                       dtype=numpy.uint64)
    np = len(addr)
    h0 = numpy.zeros((np, np))
    libfci.FCIpspace_h0tril(h0.ctypes.data_as(ctypes.c_void_p),
                            h1e.ctypes.data_as(ctypes.c_void_p),
                            eri.ctypes.data_as(ctypes.c_void_p),
                            stra.ctypes.data_as(ctypes.c_void_p),
                            strb.ctypes.data_as(ctypes.c_void_p),
                            ctypes.c_int(norb), ctypes.c_int(np))

    for i in range(np):
        h0[i, i] = hdiag[addr[i]]
    h0 = pyscf.lib.hermi_triu(h0)
    return addr, h0
Ejemplo n.º 52
0
def symm_initguess(norb, nelec, orbsym, wfnsym=0, irrep_nelec=None):
    '''Generate CI wavefunction initial guess which has the given symmetry.

    Args:
        norb : int
            Number of orbitals.
        nelec : int or 2-item list
            Number of electrons, or 2-item list for (alpha, beta) electrons
        orbsym : list of int
            The irrep ID for each orbital.

    Kwags:
        wfnsym : int
            The irrep ID of target symmetry
        irrep_nelec : dict
            Freeze occupancy for certain irreps

    Returns:
        CI coefficients 2D array which has the target symmetry.
    '''
    neleca, nelecb = _unpack(nelec)
    orbsym = numpy.asarray(orbsym)
    if not isinstance(orbsym[0], numpy.number):
        raise RuntimeError('TODO: convert irrep symbol to irrep id')

    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    ci1 = numpy.zeros((na, nb))

    ########################
    # pass 1: The fixed occs
    orbleft = numpy.ones(norb, dtype=bool)
    stra = numpy.zeros(norb, dtype=bool)
    strb = numpy.zeros(norb, dtype=bool)
    if irrep_nelec is not None:
        for k, n in irrep_nelec.items():
            orbleft[orbsym == k] = False
            if isinstance(n, (int, numpy.number)):
                idx = numpy.where(orbsym == k)[0][:n // 2]
                stra[idx] = True
                strb[idx] = True
            else:
                na, nb = n
                stra[numpy.where(orbsym == k)[0][:na]] = True
                strb[numpy.where(orbsym == k)[0][:nb]] = True
                if (na - nb) % 2:
                    wfnsym ^= k

    orbleft = numpy.where(orbleft)[0]
    neleca_left = neleca - stra.sum()
    nelecb_left = nelecb - strb.sum()
    spin = neleca_left - nelecb_left
    assert (neleca_left >= 0)
    assert (nelecb_left >= 0)
    assert (spin >= 0)

    ########################
    # pass 2: search pattern
    def gen_str_iter(orb_list, nelec):
        if nelec == 1:
            for i in orb_list:
                yield [i]
        elif nelec >= len(orb_list):
            yield orb_list
        else:
            restorb = orb_list[1:]
            #yield from gen_str_iter(restorb, nelec)
            for x in gen_str_iter(restorb, nelec):
                yield x
            for x in gen_str_iter(restorb, nelec - 1):
                yield [orb_list[0]] + x

# search for alpha and beta pattern which match to the required symmetry

    def query(target, nelec_atmost, spin, orbsym):
        norb = len(orbsym)
        for excite_level in range(1, nelec_atmost + 1):
            for beta_only in gen_str_iter(range(norb), excite_level):
                alpha_allow = [i for i in range(norb) if i not in beta_only]
                alpha_orbsym = orbsym[alpha_allow]
                alpha_target = target
                for i in beta_only:
                    alpha_target ^= orbsym[i]
                alpha_only = symm.route(alpha_target, spin + excite_level,
                                        alpha_orbsym)
                if alpha_only:
                    alpha_only = [alpha_allow[i] for i in alpha_only]
                    return alpha_only, beta_only
        raise RuntimeError('No pattern found for wfn irrep %s over orbsym %s' %
                           (target, orbsym))

    if spin == 0:
        aonly = bonly = []
        if wfnsym != 0:
            aonly, bonly = query(wfnsym, neleca_left, spin, orbsym[orbleft])
    else:
        # 1. assume "nelecb_left" doubly occupied orbitals
        # search for alpha pattern which match to the required symmetry
        aonly, bonly = orbleft[symm.route(wfnsym, spin, orbsym[orbleft])], []
        # dcompose doubly occupied orbitals, search for alpha and beta pattern
        if len(aonly) != spin:
            aonly, bonly = query(wfnsym, neleca_left, spin, orbsym[orbleft])

    ndocc = neleca_left - len(aonly)  # == nelecb_left - len(bonly)
    docc_allow = numpy.ones(len(orbleft), dtype=bool)
    docc_allow[aonly] = False
    docc_allow[bonly] = False
    docclst = orbleft[numpy.where(docc_allow)[0]][:ndocc]
    stra[docclst] = True
    strb[docclst] = True

    def find_addr_(stra, aonly, nelec):
        stra[orbleft[aonly]] = True
        return cistring.str2addr(norb, nelec,
                                 ('%i' * norb) % tuple(stra)[::-1])

    if bonly:
        if spin > 0:
            aonly, socc_only = aonly[:-spin], aonly[-spin:]
            stra[orbleft[socc_only]] = True
        stra1 = stra.copy()
        strb1 = strb.copy()

        addra = find_addr_(stra, aonly, neleca)
        addrb = find_addr_(strb, bonly, nelecb)
        addra1 = find_addr_(stra1, bonly, neleca)
        addrb1 = find_addr_(strb1, aonly, nelecb)
        ci1[addra, addrb] = ci1[addra1, addrb1] = numpy.sqrt(.5)
    else:
        addra = find_addr_(stra, aonly, neleca)
        addrb = find_addr_(strb, bonly, nelecb)
        ci1[addra, addrb] = 1


#    target = 0
#    for i,k in enumerate(stra):
#        if k:
#            target ^= orbsym[i]
#    for i,k in enumerate(strb):
#        if k:
#            target ^= orbsym[i]
#    print target
    return ci1
Ejemplo n.º 53
0
def make_shape(nsite, nelec, nphonon):
    neleca, nelecb = _unpack_nelec(nelec)
    na = cistring.num_strings(nsite, neleca)
    nb = cistring.num_strings(nsite, nelecb)
    return (na, nb) + (nphonon + 1, ) * nsite
Ejemplo n.º 54
0
        return self.link_index[(norb, nelec)]


if __name__ == '__main__':
    from functools import reduce
    from pyscf import gto
    from pyscf import scf
    from pyscf.fci import direct_spin1

    def contract_2e_ref(eri, fcivec, norb, nelec, *args, **kwargs):
        hc = direct_spin1.contract_2e(eri, numpy.diag(fcivec), norb, nelec)
        return hc.diagonal()

    norb = 6
    nelec = 3
    na = cistring.num_strings(norb, nelec)
    numpy.random.seed(2)
    eri = numpy.random.random((norb, ) * 4)
    eri = ao2mo.restore(1, ao2mo.restore(8, eri, norb), norb)
    ci0 = numpy.random.random(na)
    ci0 *= 1. / numpy.linalg.norm(ci0)
    ci1 = contract_2e(eri, ci0, norb, (nelec, nelec))
    ci1ref = contract_2e_ref(eri, ci0, norb, (nelec, nelec))
    print(abs(ci1 - ci1ref).max())

    dm1, dm2 = make_rdm12(ci0, norb, (nelec, nelec), reorder=False)
    print(numpy.einsum('ijkl,ijkl', dm2, eri) - ci1.dot(ci0))
    print(abs(dm1 - make_rdm1(ci0, norb, (nelec, nelec))).max())

    mol = gto.Mole()
    mol.verbose = 0
Ejemplo n.º 55
0
    ss = spin_square(ci0, norb, nelec)
    print(ss)
    ss = spin_square0(ci0, norb, nelec)
    print(ss)
    ss = local_spin(ci0, norb, nelec, m.mo_coeff, m.get_ovlp(), range(5))
    print('local spin for H1..H5 = 0.998988389', ss[0])
    ci1 = numpy.zeros((4, 4))
    ci1[0, 0] = 1
    print(spin_square(ci1, 4, (3, 1)))
    print(spin_square0(ci1, 4, (3, 1)))

    print(numpy.einsum('ij,ij->', ci1, contract_ss(ci1, 4, (3, 1))),
          spin_square(ci1, 4, (3, 1))[0])

    numpy.random.seed(1)
    n = cistring.num_strings(6, 3)
    ci0 = numpy.random.random((n, n))
    print(numpy.einsum('ij,ij->', ci0, contract_ss(ci0, 6, 6)),
          spin_square(ci0, 6, 6)[0])

    na = cistring.num_strings(6, 4)
    nb = cistring.num_strings(6, 2)
    ci0 = numpy.random.random((na, nb))
    print(numpy.einsum('ij,ij->', ci0, contract_ss(ci0, 6, (4, 2))),
          spin_square(ci0, 6, (4, 2))[0])

    print('----------')

    mol = gto.Mole()
    mol.verbose = 0
    mol.output = None
Ejemplo n.º 56
0
def contract_ss(fcivec, norb, nelec):
    '''Contract spin square operator with FCI wavefunction :math:`S^2 |CI>`
    '''
    neleca, nelecb = _unpack_nelec(nelec)
    na = cistring.num_strings(norb, neleca)
    nb = cistring.num_strings(norb, nelecb)
    fcivec = fcivec.reshape(na, nb)

    def gen_map(fstr_index, nelec, des=True):
        a_index = fstr_index(range(norb), nelec)
        amap = numpy.zeros((a_index.shape[0], norb, 2), dtype=numpy.int32)
        if des:
            for k, tab in enumerate(a_index):
                amap[k, tab[:, 1]] = tab[:, 2:]
        else:
            for k, tab in enumerate(a_index):
                amap[k, tab[:, 0]] = tab[:, 2:]
        return amap

    if neleca > 0:
        ades = gen_map(cistring.gen_des_str_index, neleca)
    else:
        ades = None

    if nelecb > 0:
        bdes = gen_map(cistring.gen_des_str_index, nelecb)
    else:
        bdes = None

    if neleca < norb:
        acre = gen_map(cistring.gen_cre_str_index, neleca, False)
    else:
        acre = None

    if nelecb < norb:
        bcre = gen_map(cistring.gen_cre_str_index, nelecb, False)
    else:
        bcre = None

    def trans(ci1, aindex, bindex, nea, neb):
        if aindex is None or bindex is None:
            return None

        t1 = numpy.zeros(
            (cistring.num_strings(norb, nea), cistring.num_strings(norb, neb)))
        for i in range(norb):
            signa = aindex[:, i, 1]
            signb = bindex[:, i, 1]
            maska = numpy.where(signa != 0)[0]
            maskb = numpy.where(signb != 0)[0]
            addra = aindex[maska, i, 0]
            addrb = bindex[maskb, i, 0]
            citmp = lib.take_2d(fcivec, maska, maskb)
            citmp *= signa[maska].reshape(-1, 1)
            citmp *= signb[maskb]
            #: t1[addra.reshape(-1,1),addrb] += citmp
            lib.takebak_2d(t1, citmp, addra, addrb)
        for i in range(norb):
            signa = aindex[:, i, 1]
            signb = bindex[:, i, 1]
            maska = numpy.where(signa != 0)[0]
            maskb = numpy.where(signb != 0)[0]
            addra = aindex[maska, i, 0]
            addrb = bindex[maskb, i, 0]
            citmp = lib.take_2d(t1, addra, addrb)
            citmp *= signa[maska].reshape(-1, 1)
            citmp *= signb[maskb]
            #: ci1[maska.reshape(-1,1), maskb] += citmp
            lib.takebak_2d(ci1, citmp, maska, maskb)

    ci1 = numpy.zeros((na, nb))
    trans(ci1, ades, bcre, neleca - 1, nelecb + 1)  # S+*S-
    trans(ci1, acre, bdes, neleca + 1, nelecb - 1)  # S-*S+
    ci1 *= .5
    ci1 += (neleca - nelecb)**2 * .25 * fcivec
    return ci1
Ejemplo n.º 57
0
    mol.build()

    m = scf.UHF(mol)
    ehf = m.scf()

    cis = FCISolver(mol)
    norb = m.mo_energy[0].size
    nea = (mol.nelectron + 1) // 2
    neb = (mol.nelectron - 1) // 2
    nelec = (nea, neb)
    mo_a = m.mo_coeff[0]
    mo_b = m.mo_coeff[1]
    h1e_a = reduce(numpy.dot, (mo_a.T, m.get_hcore(), mo_a))
    h1e_b = reduce(numpy.dot, (mo_b.T, m.get_hcore(), mo_b))
    g2e_aa = ao2mo.incore.general(m._eri, (mo_a, ) * 4, compact=False)
    g2e_aa = g2e_aa.reshape(norb, norb, norb, norb)
    g2e_ab = ao2mo.incore.general(m._eri, (mo_a, mo_a, mo_b, mo_b),
                                  compact=False)
    g2e_ab = g2e_ab.reshape(norb, norb, norb, norb)
    g2e_bb = ao2mo.incore.general(m._eri, (mo_b, ) * 4, compact=False)
    g2e_bb = g2e_bb.reshape(norb, norb, norb, norb)
    h1e = (h1e_a, h1e_b)
    eri = (g2e_aa, g2e_ab, g2e_bb)
    na = cistring.num_strings(norb, nea)
    nb = cistring.num_strings(norb, neb)
    numpy.random.seed(15)
    fcivec = numpy.random.random((na, nb))

    e = kernel(h1e, eri, norb, nelec)[0]
    print(e, e - -8.65159903476)
Ejemplo n.º 58
0
    ]
    mol.basis = {
        'H': 'sto-3g',
        'O': 'sto-3g',
    }
    mol.symmetry = 1
    mol.build()
    m = scf.RHF(mol)
    ehf = m.scf()

    norb = m.mo_coeff.shape[1]
    nelec = mol.nelectron - 1
    h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff))
    eri = ao2mo.incore.full(m._eri, m.mo_coeff)
    numpy.random.seed(1)
    na = cistring.num_strings(norb, nelec // 2 + 1)
    nb = cistring.num_strings(norb, nelec // 2)
    fcivec = numpy.random.random((na, nb))

    orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff)
    cis = FCISolver(mol)
    cis.orbsym = orbsym
    fcivec = addons.symmetrize_wfn(fcivec, norb, nelec, cis.orbsym, wfnsym=0)

    ci1 = cis.contract_2e(eri,
                          fcivec,
                          norb,
                          nelec,
                          orbsym=cis.orbsym,
                          wfnsym=0)
    ci1ref = direct_spin1.contract_2e(eri, fcivec, norb, nelec)
Ejemplo n.º 59
0
def to_fcivec(cisdvec, norb, nelec, frozen=0):
    '''Convert CISD coefficients to FCI coefficients'''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

    frozena_mask = numpy.zeros(norb, dtype=bool)
    frozenb_mask = numpy.zeros(norb, dtype=bool)
    if isinstance(frozen, (int, numpy.integer)):
        nfroza = nfrozb = frozen
        frozena_mask[:frozen] = True
        frozenb_mask[:frozen] = True
    else:
        nfroza = len(frozen[0])
        nfrozb = len(frozen[1])
        frozena_mask[frozen[0]] = True
        frozenb_mask[frozen[1]] = True

#    if nfroza != nfrozb:
#        raise NotImplementedError
    nocca = numpy.count_nonzero(~frozena_mask[:neleca])
    noccb = numpy.count_nonzero(~frozenb_mask[:nelecb])
    nmo = nmoa, nmob = norb - nfroza, norb - nfrozb
    nocc = nocca, noccb
    nvira, nvirb = nmoa - nocca, nmob - noccb

    c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nmo, nocc)
    c1a, c1b = c1
    c2aa, c2ab, c2bb = c2
    t1addra, t1signa = cisd.tn_addrs_signs(nmoa, nocca, 1)
    t1addrb, t1signb = cisd.tn_addrs_signs(nmob, noccb, 1)

    na = cistring.num_strings(nmoa, nocca)
    nb = cistring.num_strings(nmob, noccb)
    fcivec = numpy.zeros((na,nb))
    fcivec[0,0] = c0
    fcivec[t1addra,0] = c1a.ravel() * t1signa
    fcivec[0,t1addrb] = c1b.ravel() * t1signb
    c2ab = c2ab.transpose(0,2,1,3).reshape(nocca*nvira,-1)
    c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, c2ab)
    fcivec[t1addra[:,None],t1addrb] = c2ab

    if nocca > 1 and nvira > 1:
        ooidx = numpy.tril_indices(nocca, -1)
        vvidx = numpy.tril_indices(nvira, -1)
        c2aa = c2aa[ooidx][:,vvidx[0],vvidx[1]]
        t2addra, t2signa = cisd.tn_addrs_signs(nmoa, nocca, 2)
        fcivec[t2addra,0] = c2aa.ravel() * t2signa
    if noccb > 1 and nvirb > 1:
        ooidx = numpy.tril_indices(noccb, -1)
        vvidx = numpy.tril_indices(nvirb, -1)
        c2bb = c2bb[ooidx][:,vvidx[0],vvidx[1]]
        t2addrb, t2signb = cisd.tn_addrs_signs(nmob, noccb, 2)
        fcivec[0,t2addrb] = c2bb.ravel() * t2signb

    if nfroza == nfrozb == 0:
        return fcivec

    assert(norb < 63)

    strsa = cistring.gen_strings4orblist(range(norb), neleca)
    strsb = cistring.gen_strings4orblist(range(norb), nelecb)
    na = len(strsa)
    nb = len(strsb)
    count_a = numpy.zeros(na, dtype=int)
    count_b = numpy.zeros(nb, dtype=int)
    parity_a = numpy.zeros(na, dtype=bool)
    parity_b = numpy.zeros(nb, dtype=bool)
    core_a_mask = numpy.ones(na, dtype=bool)
    core_b_mask = numpy.ones(nb, dtype=bool)

    for i in range(norb):
        if frozena_mask[i]:
            if i < neleca:
                core_a_mask &= (strsa & (1<<i)) != 0
                parity_a ^= (count_a & 1) == 1
            else:
                core_a_mask &= (strsa & (1<<i)) == 0
        else:
            count_a += (strsa & (1<<i)) != 0

        if frozenb_mask[i]:
            if i < nelecb:
                core_b_mask &= (strsb & (1<<i)) != 0
                parity_b ^= (count_b & 1) == 1
            else:
                core_b_mask &= (strsb & (1<<i)) == 0
        else:
            count_b += (strsb & (1<<i)) != 0

    sub_strsa = strsa[core_a_mask & (count_a == nocca)]
    sub_strsb = strsb[core_b_mask & (count_b == noccb)]
    addrsa = cistring.strs2addr(norb, neleca, sub_strsa)
    addrsb = cistring.strs2addr(norb, nelecb, sub_strsb)
    fcivec1 = numpy.zeros((na,nb))
    fcivec1[addrsa[:,None],addrsb] = fcivec
    fcivec1[parity_a,:] *= -1
    fcivec1[:,parity_b] *= -1
    return fcivec1
Ejemplo n.º 60
0
def to_fcivec(cisdvec, norb, nelec, frozen=None):
    '''Convert CISD coefficients to FCI coefficients'''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec // 2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec
        assert (neleca == nelecb)

    frozen_mask = numpy.zeros(norb, dtype=bool)
    if frozen is None:
        nfroz = 0
    elif isinstance(frozen, (int, numpy.integer)):
        nfroz = frozen
        frozen_mask[:frozen] = True
    else:
        nfroz = len(frozen)
        frozen_mask[frozen] = True

    nocc = numpy.count_nonzero(~frozen_mask[:neleca])
    nmo = norb - nfroz
    nvir = nmo - nocc
    c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nmo, nocc)
    t1addr, t1sign = tn_addrs_signs(nmo, nocc, 1)

    na = cistring.num_strings(nmo, nocc)
    fcivec = numpy.zeros((na, na))
    fcivec[0, 0] = c0
    fcivec[0, t1addr] = fcivec[t1addr, 0] = c1.ravel() * t1sign
    c2ab = c2.transpose(0, 2, 1, 3).reshape(nocc * nvir, -1)
    c2ab = numpy.einsum('i,j,ij->ij', t1sign, t1sign, c2ab)
    fcivec[t1addr[:, None], t1addr] = c2ab

    if nocc > 1 and nvir > 1:
        c2aa = c2 - c2.transpose(1, 0, 2, 3)
        ooidx = numpy.tril_indices(nocc, -1)
        vvidx = numpy.tril_indices(nvir, -1)
        c2aa = c2aa[ooidx][:, vvidx[0], vvidx[1]]
        t2addr, t2sign = tn_addrs_signs(nmo, nocc, 2)
        fcivec[0, t2addr] = fcivec[t2addr, 0] = c2aa.ravel() * t2sign

    if nfroz == 0:
        return fcivec

    assert (norb < 63)

    strs = cistring.gen_strings4orblist(range(norb), neleca)
    na = len(strs)
    count = numpy.zeros(na, dtype=int)
    parity = numpy.zeros(na, dtype=bool)
    core_mask = numpy.ones(na, dtype=bool)
    # During the loop, count saves the number of occupied orbitals that
    # lower (with small orbital ID) than the present orbital i.
    # Moving all the frozen orbitals to the beginning of the orbital list
    # (before the occupied orbitals) leads to parity odd (= True, with
    # negative sign) or even (= False, with positive sign).
    for i in range(norb):
        if frozen_mask[i]:
            if i < neleca:
                # frozen occupied orbital should be occupied
                core_mask &= (strs & (1 << i)) != 0
                parity ^= (count & 1) == 1
            else:
                # frozen virtual orbital should not be occupied.
                # parity is not needed since it's unoccupied
                core_mask &= (strs & (1 << i)) == 0
        else:
            count += (strs & (1 << i)) != 0
    sub_strs = strs[core_mask & (count == nocc)]
    addrs = cistring.strs2addr(norb, neleca, sub_strs)
    fcivec1 = numpy.zeros((na, na))
    fcivec1[addrs[:, None], addrs] = fcivec
    fcivec1[parity, :] *= -1
    fcivec1[:, parity] *= -1
    return fcivec1