예제 #1
0
파일: addons.py 프로젝트: chrinide/pyscf
def spin2spatial(tx, orbspin):
    if tx.ndim == 2:  # t1
        nocc, nvir = tx.shape
    else:
        nocc, nvir = tx.shape[1:3]

    idxoa = numpy.where(orbspin[:nocc] == 0)[0]
    idxob = numpy.where(orbspin[:nocc] == 1)[0]
    idxva = numpy.where(orbspin[nocc:] == 0)[0]
    idxvb = numpy.where(orbspin[nocc:] == 1)[0]
    nocc_a = len(idxoa)
    nocc_b = len(idxob)
    nvir_a = len(idxva)
    nvir_b = len(idxvb)

    if tx.ndim == 2:  # t1
        t1a = lib.take_2d(tx, idxoa, idxva)
        t1b = lib.take_2d(tx, idxob, idxvb)
        return t1a, t1b
    else:
        idxoaa = idxoa[:,None] * nocc + idxoa
        idxoab = idxoa[:,None] * nocc + idxob
        idxobb = idxob[:,None] * nocc + idxob
        idxvaa = idxva[:,None] * nvir + idxva
        idxvab = idxva[:,None] * nvir + idxvb
        idxvbb = idxvb[:,None] * nvir + idxvb
        t2 = tx.reshape(nocc**2,nvir**2)
        t2aa = lib.take_2d(t2, idxoaa.ravel(), idxvaa.ravel())
        t2bb = lib.take_2d(t2, idxobb.ravel(), idxvbb.ravel())
        t2ab = lib.take_2d(t2, idxoab.ravel(), idxvab.ravel())
        t2aa = t2aa.reshape(nocc_a,nocc_a,nvir_a,nvir_a)
        t2bb = t2bb.reshape(nocc_b,nocc_b,nvir_b,nvir_b)
        t2ab = t2ab.reshape(nocc_a,nocc_b,nvir_a,nvir_b)
        return t2aa,t2ab,t2bb
예제 #2
0
파일: select_ci.py 프로젝트: eronca/pyscf
    def trans(ci1, aindex, bindex):
        if aindex is None or bindex is None:
            return None

        ma = len(aindex)
        mb = len(bindex)
        t1 = numpy.zeros((ma,mb))
        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(ci_coeff, addra, addrb)
            citmp *= signa[maska].reshape(-1,1)
            citmp *= signb[maskb]
            #: t1[addra.reshape(-1,1),addrb] += citmp
            lib.takebak_2d(t1, citmp, maska, maskb)
        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, maska, maskb)
            citmp *= signa[maska].reshape(-1,1)
            citmp *= signb[maskb]
            #: ci1[maska.reshape(-1,1), maskb] += citmp
            lib.takebak_2d(ci1, citmp, addra, addrb)
예제 #3
0
파일: spin_op.py 프로젝트: chrinide/pyscf
    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)
예제 #4
0
    def test_take_2d(self):
        a = numpy.arange(49.).reshape(7,7)
        idx = [3,0,5]
        idy = [5,4,1]
        ref = a[idx][:,idy]
        self.assertTrue(numpy.array_equal(ref, lib.take_2d(a, idx, idy)))

        a = numpy.arange(49, dtype=numpy.int32).reshape(7,7)
        ref = a[idx][:,idy]
        self.assertTrue(numpy.array_equal(ref, lib.take_2d(a, idx, idy)))
        self.assertTrue(lib.take_2d(a, idx, idy).dtype == numpy.int32)
예제 #5
0
파일: ccsd_t.py 프로젝트: chrinide/pyscf
def _sort_t2_vooo_(mycc, orbsym, t1, t2, eris):
    assert(t2.flags.c_contiguous)
    vooo = numpy.asarray(eris.ovoo).transpose(1,0,3,2).conj().copy()
    nocc, nvir = t1.shape
    if mycc.mol.symmetry:
        orbsym = numpy.asarray(orbsym, dtype=numpy.int32)
        o_sorted = _irrep_argsort(orbsym[:nocc])
        v_sorted = _irrep_argsort(orbsym[nocc:])
        mo_energy = eris.mo_energy
        mo_energy = numpy.hstack((mo_energy[:nocc][o_sorted],
                                  mo_energy[nocc:][v_sorted]))
        t1T = numpy.asarray(t1.T[v_sorted][:,o_sorted], order='C')
        fvo = eris.fock[nocc:,:nocc]
        fvo = numpy.asarray(fvo[v_sorted][:,o_sorted], order='C')

        o_sym = orbsym[o_sorted]
        oo_sym = (o_sym[:,None] ^ o_sym).ravel()
        oo_sorted = _irrep_argsort(oo_sym)
        #:vooo = eris.ovoo.transpose(1,0,2,3)
        #:vooo = vooo[v_sorted][:,o_sorted][:,:,o_sorted][:,:,:,o_sorted]
        #:vooo = vooo.reshape(nvir,-1,nocc)[:,oo_sorted]
        oo_idx = numpy.arange(nocc**2).reshape(nocc,nocc)[o_sorted][:,o_sorted]
        oo_idx = oo_idx.ravel()[oo_sorted]
        oo_idx = (oo_idx[:,None]*nocc+o_sorted).ravel()
        vooo = lib.take_2d(vooo.reshape(nvir,-1), v_sorted, oo_idx)
        vooo = vooo.reshape(nvir,nocc,nocc,nocc)

        #:t2T = t2.transpose(2,3,1,0)
        #:t2T = ref_t2T[v_sorted][:,v_sorted][:,:,o_sorted][:,:,:,o_sorted]
        #:t2T = ref_t2T.reshape(nvir,nvir,-1)[:,:,oo_sorted]
        t2T = lib.transpose(t2.reshape(nocc**2,-1))
        oo_idx = numpy.arange(nocc**2).reshape(nocc,nocc).T[o_sorted][:,o_sorted]
        oo_idx = oo_idx.ravel()[oo_sorted]
        vv_idx = (v_sorted[:,None]*nvir+v_sorted).ravel()
        t2T = lib.take_2d(t2T.reshape(nvir**2,nocc**2), vv_idx, oo_idx, out=t2)
        t2T = t2T.reshape(nvir,nvir,nocc,nocc)
        def restore_t2_inplace(t2T):
            tmp = numpy.zeros((nvir**2,nocc**2), dtype=t2T.dtype)
            lib.takebak_2d(tmp, t2T.reshape(nvir**2,nocc**2), vv_idx, oo_idx)
            t2 = lib.transpose(tmp.reshape(nvir**2,nocc**2), out=t2T)
            return t2.reshape(nocc,nocc,nvir,nvir)
    else:
        fvo = eris.fock[nocc:,:nocc].copy()
        t1T = t1.T.copy()
        t2T = lib.transpose(t2.reshape(nocc**2,nvir**2))
        t2T = lib.transpose(t2T.reshape(nvir**2,nocc,nocc), axes=(0,2,1), out=t2)
        mo_energy = numpy.asarray(eris.mo_energy, order='C')
        def restore_t2_inplace(t2T):
            tmp = lib.transpose(t2T.reshape(nvir**2,nocc,nocc), axes=(0,2,1))
            t2 = lib.transpose(tmp.reshape(nvir**2,nocc**2), out=t2T)
            return t2.reshape(nocc,nocc,nvir,nvir)
    t2T = t2T.reshape(nvir,nvir,nocc,nocc)
    return mo_energy, t1T, t2T, vooo, fvo, restore_t2_inplace
예제 #6
0
파일: gcisd.py 프로젝트: chrinide/pyscf
def amplitudes_to_cisdvec(c0, c1, c2):
    nocc, nvir = c1.shape
    ooidx = numpy.tril_indices(nocc, -1)
    vvidx = numpy.tril_indices(nvir, -1)
    c2tril = lib.take_2d(c2.reshape(nocc**2,nvir**2),
                         ooidx[0]*nocc+ooidx[1], vvidx[0]*nvir+vvidx[1])
    return numpy.hstack((c0, c1.ravel(), c2tril.ravel()))
예제 #7
0
def reorder_eri(eri, norb, orbsym):
    if orbsym is None:
        return [eri], numpy.arange(norb), numpy.zeros(norb,dtype=numpy.int32)
# map irrep IDs of Dooh or Coov to D2h, C2v
# see symm.basis.linearmole_symm_descent
    orbsym = numpy.asarray(orbsym) % 10
# irrep of (ij| pair
    trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb)]
# and the number of occurence for each irrep
    dimirrep = numpy.asarray(numpy.bincount(trilirrep), dtype=numpy.int32)
# we sort the irreps of (ij| pair, to group the pairs which have same irreps
# "order" is irrep-id-sorted index. The (ij| paired is ordered that the
# pair-id given by order[0] comes first in the sorted pair
# "rank" is a sorted "order". Given nth (ij| pair, it returns the place(rank)
# of the sorted pair
    old_eri_irrep = numpy.asarray(trilirrep, dtype=numpy.int32)
    rank_in_irrep = numpy.empty_like(old_eri_irrep)
    p0 = 0
    eri_irs = [numpy.zeros((0,0))] * TOTIRREPS
    for ir, nnorb in enumerate(dimirrep):
        idx = numpy.asarray(numpy.where(trilirrep == ir)[0], dtype=numpy.int32)
        rank_in_irrep[idx] = numpy.arange(nnorb, dtype=numpy.int32)
        eri_irs[ir] = lib.take_2d(eri, idx, idx)
        p0 += nnorb
    return eri_irs, rank_in_irrep, old_eri_irrep
예제 #8
0
파일: select_ci.py 프로젝트: eronca/pyscf
def contract_2e(eri, civec_strs, norb, nelec, link_index=None):
    ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec)
    if link_index is None:
        link_index = _all_linkstr_index(ci_strs, norb, nelec)
    cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index
    na, nlinka = cd_indexa.shape[:2]
    nb, nlinkb = cd_indexb.shape[:2]

    eri = ao2mo.restore(1, eri, norb)
    eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1)
    idx,idy = numpy.tril_indices(norb, -1)
    idx = idx * norb + idy
    eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2
    fcivec = ci_coeff.reshape(na,nb)
    # (bb|bb)
    if nelec[1] > 1:
        mb, mlinkb = dd_indexb.shape[:2]
        fcivecT = lib.transpose(fcivec)
        ci1T = numpy.zeros((nb,na))
        libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p),
                                   fcivecT.ctypes.data_as(ctypes.c_void_p),
                                   ci1T.ctypes.data_as(ctypes.c_void_p),
                                   ctypes.c_int(norb),
                                   ctypes.c_int(nb), ctypes.c_int(na),
                                   ctypes.c_int(mb), ctypes.c_int(mlinkb),
                                   dd_indexb.ctypes.data_as(ctypes.c_void_p))
        ci1 = lib.transpose(ci1T, out=fcivecT)
    else:
        ci1 = numpy.zeros_like(fcivec)
    # (aa|aa)
    if nelec[0] > 1:
        ma, mlinka = dd_indexa.shape[:2]
        libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p),
                                   fcivec.ctypes.data_as(ctypes.c_void_p),
                                   ci1.ctypes.data_as(ctypes.c_void_p),
                                   ctypes.c_int(norb),
                                   ctypes.c_int(na), ctypes.c_int(nb),
                                   ctypes.c_int(ma), ctypes.c_int(mlinka),
                                   dd_indexa.ctypes.data_as(ctypes.c_void_p))

    h_ps = numpy.einsum('pqqs->ps', eri)
    eri1 = eri * 2
    for k in range(norb):
        eri1[:,:,k,k] += h_ps/nelec[0]
        eri1[k,k,:,:] += h_ps/nelec[1]
    eri1 = ao2mo.restore(4, eri1, norb)
    # (bb|aa)
    libfci.SCIcontract_2e_bbaa(eri1.ctypes.data_as(ctypes.c_void_p),
                               fcivec.ctypes.data_as(ctypes.c_void_p),
                               ci1.ctypes.data_as(ctypes.c_void_p),
                               ctypes.c_int(norb),
                               ctypes.c_int(na), ctypes.c_int(nb),
                               ctypes.c_int(nlinka), ctypes.c_int(nlinkb),
                               cd_indexa.ctypes.data_as(ctypes.c_void_p),
                               cd_indexb.ctypes.data_as(ctypes.c_void_p))

    return _as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
예제 #9
0
파일: select_ci.py 프로젝트: eronca/pyscf
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)
예제 #10
0
파일: rccsd.py 프로젝트: chrinide/pyscf
def _make_eris_outcore(mycc, mo_coeff=None):
    cput0 = (time.clock(), time.time())
    log = logger.Logger(mycc.stdout, mycc.verbose)
    eris = _ChemistsERIs()
    eris._common_init_(mycc, mo_coeff)

    mol = mycc.mol
    mo_coeff = eris.mo_coeff
    nocc = eris.nocc
    nao, nmo = mo_coeff.shape
    nvir = nmo - nocc
    orbo = mo_coeff[:,:nocc]
    orbv = mo_coeff[:,nocc:]
    nvpair = nvir * (nvir+1) // 2
    eris.feri1 = lib.H5TmpFile()
    eris.oooo = eris.feri1.create_dataset('oooo', (nocc,nocc,nocc,nocc), 'f8')
    eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc,nvir,nocc,nocc), 'f8', chunks=(nocc,1,nocc,nocc))
    eris.ovov = eris.feri1.create_dataset('ovov', (nocc,nvir,nocc,nvir), 'f8', chunks=(nocc,1,nocc,nvir))
    eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc,nvir,nvir,nocc), 'f8', chunks=(nocc,1,nvir,nocc))
    eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc,nvir,nvir,nvir), 'f8')
    eris.oovv = eris.feri1.create_dataset('oovv', (nocc,nocc,nvir,nvir), 'f8', chunks=(nocc,nocc,1,nvir))
    eris.vvvv = eris.feri1.create_dataset('vvvv', (nvir,nvir,nvir,nvir), 'f8')
    max_memory = max(MEMORYMIN, mycc.max_memory-lib.current_memory()[0])

    ftmp = lib.H5TmpFile()
    ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log)
    eri = ftmp['eri_mo']

    nocc_pair = nocc*(nocc+1)//2
    tril2sq = lib.square_mat_in_trilu_indices(nmo)
    oo = eri[:nocc_pair]
    eris.oooo[:] = ao2mo.restore(1, oo[:,:nocc_pair], nocc)
    oovv = lib.take_2d(oo, tril2sq[:nocc,:nocc].ravel(), tril2sq[nocc:,nocc:].ravel())
    eris.oovv[:] = oovv.reshape(nocc,nocc,nvir,nvir)
    oo = oovv = None

    tril2sq = lib.square_mat_in_trilu_indices(nmo)
    blksize = min(nvir, max(BLKMIN, int(max_memory*1e6/8/nmo**3/2)))
    for p0, p1 in lib.prange(0, nvir, blksize):
        q0, q1 = p0+nocc, p1+nocc
        off0 = q0*(q0+1)//2
        off1 = q1*(q1+1)//2
        buf = lib.unpack_tril(eri[off0:off1])

        tmp = buf[ tril2sq[q0:q1,:nocc] - off0 ]
        eris.ovoo[:,p0:p1] = tmp[:,:,:nocc,:nocc].transpose(1,0,2,3)
        eris.ovvo[:,p0:p1] = tmp[:,:,nocc:,:nocc].transpose(1,0,2,3)
        eris.ovov[:,p0:p1] = tmp[:,:,:nocc,nocc:].transpose(1,0,2,3)
        eris.ovvv[:,p0:p1] = tmp[:,:,nocc:,nocc:].transpose(1,0,2,3)

        tmp = buf[ tril2sq[q0:q1,nocc:q1] - off0 ]
        eris.vvvv[p0:p1,:p1] = tmp[:,:,nocc:,nocc:]
        if p0 > 0:
            eris.vvvv[:p0,p0:p1] = tmp[:,:p0,nocc:,nocc:].transpose(1,0,2,3)
        buf = tmp = None
    log.timer('CCSD integral transformation', *cput0)
    return eris
예제 #11
0
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0):
    if orbsym is None:
        return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = direct_spin1._unpack_nelec(nelec)
    assert(neleca == nelecb)
    link_indexa = direct_spin0._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    eri_irs, rank_eri, irrep_eri = direct_spin1_symm.reorder_eri(eri, norb, orbsym)
    totirrep = len(eri_irs)

    strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca))
    aidx, link_indexa = direct_spin1_symm.gen_str_irrep(strsa, orbsym, link_indexa,
                                                        rank_eri, irrep_eri, totirrep)

    Tirrep = ctypes.c_void_p*totirrep
    linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int*totirrep)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na,na), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int*8)(*[x.size for x in aidx])

    ci0 = []
    ci1 = []
    for ir in range(totirrep):
        ma, mb = aidx[ir].size, aidx[wfnsym^ir].size
        ci0.append(numpy.zeros((ma,mb)))
        ci1.append(numpy.zeros((ma,mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], aidx[wfnsym^ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nas,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinka),
                                linka_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(totirrep), ctypes.c_int(wfnsym))
    for ir in range(totirrep):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], aidx[wfnsym^ir])
    return lib.transpose_sum(ci1new, inplace=True).reshape(fcivec_shape)
예제 #12
0
파일: kccsd.py 프로젝트: chrinide/pyscf
def spin2spatial(tx, orbspin, kconserv):
    if tx.ndim == 3:  # t1
        nocc, nvir = tx.shape[1:]
    else:
        nocc, nvir = tx.shape[4:6]
    nkpts = len(tx)

    idxoa = [numpy.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)]
    idxob = [numpy.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)]
    idxva = [numpy.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)]
    idxvb = [numpy.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)]
    nocc_a = len(idxoa[0])
    nocc_b = len(idxob[0])
    nvir_a = len(idxva[0])
    nvir_b = len(idxvb[0])

    if tx.ndim == 3:  # t1
        t1a = numpy.zeros((nkpts,nocc_a,nvir_a), dtype=tx.dtype)
        t1b = numpy.zeros((nkpts,nocc_b,nvir_b), dtype=tx.dtype)
        for k in range(nkpts):
            lib.take_2d(tx[k], idxoa[k], idxva[k], out=t1a[k])
            lib.take_2d(tx[k], idxob[k], idxvb[k], out=t1b[k])
        return t1a, t1b

    else:
        t2aa = numpy.zeros((nkpts,nkpts,nkpts,nocc_a,nocc_a,nvir_a,nvir_a), dtype=tx.dtype)
        t2ab = numpy.zeros((nkpts,nkpts,nkpts,nocc_a,nocc_b,nvir_a,nvir_b), dtype=tx.dtype)
        t2bb = numpy.zeros((nkpts,nkpts,nkpts,nocc_b,nocc_b,nvir_b,nvir_b), dtype=tx.dtype)
        t2 = tx.reshape(nkpts,nkpts,nkpts,nocc**2,nvir**2)
        for ki, kj, ka in kpts_helper.loop_kkk(nkpts):
            kb = kconserv[ki,ka,kj]
            idxoaa = idxoa[ki][:,None] * nocc + idxoa[kj]
            idxoab = idxoa[ki][:,None] * nocc + idxob[kj]
            idxobb = idxob[ki][:,None] * nocc + idxob[kj]
            idxvaa = idxva[ka][:,None] * nvir + idxva[kb]
            idxvab = idxva[ka][:,None] * nvir + idxvb[kb]
            idxvbb = idxvb[ka][:,None] * nvir + idxvb[kb]
            lib.take_2d(t2[ki,kj,ka], idxoaa.ravel(), idxvaa.ravel(), out=t2aa[ki,kj,ka])
            lib.take_2d(t2[ki,kj,ka], idxobb.ravel(), idxvbb.ravel(), out=t2bb[ki,kj,ka])
            lib.take_2d(t2[ki,kj,ka], idxoab.ravel(), idxvab.ravel(), out=t2ab[ki,kj,ka])
        return t2aa, t2ab, t2bb
예제 #13
0
def reorder4irrep_minors(eri, norb, link_index, orbsym):
    if orbsym is None:
        return eri, link_index, numpy.array(norb, dtype=numpy.int32)
    orbsym = numpy.asarray(orbsym) % 10
    trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb,-1)]
    dimirrep = numpy.array(numpy.bincount(trilirrep), dtype=numpy.int32)
    order = numpy.argsort(trilirrep)
    rank = order.argsort()
    eri = lib.take_2d(eri, order, order)
    link_index_irrep = link_index.copy()
    link_index_irrep[:,:,0] = rank[link_index[:,:,0]]
    return numpy.asarray(eri, order='C'), link_index_irrep, dimirrep
예제 #14
0
def contract_2e(eri, civec_strs, norb, nelec, link_index=None, orbsym=None):
    ci_coeff, nelec, ci_strs = selected_ci._unpack(civec_strs, nelec)
    if link_index is None:
        link_index = selected_ci._all_linkstr_index(ci_strs, norb, nelec)
    cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index
    na, nlinka = nb, nlinkb = cd_indexa.shape[:2]

    eri = ao2mo.restore(1, eri, norb)
    eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1)
    idx,idy = numpy.tril_indices(norb, -1)
    idx = idx * norb + idy
    eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2
    lib.transpose_sum(eri1, inplace=True)
    eri1 *= .5
    eri1, dd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, dd_indexa, orbsym, -1)
    fcivec = ci_coeff.reshape(na,nb)
    ci1 = numpy.zeros_like(fcivec)
    # (aa|aa)
    if nelec[0] > 1:
        ma, mlinka = mb, mlinkb = dd_indexa.shape[:2]
        libfci.SCIcontract_2e_aaaa_symm(eri1.ctypes.data_as(ctypes.c_void_p),
                                        fcivec.ctypes.data_as(ctypes.c_void_p),
                                        ci1.ctypes.data_as(ctypes.c_void_p),
                                        ctypes.c_int(norb),
                                        ctypes.c_int(na), ctypes.c_int(nb),
                                        ctypes.c_int(ma), ctypes.c_int(mlinka),
                                        dd_indexa.ctypes.data_as(ctypes.c_void_p),
                                        dimirrep.ctypes.data_as(ctypes.c_void_p),
                                        ctypes.c_int(len(dimirrep)))

    h_ps = numpy.einsum('pqqs->ps', eri) * (.5/nelec[0])
    eri1 = eri.copy()
    for k in range(norb):
        eri1[:,:,k,k] += h_ps
        eri1[k,k,:,:] += h_ps
    eri1 = ao2mo.restore(4, eri1, norb)
    lib.transpose_sum(eri1, inplace=True)
    eri1 *= .5
    eri1, cd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, cd_indexa, orbsym)
    # (bb|aa)
    libfci.SCIcontract_2e_bbaa_symm(eri1.ctypes.data_as(ctypes.c_void_p),
                                    fcivec.ctypes.data_as(ctypes.c_void_p),
                                    ci1.ctypes.data_as(ctypes.c_void_p),
                                    ctypes.c_int(norb),
                                    ctypes.c_int(na), ctypes.c_int(nb),
                                    ctypes.c_int(nlinka), ctypes.c_int(nlinkb),
                                    cd_indexa.ctypes.data_as(ctypes.c_void_p),
                                    cd_indexa.ctypes.data_as(ctypes.c_void_p),
                                    dimirrep.ctypes.data_as(ctypes.c_void_p),
                                    ctypes.c_int(len(dimirrep)))

    lib.transpose_sum(ci1, inplace=True)
    return selected_ci._as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
예제 #15
0
def spin2spatial_ip_doublet(r1, r2, kconserv, kshift, orbspin):
    '''Convert R1/R2 of spin orbital representation to R1/R2 of
    spatial orbital representation '''
    nkpts, nocc, nvir = np.array(r2.shape)[[1, 3, 4]]

    idxoa = [np.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)]
    idxob = [np.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)]
    idxva = [np.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)]
    idxvb = [np.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)]
    nocc_a = len(idxoa[0])  # Assume nocc/nvir same for each k-point
    nocc_b = len(idxob[0])
    nvir_a = len(idxva[0])
    nvir_b = len(idxvb[0])

    r1a = r1[idxoa[kshift]]
    r1b = r1[idxob[kshift]]

    r2aaa = np.zeros((nkpts,nkpts,nocc_a,nocc_a,nvir_a), dtype=r2.dtype)
    r2baa = np.zeros((nkpts,nkpts,nocc_b,nocc_a,nvir_a), dtype=r2.dtype)
    r2abb = np.zeros((nkpts,nkpts,nocc_a,nocc_b,nvir_b), dtype=r2.dtype)
    r2bbb = np.zeros((nkpts,nkpts,nocc_b,nocc_b,nvir_b), dtype=r2.dtype)
    for ki, kj in itertools.product(range(nkpts), repeat=2):
        ka = kconserv[ki, kshift, kj]
        idxoaa = idxoa[ki][:,None] * nocc + idxoa[kj]
        idxoab = idxoa[ki][:,None] * nocc + idxob[kj]
        idxoba = idxob[ki][:,None] * nocc + idxoa[kj]
        idxobb = idxob[ki][:,None] * nocc + idxob[kj]

        r2_tmp = r2[ki, kj].reshape(nocc**2, nvir)
        r2aaa_tmp = lib.take_2d(r2_tmp, idxoaa.ravel(), idxva[ka])
        r2baa_tmp = lib.take_2d(r2_tmp, idxoba.ravel(), idxva[ka])
        r2abb_tmp = lib.take_2d(r2_tmp, idxoab.ravel(), idxvb[ka])
        r2bbb_tmp = lib.take_2d(r2_tmp, idxobb.ravel(), idxvb[ka])

        r2aaa[ki, kj] = r2aaa_tmp.reshape(nocc_a, nocc_a, nvir_a)
        r2baa[ki, kj] = r2baa_tmp.reshape(nocc_b, nocc_a, nvir_a)
        r2abb[ki, kj] = r2abb_tmp.reshape(nocc_a, nocc_b, nvir_b)
        r2bbb[ki, kj] = r2bbb_tmp.reshape(nocc_b, nocc_b, nvir_b)
    return [r1a, r1b], [r2aaa, r2baa, r2abb, r2bbb]
예제 #16
0
def spin2spatial_ea_doublet(r1, r2, kconserv, kshift, orbspin):
    '''Convert R1/R2 of spin orbital representation to R1/R2 of
    spatial orbital representation'''
    nkpts, nocc, nvir = np.array(r2.shape)[[1, 2, 3]]

    idxoa = [np.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)]
    idxob = [np.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)]
    idxva = [np.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)]
    idxvb = [np.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)]
    nocc_a = len(idxoa[0])
    nocc_b = len(idxob[0])
    nvir_a = len(idxva[0])
    nvir_b = len(idxvb[0])

    r1a = r1[idxva[kshift]]
    r1b = r1[idxvb[kshift]]

    r2aaa = np.zeros((nkpts,nkpts,nocc_a,nvir_a,nvir_a), dtype=r2.dtype)
    r2aba = np.zeros((nkpts,nkpts,nocc_a,nvir_b,nvir_a), dtype=r2.dtype)
    r2bab = np.zeros((nkpts,nkpts,nocc_b,nvir_a,nvir_b), dtype=r2.dtype)
    r2bbb = np.zeros((nkpts,nkpts,nocc_b,nvir_b,nvir_b), dtype=r2.dtype)
    for kj, ka in itertools.product(range(nkpts), repeat=2):
        kb = kconserv[kshift, ka, kj]
        idxvaa = idxva[ka][:,None] * nvir + idxva[kb]
        idxvab = idxva[ka][:,None] * nvir + idxvb[kb]
        idxvba = idxvb[ka][:,None] * nvir + idxva[kb]
        idxvbb = idxvb[ka][:,None] * nvir + idxvb[kb]

        r2_tmp = r2[kj, ka].reshape(nocc, nvir**2)
        r2aaa_tmp = lib.take_2d(r2_tmp, idxoa[kj], idxvaa.ravel())
        r2aba_tmp = lib.take_2d(r2_tmp, idxoa[kj], idxvba.ravel())
        r2bab_tmp = lib.take_2d(r2_tmp, idxob[kj], idxvab.ravel())
        r2bbb_tmp = lib.take_2d(r2_tmp, idxob[kj], idxvbb.ravel())

        r2aaa[kj, ka] = r2aaa_tmp.reshape(nocc_a, nvir_a, nvir_a)
        r2aba[kj, ka] = r2aba_tmp.reshape(nocc_a, nvir_b, nvir_a)
        r2bab[kj, ka] = r2bab_tmp.reshape(nocc_b, nvir_a, nvir_b)
        r2bbb[kj, ka] = r2bbb_tmp.reshape(nocc_b, nvir_b, nvir_b)
    return [r1a, r1b], [r2aaa, r2aba, r2bab, r2bbb]
예제 #17
0
파일: ucisd.py 프로젝트: chrinide/pyscf
def amplitudes_to_cisdvec(c0, c1, c2):
    c1a, c1b = c1
    c2aa, c2ab, c2bb = c2
    nocca, nvira = c1a.shape
    noccb, nvirb = c1b.shape
    def trilidx(n):
        idx = numpy.tril_indices(n, -1)
        return idx[0] * n + idx[1]
    ooidxa = trilidx(nocca)
    vvidxa = trilidx(nvira)
    ooidxb = trilidx(noccb)
    vvidxb = trilidx(nvirb)
    size = (1, nocca*nvira, noccb*nvirb, nocca*noccb*nvira*nvirb,
            len(ooidxa)*len(vvidxa), len(ooidxb)*len(vvidxb))
    loc = numpy.cumsum(size)
    civec = numpy.empty(loc[-1], dtype=c2ab.dtype)
    civec[0] = c0
    civec[loc[0]:loc[1]] = c1a.ravel()
    civec[loc[1]:loc[2]] = c1b.ravel()
    civec[loc[2]:loc[3]] = c2ab.ravel()
    lib.take_2d(c2aa.reshape(nocca**2,nvira**2), ooidxa, vvidxa, out=civec[loc[3]:loc[4]])
    lib.take_2d(c2bb.reshape(noccb**2,nvirb**2), ooidxb, vvidxb, out=civec[loc[4]:loc[5]])
    return civec
예제 #18
0
파일: newton_ah.py 프로젝트: eronca/pyscf
 def rotate_mo(self, mo_coeff, u, log=None):
     #from pyscf.lo import orth
     #s = self._scf.get_ovlp()
     #if self._scf.mol.symmetry:
     #    s = symm.symmetrize_matrix(s, self._scf._scf.mol.symm_orb)
     #return orth.vec_lowdin(numpy.dot(mo_coeff, u), s)
     mo = numpy.dot(mo_coeff, u)
     if log is not None and log.verbose >= logger.DEBUG:
         idx = numpy.where(self.mo_occ > 0)[0]
         s = reduce(numpy.dot, (mo[:,idx].T, self._scf.get_ovlp(),
                                self.mo_coeff[:,idx]))
         log.debug('Overlap to initial guess, SVD = %s',
                   _effective_svd(s, 1e-5))
         log.debug('Overlap to last step, SVD = %s',
                   _effective_svd(lib.take_2d(u,idx,idx), 1e-5))
     return mo
예제 #19
0
파일: select_ci.py 프로젝트: eronca/pyscf
def enlarge_space(myci, civec_strs, eri, norb, nelec):
    if isinstance(civec_strs, (tuple, list)):
        nelec, (strsa, strsb) = _unpack(civec_strs[0], nelec)[1:]
        ci_coeff = lib.asarray(civec_strs)
    else:
        ci_coeff, nelec, (strsa, strsb) = _unpack(civec_strs, nelec)
    na = len(strsa)
    nb = len(strsb)
    ci0 = ci_coeff.reshape(-1,na,nb)
    civec_a_max = lib.norm(ci0, axis=2).max(axis=0)
    civec_b_max = lib.norm(ci0, axis=1).max(axis=0)
    ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0]
    ci_bidx = numpy.where(civec_b_max > myci.ci_coeff_cutoff)[0]
    civec_a_max = civec_a_max[ci_aidx]
    civec_b_max = civec_b_max[ci_bidx]
    strsa = strsa[ci_aidx]
    strsb = strsb[ci_bidx]

    eri = ao2mo.restore(1, eri, norb)
    eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb)

    strsa_add = select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0])
    strsb_add = select_strs(myci, eri, eri_pq_max, civec_b_max, strsb, norb, nelec[1])
    strsa = numpy.append(strsa, strsa_add)
    strsb = numpy.append(strsb, strsb_add)
    aidx = numpy.argsort(strsa)
    bidx = numpy.argsort(strsb)
    ci_strs = (strsa[aidx], strsb[bidx])
    aidx = numpy.where(aidx < len(ci_aidx))[0]
    bidx = numpy.where(bidx < len(ci_bidx))[0]
    ma = len(strsa)
    mb = len(strsb)

    cs = []
    for i in range(ci0.shape[0]):
        ci1 = numpy.zeros((ma,mb))
        tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx)
        lib.takebak_2d(ci1, tmp, aidx, bidx)
        cs.append(_as_SCIvector(ci1, ci_strs))

    if not isinstance(civec_strs, (tuple, list)) and civec_strs.ndim < 3:
        cs = cs[0]
    return cs
예제 #20
0
def overlap(string1, string2, norb, s=None):
    '''Determinants overlap on non-orthogonal one-particle basis'''
    if s is None:  # orthogonal basis with s_ij = delta_ij
        return string1 == string2
    else:
        if isinstance(string1, str):
            nelec = string1.count('1')
            string1 = int(string1, 2)
        else:
            nelec = bin(string1).count('1')
        if isinstance(string2, str):
            assert(string2.count('1') == nelec)
            string2 = int(string2, 2)
        else:
            assert(bin(string2).count('1') == nelec)
        idx1 = [i for i in range(norb) if (1<<i & string1)]
        idx2 = [i for i in range(norb) if (1<<i & string2)]
        s1 = lib.take_2d(s, idx1, idx2)
        return numpy.linalg.det(s1)
예제 #21
0
def reorder(ci, nelec, orbidxa, orbidxb=None):
    '''Reorder the CI coefficients, to adapt the reordered orbitals (The relation
    of the reordered orbitals and original orbitals is  new = old[idx]).  Eg.

    The orbital ordering indices ``orbidx = [2,0,1]`` indicates the map
    old orbital  a b c  ->   new orbital  c a b.  The strings are reordered as
    old-strings   0b011, 0b101, 0b110 ==  (1,2), (1,3), (2,3)   <= apply orbidx to get orb-strings
    orb-strings   (3,1), (3,2), (1,2) ==  0B101, 0B110, 0B011   <= by gen_strings4orblist
    then argsort to translate the string representation to the address
    [2(=0B011), 0(=0B101), 1(=0B110)]
    '''
    neleca, nelecb = _unpack(nelec)
    if orbidxb is None:
        orbidxb = orbidxa
    guide_stringsa = cistring.gen_strings4orblist(orbidxa, neleca)
    guide_stringsb = cistring.gen_strings4orblist(orbidxb, nelecb)
    old_det_idxa = numpy.argsort(guide_stringsa)
    old_det_idxb = numpy.argsort(guide_stringsb)
    return lib.take_2d(ci, old_det_idxa, old_det_idxb)
예제 #22
0
def enlarge_space(myci, civec_strs, eri, norb, nelec):
    if isinstance(civec_strs, (tuple, list)):
        nelec, (strsa, strsb) = select_ci._unpack(civec_strs[0], nelec)[1:]
        ci_coeff = lib.asarray(civec_strs)
    else:
        ci_coeff, nelec, (strsa, strsb) = select_ci._unpack(civec_strs, nelec)
    na = nb = len(strsa)
    ci0 = ci_coeff.reshape(-1,na,nb)
    abs_ci = abs(ci0).max(axis=0)

    eri = ao2mo.restore(1, eri, norb)
    eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb)

    civec_a_max = abs_ci.max(axis=1)
    ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0]
    civec_a_max = civec_a_max[ci_aidx]
    strsa = strsa[ci_aidx]
    strsa_add = select_ci.select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0])
    strsa = numpy.append(strsa, strsa_add)
    aidx = numpy.argsort(strsa)
    strsa = strsa[aidx]
    aidx = numpy.where(aidx < len(ci_aidx))[0]

    ci_bidx = ci_aidx
    strsb = strsa
    bidx = aidx

    ma = mb = len(strsa)
    cs = []
    for i in range(ci0.shape[0]):
        ci1 = numpy.zeros((ma,mb))
        tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx)
        lib.takebak_2d(ci1, tmp, aidx, bidx)
        cs.append(select_ci._as_SCIvector(ci1, (strsa,strsb)))

    if ci_coeff[0].ndim == 0 or ci_coeff[0].shape[-1] != nb:
        cs = [c.ravel() for c in cs]

    if (isinstance(ci_coeff, numpy.ndarray) and
        ci_coeff.shape[0] == na or ci_coeff.shape[0] == na*nb):
        cs = cs[0]
    return cs
예제 #23
0
def _gamma2_intermediates(mycc, t1, t2, l1, l2, eris=None,
                          compress_vvvv=False):
    dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = \
            ccsd_rdm._gamma2_intermediates(mycc, t1, t2, l1, l2)
    if eris is None: eris = mycc.ao2mo()

    nocc, nvir = t1.shape
    eris_ovvv = numpy.asarray(eris.get_ovvv())
    eris_ovoo = numpy.asarray(eris.ovoo)
    eris_ovov = numpy.asarray(eris.ovov)

    mo_e = eris.mo_energy
    eia = lib.direct_sum('i-a->ia', mo_e[:nocc], mo_e[nocc:])
    d3 = lib.direct_sum('ia,jb,kc->ijkabc', eia, eia, eia)

    w =(numpy.einsum('iafb,kjcf->ijkabc', eris_ovvv.conj(), t2)
      - numpy.einsum('iajm,mkbc->ijkabc', eris_ovoo.conj(), t2)) / d3
    v =(numpy.einsum('iajb,kc->ijkabc', eris_ovov.conj(), t1)
      + numpy.einsum('ck,ijab->ijkabc', eris.fock[nocc:,:nocc], t2)) / d3
    w = p6(w)
    v = p6(v)
    rw = r6(w)
    rwv = r6(w * 2 + v * .5)

    dovov += numpy.einsum('kc,ijkabc->iajb', t1, rw.conj()) * .5
    dooov -= numpy.einsum('mkbc,ijkabc->jmia', t2, rwv.conj())
    # Note "dovvv +=" also changes the value of dvvov
    dovvv += numpy.einsum('kjcf,ijkabc->iafb', t2, rwv.conj())
    dvvov = dovvv.transpose(2,3,0,1)

    if compress_vvvv:
        nvir = mycc.nmo - mycc.nocc
        idx = numpy.tril_indices(nvir)
        vidx = idx[0] * nvir + idx[1]
        dvvvv = dvvvv + dvvvv.transpose(1,0,2,3)
        dvvvv = dvvvv + dvvvv.transpose(0,1,3,2)
        dvvvv = lib.take_2d(dvvvv.reshape(nvir**2,nvir**2), vidx, vidx)
        dvvvv *= .25

    return dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov
예제 #24
0
def reorder4irrep(eri, norb, link_index, orbsym, offdiag=0):
    if orbsym is None:
        return eri, link_index, numpy.array(norb, dtype=numpy.int32)
    orbsym = numpy.asarray(orbsym)
# map irrep IDs of Dooh or Coov to D2h, C2v
# see symm.basis.linearmole_symm_descent
    orbsym = orbsym % 10
# irrep of (ij| pair
    trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb, offdiag)]
# and the number of occurence for each irrep
    dimirrep = numpy.array(numpy.bincount(trilirrep), dtype=numpy.int32)
# we sort the irreps of (ij| pair, to group the pairs which have same irreps
# "order" is irrep-id-sorted index. The (ij| paired is ordered that the
# pair-id given by order[0] comes first in the sorted pair
# "rank" is a sorted "order". Given nth (ij| pair, it returns the place(rank)
# of the sorted pair
    order = numpy.asarray(trilirrep.argsort(), dtype=numpy.int32)
    rank = numpy.asarray(order.argsort(), dtype=numpy.int32)
    eri = lib.take_2d(eri, order, order)
    link_index_irrep = link_index.copy()
    link_index_irrep[:,:,0] = rank[link_index[:,:,0]]
    return numpy.asarray(eri, order='C'), link_index_irrep, dimirrep
예제 #25
0
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None):
    cput0 = (time.clock(), time.time())
    eris = _ChemistsERIs()
    eris._common_init_(mycc, mo_coeff)

    nocca, noccb = mycc.nocc
    nmoa, nmob = mycc.nmo
    nvira, nvirb = nmoa - nocca, nmob - noccb

    moa = eris.mo_coeff[0]
    mob = eris.mo_coeff[1]
    nmoa = moa.shape[1]
    nmob = mob.shape[1]

    if callable(ao2mofn):
        eri_aa = ao2mofn(moa).reshape([nmoa] * 4)
        eri_bb = ao2mofn(mob).reshape([nmob] * 4)
        eri_ab = ao2mofn((moa, moa, mob, mob))
    else:
        eri_aa = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, moa), nmoa)
        eri_bb = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, mob), nmob)
        eri_ab = ao2mo.general(mycc._scf._eri, (moa, moa, mob, mob),
                               compact=False)
    eri_ba = eri_ab.reshape(nmoa, nmoa, nmob, nmob).transpose(2, 3, 0, 1)

    eri_aa = eri_aa.reshape(nmoa, nmoa, nmoa, nmoa)
    eri_ab = eri_ab.reshape(nmoa, nmoa, nmob, nmob)
    eri_ba = eri_ba.reshape(nmob, nmob, nmoa, nmoa)
    eri_bb = eri_bb.reshape(nmob, nmob, nmob, nmob)
    eris.oooo = eri_aa[:nocca, :nocca, :nocca, :nocca].copy()
    eris.ovoo = eri_aa[:nocca, nocca:, :nocca, :nocca].copy()
    eris.ovov = eri_aa[:nocca, nocca:, :nocca, nocca:].copy()
    eris.oovv = eri_aa[:nocca, :nocca, nocca:, nocca:].copy()
    eris.ovvo = eri_aa[:nocca, nocca:, nocca:, :nocca].copy()
    eris.ovvv = eri_aa[:nocca, nocca:, nocca:, nocca:].copy()
    eris.vvvv = eri_aa[nocca:, nocca:, nocca:, nocca:].copy()

    eris.OOOO = eri_bb[:noccb, :noccb, :noccb, :noccb].copy()
    eris.OVOO = eri_bb[:noccb, noccb:, :noccb, :noccb].copy()
    eris.OVOV = eri_bb[:noccb, noccb:, :noccb, noccb:].copy()
    eris.OOVV = eri_bb[:noccb, :noccb, noccb:, noccb:].copy()
    eris.OVVO = eri_bb[:noccb, noccb:, noccb:, :noccb].copy()
    eris.OVVV = eri_bb[:noccb, noccb:, noccb:, noccb:].copy()
    eris.VVVV = eri_bb[noccb:, noccb:, noccb:, noccb:].copy()

    eris.ooOO = eri_ab[:nocca, :nocca, :noccb, :noccb].copy()
    eris.ovOO = eri_ab[:nocca, nocca:, :noccb, :noccb].copy()
    eris.ovOV = eri_ab[:nocca, nocca:, :noccb, noccb:].copy()
    eris.ooVV = eri_ab[:nocca, :nocca, noccb:, noccb:].copy()
    eris.ovVO = eri_ab[:nocca, nocca:, noccb:, :noccb].copy()
    eris.ovVV = eri_ab[:nocca, nocca:, noccb:, noccb:].copy()
    eris.vvVV = eri_ab[nocca:, nocca:, noccb:, noccb:].copy()

    #eris.OOoo = eri_ba[:noccb,:noccb,:nocca,:nocca].copy()
    eris.OVoo = eri_ba[:noccb, noccb:, :nocca, :nocca].copy()
    #eris.OVov = eri_ba[:noccb,noccb:,:nocca,nocca:].copy()
    eris.OOvv = eri_ba[:noccb, :noccb, nocca:, nocca:].copy()
    eris.OVvo = eri_ba[:noccb, noccb:, nocca:, :nocca].copy()
    eris.OVvv = eri_ba[:noccb, noccb:, nocca:, nocca:].copy()
    #eris.VVvv = eri_ba[noccb:,noccb:,nocca:,nocca:].copy()

    if not callable(ao2mofn):
        ovvv = eris.ovvv.reshape(nocca * nvira, nvira, nvira)
        eris.ovvv = lib.pack_tril(ovvv).reshape(nocca, nvira,
                                                nvira * (nvira + 1) // 2)
        eris.vvvv = ao2mo.restore(4, eris.vvvv, nvira)

        OVVV = eris.OVVV.reshape(noccb * nvirb, nvirb, nvirb)
        eris.OVVV = lib.pack_tril(OVVV).reshape(noccb, nvirb,
                                                nvirb * (nvirb + 1) // 2)
        eris.VVVV = ao2mo.restore(4, eris.VVVV, nvirb)

        ovVV = eris.ovVV.reshape(nocca * nvira, nvirb, nvirb)
        eris.ovVV = lib.pack_tril(ovVV).reshape(nocca, nvira,
                                                nvirb * (nvirb + 1) // 2)
        vvVV = eris.vvVV.reshape(nvira**2, nvirb**2)
        idxa = np.tril_indices(nvira)
        idxb = np.tril_indices(nvirb)
        eris.vvVV = lib.take_2d(vvVV, idxa[0] * nvira + idxa[1],
                                idxb[0] * nvirb + idxb[1])

        OVvv = eris.OVvv.reshape(noccb * nvirb, nvira, nvira)
        eris.OVvv = lib.pack_tril(OVvv).reshape(noccb, nvirb,
                                                nvira * (nvira + 1) // 2)
    return eris
예제 #26
0
def overlap(cibra, ciket, nmo, nocc, s=None):
    '''Overlap between two CISD wavefunctions.

    Args:
        s : 2D array
            The overlap matrix of non-orthogonal one-particle basis
    '''
    if s is None:
        return dot(cibra, ciket, nmo, nocc)

    DEBUG = True

    nvir = nmo - nocc
    nov = nocc * nvir
    bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, nmo, nocc)
    ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, nmo, nocc)

    # Sort the ket orbitals to make the orbitals in bra one-one mapt to orbitals
    # in ket.
    if ((not DEBUG) and abs(numpy.linalg.det(s[:nocc, :nocc]) - 1) < 1e-2
            and abs(numpy.linalg.det(s[nocc:, nocc:]) - 1) < 1e-2):
        ket_orb_idx = numpy.where(abs(s) > 0.9)[1]
        s = s[:, ket_orb_idx]
        oidx = ket_orb_idx[:nocc]
        vidx = ket_orb_idx[nocc:] - nocc
        ket1 = ket1[oidx[:, None], vidx]
        ket2 = ket2[oidx[:, None, None, None], oidx[:, None, None],
                    vidx[:, None], vidx]

    ooidx = numpy.tril_indices(nocc, -1)
    vvidx = numpy.tril_indices(nvir, -1)
    bra2aa = bra2 - bra2.transpose(1, 0, 2, 3)
    bra2aa = lib.take_2d(bra2aa.reshape(nocc**2,
                                        nvir**2), ooidx[0] * nocc + ooidx[1],
                         vvidx[0] * nvir + vvidx[1])
    ket2aa = ket2 - ket2.transpose(1, 0, 2, 3)
    ket2aa = lib.take_2d(ket2aa.reshape(nocc**2,
                                        nvir**2), ooidx[0] * nocc + ooidx[1],
                         vvidx[0] * nvir + vvidx[1])

    occlist0 = numpy.arange(nocc).reshape(1, nocc)
    occlists = numpy.repeat(occlist0, 1 + nov + bra2aa.size, axis=0)
    occlist0 = occlists[:1]
    occlist1 = occlists[1:1 + nov]
    occlist2 = occlists[1 + nov:]

    ia = 0
    for i in range(nocc):
        for a in range(nocc, nmo):
            occlist1[ia, i] = a
            ia += 1

    ia = 0
    for i in range(nocc):
        for j in range(i):
            for a in range(nocc, nmo):
                for b in range(nocc, a):
                    occlist2[ia, i] = a
                    occlist2[ia, j] = b
                    ia += 1

    na = len(occlists)
    if DEBUG:
        trans = numpy.empty((na, na))
        for i, idx in enumerate(occlists):
            s_sub = s[idx].T.copy()
            minors = s_sub[occlists]
            trans[i, :] = numpy.linalg.det(minors)

        # Mimic the transformation einsum('ab,ap->pb', FCI, trans).
        # The wavefunction FCI has the [excitation_alpha,excitation_beta]
        # representation.  The zero blocks like FCI[S_alpha,D_beta],
        # FCI[D_alpha,D_beta], are explicitly excluded.
        bra_mat = numpy.zeros((na, na))
        bra_mat[0, 0] = bra0
        bra_mat[0, 1:1 + nov] = bra_mat[1:1 + nov, 0] = bra1.ravel()
        bra_mat[0, 1 + nov:] = bra_mat[1 + nov:, 0] = bra2aa.ravel()
        bra_mat[1:1 + nov, 1:1 + nov] = bra2.transpose(0, 2, 1,
                                                       3).reshape(nov, nov)
        ket_mat = numpy.zeros((na, na))
        ket_mat[0, 0] = ket0
        ket_mat[0, 1:1 + nov] = ket_mat[1:1 + nov, 0] = ket1.ravel()
        ket_mat[0, 1 + nov:] = ket_mat[1 + nov:, 0] = ket2aa.ravel()
        ket_mat[1:1 + nov, 1:1 + nov] = ket2.transpose(0, 2, 1,
                                                       3).reshape(nov, nov)
        ovlp = lib.einsum('ab,ap,bq,pq->', bra_mat, trans, trans, ket_mat)

    else:
        nov1 = 1 + nov
        noovv = bra2aa.size
        bra_SS = numpy.zeros((nov1, nov1))
        bra_SS[0, 0] = bra0
        bra_SS[0, 1:] = bra_SS[1:, 0] = bra1.ravel()
        bra_SS[1:, 1:] = bra2.transpose(0, 2, 1, 3).reshape(nov, nov)
        ket_SS = numpy.zeros((nov1, nov1))
        ket_SS[0, 0] = ket0
        ket_SS[0, 1:] = ket_SS[1:, 0] = ket1.ravel()
        ket_SS[1:, 1:] = ket2.transpose(0, 2, 1, 3).reshape(nov, nov)

        trans_SS = numpy.empty((nov1, nov1))
        trans_SD = numpy.empty((nov1, noovv))
        trans_DS = numpy.empty((noovv, nov1))
        occlist01 = occlists[:nov1]
        for i, idx in enumerate(occlist01):
            s_sub = s[idx].T.copy()
            minors = s_sub[occlist01]
            trans_SS[i, :] = numpy.linalg.det(minors)

            minors = s_sub[occlist2]
            trans_SD[i, :] = numpy.linalg.det(minors)

            s_sub = s[:, idx].copy()
            minors = s_sub[occlist2]
            trans_DS[:, i] = numpy.linalg.det(minors)

        ovlp = lib.einsum('ab,ap,bq,pq->', bra_SS, trans_SS, trans_SS, ket_SS)
        ovlp += lib.einsum('ab,a ,bq, q->', bra_SS, trans_SS[:, 0], trans_SD,
                           ket2aa.ravel())
        ovlp += lib.einsum('ab,ap,b ,p ->', bra_SS, trans_SD, trans_SS[:, 0],
                           ket2aa.ravel())

        ovlp += lib.einsum(' b, p,bq,pq->', bra2aa.ravel(), trans_SS[0, :],
                           trans_DS, ket_SS)
        ovlp += lib.einsum(' b, p,b ,p ->', bra2aa.ravel(), trans_SD[0, :],
                           trans_DS[:, 0], ket2aa.ravel())

        ovlp += lib.einsum('a ,ap, q,pq->', bra2aa.ravel(), trans_DS,
                           trans_SS[0, :], ket_SS)
        ovlp += lib.einsum('a ,a , q, q->', bra2aa.ravel(), trans_DS[:, 0],
                           trans_SD[0, :], ket2aa.ravel())

        # FIXME: whether to approximate the overlap between double excitation coefficients
        if numpy.linalg.norm(bra2aa) * numpy.linalg.norm(ket2aa) < 1e-4:
            # Skip the overlap if coefficients of double excitation are small enough
            pass
        if (abs(numpy.linalg.det(s[:nocc, :nocc]) - 1) < 1e-2
                and abs(numpy.linalg.det(s[nocc:, nocc:]) - 1) < 1e-2):
            # If the overlap matrix close to identity enough, use the <D|D'> overlap
            # for orthogonal single-particle basis to approximate the overlap
            # for non-orthogonal basis.
            ovlp += numpy.dot(bra2aa.ravel(), ket2aa.ravel()) * trans_SS[0,
                                                                         0] * 2
        else:
            from multiprocessing import sharedctypes, Process
            buf_ctypes = sharedctypes.RawArray('d', noovv)
            trans_ket = numpy.ndarray(noovv, buffer=buf_ctypes)

            def trans_dot_ket(i0, i1):
                for i in range(i0, i1):
                    s_sub = s[occlist2[i]].T.copy()
                    minors = s_sub[occlist2]
                    trans_ket[i] = numpy.linalg.det(minors).dot(ket2aa.ravel())

            nproc = lib.num_threads()
            if nproc > 1:
                seg = (noovv + nproc - 1) // nproc
                ps = []
                for i0, i1 in lib.prange(0, noovv, seg):
                    p = Process(target=trans_dot_ket, args=(i0, i1))
                    ps.append(p)
                    p.start()
                [p.join() for p in ps]
            else:
                trans_dot_ket(0, noovv)

            ovlp += numpy.dot(bra2aa.ravel(), trans_ket) * trans_SS[0, 0] * 2

    return ovlp
예제 #27
0
def _gamma2_outcore(cc, t1, t2, l1, l2, h5fobj, compress_vvvv=False):
    t1a, t1b = t1
    t2aa, t2ab, t2bb = t2
    l1a, l1b = l1
    l2aa, l2ab, l2bb = l2

    tauaa = t2aa + numpy.einsum('ia,jb->ijab', 2 * t1a, t1a)
    tauab = t2ab + numpy.einsum('ia,jb->ijab', t1a, t1b)
    taubb = t2bb + numpy.einsum('ia,jb->ijab', 2 * t1b, t1b)
    miajb = einsum('ikac,kjcb->iajb', l2aa, t2aa)
    miajb += einsum('ikac,jkbc->iajb', l2ab, t2ab)
    miaJB = einsum('ikac,kjcb->iajb', l2aa, t2ab)
    miaJB += einsum('ikac,kjcb->iajb', l2ab, t2bb)
    mIAjb = einsum('kica,jkbc->iajb', l2bb, t2ab)
    mIAjb += einsum('kica,kjcb->iajb', l2ab, t2aa)
    mIAJB = einsum('ikac,kjcb->iajb', l2bb, t2bb)
    mIAJB += einsum('kica,kjcb->iajb', l2ab, t2ab)
    miAjB = einsum('ikca,jkcb->iajb', l2ab, t2ab)
    mIaJb = einsum('kiac,kjbc->iajb', l2ab, t2ab)

    goovv = (l2aa.conj() + tauaa) * .25
    goOvV = (l2ab.conj() + tauab) * .5
    gOOVV = (l2bb.conj() + taubb) * .25

    tmpa = einsum('kc,kica->ia', l1a, t2aa)
    tmpa += einsum('kc,ikac->ia', l1b, t2ab)
    tmpb = einsum('kc,kica->ia', l1b, t2bb)
    tmpb += einsum('kc,kica->ia', l1a, t2ab)
    goovv += einsum('ia,jb->ijab', tmpa, t1a)
    goOvV += einsum('ia,jb->ijab', tmpa, t1b) * .5
    goOvV += einsum('ia,jb->jiba', tmpb, t1a) * .5
    gOOVV += einsum('ia,jb->ijab', tmpb, t1b)

    tmpa = einsum('kc,kb->cb', l1a, t1a)
    tmpb = einsum('kc,kb->cb', l1b, t1b)
    goovv += einsum('cb,ijca->ijab', tmpa, t2aa) * .5
    goOvV -= einsum('cb,ijac->ijab', tmpb, t2ab) * .5
    goOvV -= einsum('cb,jica->jiba', tmpa, t2ab) * .5
    gOOVV += einsum('cb,ijca->ijab', tmpb, t2bb) * .5
    tmpa = einsum('kc,jc->kj', l1a, t1a)
    tmpb = einsum('kc,jc->kj', l1b, t1b)
    goovv += einsum('kiab,kj->ijab', tauaa, tmpa) * .5
    goOvV -= einsum('ikab,kj->ijab', tauab, tmpb) * .5
    goOvV -= einsum('kiba,kj->jiba', tauab, tmpa) * .5
    gOOVV += einsum('kiab,kj->ijab', taubb, tmpb) * .5

    tmpa = numpy.einsum('ldjd->lj', miajb)
    tmpa += numpy.einsum('ldjd->lj', miAjB)
    tmpb = numpy.einsum('ldjd->lj', mIAJB)
    tmpb += numpy.einsum('ldjd->lj', mIaJb)
    goovv -= einsum('lj,liba->ijab', tmpa, tauaa) * .25
    goOvV -= einsum('lj,ilab->ijab', tmpb, tauab) * .25
    goOvV -= einsum('lj,liba->jiba', tmpa, tauab) * .25
    gOOVV -= einsum('lj,liba->ijab', tmpb, taubb) * .25
    tmpa = numpy.einsum('ldlb->db', miajb)
    tmpa += numpy.einsum('ldlb->db', mIaJb)
    tmpb = numpy.einsum('ldlb->db', mIAJB)
    tmpb += numpy.einsum('ldlb->db', miAjB)
    goovv -= einsum('db,jida->ijab', tmpa, tauaa) * .25
    goOvV -= einsum('db,ijad->ijab', tmpb, tauab) * .25
    goOvV -= einsum('db,jida->jiba', tmpa, tauab) * .25
    gOOVV -= einsum('db,jida->ijab', tmpb, taubb) * .25

    goovv -= einsum('ldia,ljbd->ijab', miajb, tauaa) * .5
    goovv += einsum('LDia,jLbD->ijab', mIAjb, t2ab) * .5
    gOOVV -= einsum('ldia,ljbd->ijab', mIAJB, taubb) * .5
    gOOVV += einsum('ldia,ljdb->ijab', miaJB, t2ab) * .5
    goOvV -= einsum('LDia,LJBD->iJaB', mIAjb, taubb) * .25
    goOvV += einsum('ldia,lJdB->iJaB', miajb, t2ab) * .25
    goOvV -= einsum('ldIA,ljbd->jIbA', miaJB, tauaa) * .25
    goOvV += einsum('LDIA,jLbD->jIbA', mIAJB, t2ab) * .25
    goOvV += einsum('lDiA,lJbD->iJbA', miAjB, tauab) * .5
    goOvV += einsum('LdIa,jd,LB->jIaB', mIaJb, t1a, t1b) * .5

    tmpaa = einsum('klcd,ijcd->ijkl', l2aa, tauaa) * .25**2
    tmpbb = einsum('klcd,ijcd->ijkl', l2bb, taubb) * .25**2
    tmpabab = einsum('kLcD,iJcD->iJkL', l2ab, tauab) * .5
    goovv += einsum('ijkl,klab->ijab', tmpaa, tauaa)
    goOvV += einsum('ijkl,klab->ijab', tmpabab, tauab)
    gOOVV += einsum('ijkl,klab->ijab', tmpbb, taubb)
    goovv = goovv.conj()
    goOvV = goOvV.conj()
    gOOVV = gOOVV.conj()

    gvvvv = einsum('ijab,ijcd->abcd', tauaa, l2aa) * .125
    gvVvV = einsum('ijab,ijcd->abcd', tauab, l2ab) * .25
    gVVVV = einsum('ijab,ijcd->abcd', taubb, l2bb) * .125

    goooo = einsum('ijab,klab->ijkl', l2aa, tauaa) * .125
    goOoO = einsum('ijab,klab->ijkl', l2ab, tauab) * .25
    gOOOO = einsum('ijab,klab->ijkl', l2bb, taubb) * .125

    gooov = einsum('jkba,ib->jkia', tauaa, -0.25 * l1a)
    goOoV = einsum('jkba,ib->jkia', tauab, -0.5 * l1a)
    gOoOv = einsum('kjab,ib->jkia', tauab, -0.5 * l1b)
    gOOOV = einsum('jkba,ib->jkia', taubb, -0.25 * l1b)

    gooov += einsum('iljk,la->jkia', goooo, t1a)
    goOoV += einsum('iljk,la->jkia', goOoO, t1b) * 2
    gOoOv += einsum('likj,la->jkia', goOoO, t1a) * 2
    gOOOV += einsum('iljk,la->jkia', gOOOO, t1b)

    tmpa = numpy.einsum('icjc->ij', miajb) * .25
    tmpa += numpy.einsum('icjc->ij', miAjB) * .25
    tmpb = numpy.einsum('icjc->ij', mIAJB) * .25
    tmpb += numpy.einsum('icjc->ij', mIaJb) * .25
    gooov -= einsum('ij,ka->jkia', tmpa, t1a)
    goOoV -= einsum('ij,ka->jkia', tmpa, t1b)
    gOoOv -= einsum('ij,ka->jkia', tmpb, t1a)
    gOOOV -= einsum('ij,ka->jkia', tmpb, t1b)

    gooov += einsum('icja,kc->jkia', miajb, .5 * t1a)
    goOoV += einsum('icja,kc->jkia', miAjB, .5 * t1b)
    goOoV -= einsum('icJA,kc->kJiA', miaJB, .5 * t1a)
    gOoOv += einsum('icja,kc->jkia', mIaJb, .5 * t1a)
    gOoOv -= einsum('ICja,KC->KjIa', mIAjb, .5 * t1b)
    gOOOV += einsum('icja,kc->jkia', mIAJB, .5 * t1b)

    gooov = gooov.conj()
    goOoV = goOoV.conj()
    gOoOv = gOoOv.conj()
    gOOOV = gOOOV.conj()
    gooov += einsum('jkab,ib->jkia', l2aa, .25 * t1a)
    goOoV -= einsum('jkba,ib->jkia', l2ab, .5 * t1a)
    gOoOv -= einsum('kjab,ib->jkia', l2ab, .5 * t1b)
    gOOOV += einsum('jkab,ib->jkia', l2bb, .25 * t1b)

    govvv = einsum('ja,ijcb->iacb', .25 * l1a, tauaa)
    goVvV = einsum('ja,ijcb->iacb', .5 * l1b, tauab)
    gOvVv = einsum('ja,jibc->iacb', .5 * l1a, tauab)
    gOVVV = einsum('ja,ijcb->iacb', .25 * l1b, taubb)

    govvv += einsum('bcad,id->iabc', gvvvv, t1a)
    goVvV -= einsum('bcda,id->iabc', gvVvV, t1a) * 2
    gOvVv -= einsum('cbad,id->iabc', gvVvV, t1b) * 2
    gOVVV += einsum('bcad,id->iabc', gVVVV, t1b)

    tmpa = numpy.einsum('kakb->ab', miajb) * .25
    tmpa += numpy.einsum('kakb->ab', mIaJb) * .25
    tmpb = numpy.einsum('kakb->ab', mIAJB) * .25
    tmpb += numpy.einsum('kakb->ab', miAjB) * .25
    govvv += einsum('ab,ic->iacb', tmpa, t1a)
    goVvV += einsum('ab,ic->iacb', tmpb, t1a)
    gOvVv += einsum('ab,ic->iacb', tmpa, t1b)
    gOVVV += einsum('ab,ic->iacb', tmpb, t1b)

    govvv += einsum('kaib,kc->iabc', miajb, .5 * t1a)
    goVvV += einsum('KAib,KC->iAbC', mIAjb, .5 * t1b)
    goVvV -= einsum('kAiB,kc->iAcB', miAjB, .5 * t1a)
    gOvVv += einsum('kaIB,kc->IaBc', miaJB, .5 * t1a)
    gOvVv -= einsum('KaIb,KC->IaCb', mIaJb, .5 * t1b)
    gOVVV += einsum('kaib,kc->iabc', mIAJB, .5 * t1b)
    govvv = govvv.conj()
    goVvV = goVvV.conj()
    gOvVv = gOvVv.conj()
    gOVVV = gOVVV.conj()
    govvv += einsum('ijbc,ja->iabc', l2aa, .25 * t1a)
    goVvV += einsum('iJbC,JA->iAbC', l2ab, .5 * t1b)
    gOvVv += einsum('jIcB,ja->IaBc', l2ab, .5 * t1a)
    gOVVV += einsum('ijbc,ja->iabc', l2bb, .25 * t1b)

    govvo = einsum('ia,jb->ibaj', l1a, t1a)
    goVvO = einsum('ia,jb->ibaj', l1a, t1b)
    gOvVo = einsum('ia,jb->ibaj', l1b, t1a)
    gOVVO = einsum('ia,jb->ibaj', l1b, t1b)

    govvo += numpy.einsum('iajb->ibaj', miajb)
    goVvO += numpy.einsum('iajb->ibaj', miaJB)
    gOvVo += numpy.einsum('iajb->ibaj', mIAjb)
    gOVVO += numpy.einsum('iajb->ibaj', mIAJB)
    goVoV = numpy.einsum('iajb->ibja', miAjB)
    gOvOv = numpy.einsum('iajb->ibja', mIaJb)

    govvo -= einsum('ikac,jc,kb->ibaj', l2aa, t1a, t1a)
    goVvO -= einsum('iKaC,JC,KB->iBaJ', l2ab, t1b, t1b)
    gOvVo -= einsum('kIcA,jc,kb->IbAj', l2ab, t1a, t1a)
    gOVVO -= einsum('ikac,jc,kb->ibaj', l2bb, t1b, t1b)
    goVoV += einsum('iKcA,jc,KB->iBjA', l2ab, t1a, t1b)
    gOvOv += einsum('kIaC,JC,kb->IbJa', l2ab, t1b, t1a)

    dovov = goovv.transpose(0, 2, 1, 3) - goovv.transpose(0, 3, 1, 2)
    dvvvv = gvvvv.transpose(0, 2, 1, 3) - gvvvv.transpose(0, 3, 1, 2)
    doooo = goooo.transpose(0, 2, 1, 3) - goooo.transpose(0, 3, 1, 2)
    dovvv = govvv.transpose(0, 2, 1, 3) - govvv.transpose(0, 3, 1, 2)
    dooov = gooov.transpose(0, 2, 1, 3) - gooov.transpose(1, 2, 0, 3)
    dovvo = govvo.transpose(0, 2, 1, 3)
    dovov = (dovov + dovov.transpose(2, 3, 0, 1)) * .5
    dvvvv = dvvvv + dvvvv.transpose(1, 0, 3, 2).conj()
    doooo = doooo + doooo.transpose(1, 0, 3, 2).conj()
    dovvo = (dovvo + dovvo.transpose(3, 2, 1, 0).conj()) * .5
    doovv = -dovvo.transpose(0, 3, 2, 1)
    dvvov = None

    dOVOV = gOOVV.transpose(0, 2, 1, 3) - gOOVV.transpose(0, 3, 1, 2)
    dVVVV = gVVVV.transpose(0, 2, 1, 3) - gVVVV.transpose(0, 3, 1, 2)
    dOOOO = gOOOO.transpose(0, 2, 1, 3) - gOOOO.transpose(0, 3, 1, 2)
    dOVVV = gOVVV.transpose(0, 2, 1, 3) - gOVVV.transpose(0, 3, 1, 2)
    dOOOV = gOOOV.transpose(0, 2, 1, 3) - gOOOV.transpose(1, 2, 0, 3)
    dOVVO = gOVVO.transpose(0, 2, 1, 3)
    dOVOV = (dOVOV + dOVOV.transpose(2, 3, 0, 1)) * .5
    dVVVV = dVVVV + dVVVV.transpose(1, 0, 3, 2).conj()
    dOOOO = dOOOO + dOOOO.transpose(1, 0, 3, 2).conj()
    dOVVO = (dOVVO + dOVVO.transpose(3, 2, 1, 0).conj()) * .5
    dOOVV = -dOVVO.transpose(0, 3, 2, 1)
    dVVOV = None

    dovOV = goOvV.transpose(0, 2, 1, 3)
    dvvVV = gvVvV.transpose(0, 2, 1, 3) * 2
    dooOO = goOoO.transpose(0, 2, 1, 3) * 2
    dovVV = goVvV.transpose(0, 2, 1, 3)
    dooOV = goOoV.transpose(0, 2, 1, 3)
    dovVO = goVvO.transpose(0, 2, 1, 3)

    dOVvv = gOvVv.transpose(0, 2, 1, 3)
    dOOov = gOoOv.transpose(0, 2, 1, 3)
    dOVvo = gOvVo.transpose(0, 2, 1, 3)
    dooVV = goVoV.transpose(0, 2, 1, 3)
    dOOvv = gOvOv.transpose(0, 2, 1, 3)

    dvvVV = dvvVV + dvvVV.transpose(1, 0, 3, 2).conj()
    dooOO = dooOO + dooOO.transpose(1, 0, 3, 2).conj()
    dovVO = (dovVO + dOVvo.transpose(3, 2, 1, 0).conj()) * .5
    dooVV = -(dooVV + dooVV.transpose(1, 0, 3, 2).conj()) * .5
    dvvOV = None

    dOVov = None
    dVVvv = None
    dOOoo = None
    dOVvo = dovVO.transpose(3, 2, 1, 0).conj()
    dOOvv = -(dOOvv + dOOvv.transpose(1, 0, 3, 2).conj()) * .5
    dVVov = None

    if compress_vvvv:
        nocca, noccb, nvira, nvirb = t2ab.shape
        idxa = numpy.tril_indices(nvira)
        idxa = idxa[0] * nvira + idxa[1]
        idxb = numpy.tril_indices(nvirb)
        idxb = idxb[0] * nvirb + idxb[1]
        dvvvv = dvvvv + dvvvv.transpose(1, 0, 2, 3)
        dvvvv = lib.take_2d(dvvvv.reshape(nvira**2, nvira**2), idxa, idxa)
        dvvvv *= .5
        dvvVV = dvvVV + dvvVV.transpose(1, 0, 2, 3)
        dvvVV = lib.take_2d(dvvVV.reshape(nvira**2, nvirb**2), idxa, idxb)
        dvvVV *= .5
        dVVVV = dVVVV + dVVVV.transpose(1, 0, 2, 3)
        dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2, nvirb**2), idxb, idxb)
        dVVVV *= .5

    return ((dovov, dovOV, dOVov, dOVOV), (dvvvv, dvvVV, dVVvv, dVVVV),
            (doooo, dooOO, dOOoo, dOOOO), (doovv, dooVV, dOOvv, dOOVV),
            (dovvo, dovVO, dOVvo, dOVVO), (dvvov, dvvOV, dVVov, dVVOV),
            (dovvv, dovVV, dOVvv, dOVVV), (dooov, dooOV, dOOov, dOOOV))
예제 #28
0
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0):
    if orbsym is None:
        return direct_spin1.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa, link_indexb = direct_spin1._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    nb, nlinkb = link_indexb.shape[:2]
    eri_irs, rank_eri, irrep_eri = reorder_eri(eri, norb, orbsym)

    strsa = cistring.gen_strings4orblist(range(norb), neleca)
    aidx, link_indexa = gen_str_irrep(strsa, orbsym, link_indexa, rank_eri, irrep_eri)
    if neleca == nelecb:
        bidx, link_indexb = aidx, link_indexa
    else:
        strsb = cistring.gen_strings4orblist(range(norb), nelecb)
        bidx, link_indexb = gen_str_irrep(strsb, orbsym, link_indexb, rank_eri, irrep_eri)

    Tirrep = ctypes.c_void_p*TOTIRREPS
    linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    linkb_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexb])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int*TOTIRREPS)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na,nb), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int*TOTIRREPS)(*[x.size for x in aidx])
    nbs = (ctypes.c_int*TOTIRREPS)(*[x.size for x in bidx])

# aa, ab
    ci0 = []
    ci1 = []
    for ir in range(TOTIRREPS):
        ma, mb = aidx[ir].size, bidx[wfnsym^ir].size
        ci0.append(numpy.zeros((ma,mb)))
        ci1.append(numpy.zeros((ma,mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], bidx[wfnsym^ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nbs,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinkb),
                                linka_ptr, linkb_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], bidx[wfnsym^ir])

# bb, ba
    ci0T = []
    for ir in range(TOTIRREPS):
        mb, ma = bidx[ir].size, aidx[wfnsym^ir].size
        ci0T.append(numpy.zeros((mb,ma)))
        if ma > 0 and mb > 0:
            lib.transpose(ci0[wfnsym^ir], out=ci0T[ir])
    ci0, ci0T = ci0T, None
    ci1 = [numpy.zeros_like(x) for x in ci0]
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nbs, nas,
                                ctypes.c_int(nlinkb), ctypes.c_int(nlinka),
                                linkb_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, lib.transpose(ci1[ir]), aidx[wfnsym^ir], bidx[ir])
    return ci1new.reshape(fcivec_shape)
예제 #29
0
def _make_eris_incore(myci, mo_coeff=None):
    cput0 = (time.clock(), time.time())
    eris = _UCISD_ERIs(myci, mo_coeff)
    nocca = eris.nocca
    noccb = eris.noccb
    nmoa = eris.focka.shape[0]
    nmob = eris.fockb.shape[0]
    nvira = nmoa - nocca
    nvirb = nmob - noccb
    moa, mob = eris.mo_coeff

    eri_aa = ao2mo.restore(1, ao2mo.full(myci._scf._eri, moa), nmoa)
    eris.oooo = eri_aa[:nocca, :nocca, :nocca, :nocca].copy()
    eris.ooov = eri_aa[:nocca, :nocca, :nocca, nocca:].copy()
    eris.vooo = eri_aa[nocca:, :nocca, :nocca, :nocca].copy()
    eris.oovo = eri_aa[:nocca, :nocca, nocca:, :nocca].copy()
    eris.voov = eri_aa[nocca:, :nocca, :nocca, nocca:].copy()
    eris.vvoo = eri_aa[nocca:, nocca:, :nocca, :nocca].copy()
    eris.oovv = eri_aa[:nocca, :nocca, nocca:, nocca:].copy()
    eris.vovo = eri_aa[nocca:, :nocca, nocca:, :nocca].copy()
    eris.vovv = eri_aa[nocca:, :nocca, nocca:, nocca:].copy()
    #vovv = eri_aa[nocca:,:nocca,nocca:,nocca:].reshape(-1,nvira,nvira)
    #eris.vovv = lib.pack_tril(vovv).reshape(nvira,nocca,nvira*(nvira+1)//2)
    eris.vvvv = ao2mo.restore(4, eri_aa[nocca:, nocca:, nocca:, nocca:].copy(),
                              nvira)
    vovv = eri_aa = None

    eri_bb = ao2mo.restore(1, ao2mo.full(myci._scf._eri, mob), nmob)
    eris.OOOO = eri_bb[:noccb, :noccb, :noccb, :noccb].copy()
    eris.OOOV = eri_bb[:noccb, :noccb, :noccb, noccb:].copy()
    eris.VOOO = eri_bb[noccb:, :noccb, :noccb, :noccb].copy()
    eris.OOVO = eri_bb[:noccb, :noccb, noccb:, :noccb].copy()
    eris.VOOV = eri_bb[noccb:, :noccb, :noccb, noccb:].copy()
    eris.VVOO = eri_bb[noccb:, noccb:, :noccb, :noccb].copy()
    eris.OOVV = eri_bb[:noccb, :noccb, noccb:, noccb:].copy()
    eris.VOVO = eri_bb[noccb:, :noccb, noccb:, :noccb].copy()
    eris.VOVV = eri_bb[noccb:, :noccb, noccb:, noccb:].copy()
    #VOVV = eri_bb[noccb:,:noccb,noccb:,noccb:].reshape(-1,nvirb,nvirb)
    #eris.VOVV = lib.pack_tril(VOVV).reshape(nvirb,noccb,nvirb*(nvirb+1)//2)
    eris.VVVV = ao2mo.restore(4, eri_bb[noccb:, noccb:, noccb:, noccb:].copy(),
                              nvirb)
    VOVV = eri_bb = None

    eri_ab = ao2mo.general(myci._scf._eri, (moa, moa, mob, mob), compact=False)
    eri_ab = eri_ab.reshape(nmoa, nmoa, nmob, nmob)
    eris.ooOO = eri_ab[:nocca, :nocca, :noccb, :noccb].copy()
    eris.ooOV = eri_ab[:nocca, :nocca, :noccb, noccb:].copy()
    eris.voOO = eri_ab[nocca:, :nocca, :noccb, :noccb].copy()
    eris.ooVO = eri_ab[:nocca, :nocca, noccb:, :noccb].copy()
    eris.voOV = eri_ab[nocca:, :nocca, :noccb, noccb:].copy()
    eris.ooVV = eri_ab[:nocca, :nocca, noccb:, noccb:].copy()
    eris.vvOO = eri_ab[nocca:, nocca:, :noccb, :noccb].copy()
    eris.voVO = eri_ab[nocca:, :nocca, noccb:, :noccb].copy()
    eris.voVV = eri_ab[nocca:, :nocca, noccb:, noccb:].copy()
    #voVV = eri_ab[nocca:,:nocca,noccb:,noccb:].reshape(nocca*nvira,nvirb,nvirb)
    #eris.voVV = lib.pack_tril(voVV).reshape(nvira,nocca,nvirb*(nvirb+1)//2)
    voVV = None
    vvVV = eri_ab[nocca:, nocca:, noccb:, noccb:].reshape(nvira**2, nvirb**2)
    idxa = numpy.tril_indices(nvira)
    idxb = numpy.tril_indices(nvirb)
    eris.vvVV = lib.take_2d(vvVV, idxa[0] * nvira + idxa[1],
                            idxb[0] * nvirb + idxb[1])

    eri_ba = lib.transpose(eri_ab.reshape(nmoa**2, nmob**2))
    eri_ba = eri_ba.reshape(nmob, nmob, nmoa, nmoa)
    eris.OOoo = eri_ba[:noccb, :noccb, :nocca, :nocca].copy()
    eris.OOov = eri_ba[:noccb, :noccb, :nocca, nocca:].copy()
    eris.VOoo = eri_ba[noccb:, :noccb, :nocca, :nocca].copy()
    eris.OOvo = eri_ba[:noccb, :noccb, nocca:, :nocca].copy()
    eris.VOov = eri_ba[noccb:, :noccb, :nocca, nocca:].copy()
    eris.VVoo = eri_ba[noccb:, noccb:, :nocca, :nocca].copy()
    eris.VOvo = eri_ba[noccb:, :noccb, nocca:, :nocca].copy()
    eris.VOvv = eri_ba[noccb:, :noccb, nocca:, nocca:].copy()
    #VOvv = eri_ba[noccb:,:noccb,nocca:,nocca:].reshape(noccb*nvirb,nvira,nvira)
    #eris.VOvv = lib.pack_tril(VOvv).reshape(nvirb,noccb,nvira*(nvira+1)//2)
    VOvv = None
    eris.VVvv = eri_ba[noccb:, noccb:, nocca:, nocca:].copy()
    return eris
예제 #30
0
def _ao2mo_ovov(mp, orbo, orbv, feri, max_memory=2000, verbose=None):
    time0 = (time.clock(), time.time())
    log = logger.new_logger(mp, verbose)

    mol = mp.mol
    int2e = mol._add_suffix('int2e')
    ao2mopt = _ao2mo.AO2MOpt(mol, int2e, 'CVHFnr_schwarz_cond',
                             'CVHFsetnr_direct_scf')
    nao, nocc = orbo.shape
    nvir = orbv.shape[1]
    nbas = mol.nbas
    assert(nvir <= nao)

    ao_loc = mol.ao_loc_nr()
    dmax = max(4, min(nao/3, numpy.sqrt(max_memory*.95e6/8/(nao+nocc)**2)))
    sh_ranges = ao2mo.outcore.balance_partition(ao_loc, dmax)
    dmax = max(x[2] for x in sh_ranges)
    eribuf = numpy.empty((nao,dmax,dmax,nao))
    ftmp = lib.H5TmpFile()
    log.debug('max_memory %s MB (dmax = %s) required disk space %g MB',
              max_memory, dmax, nocc**2*(nao*(nao+dmax)/2+nvir**2)*8/1e6)

    buf_i = numpy.empty((nocc*dmax**2*nao))
    buf_li = numpy.empty((nocc**2*dmax**2))
    buf1 = numpy.empty_like(buf_li)

    fint = gto.moleintor.getints4c
    jk_blk_slices = []
    count = 0
    time1 = time0
    with lib.call_in_background(ftmp.__setitem__) as save:
        for ip, (ish0, ish1, ni) in enumerate(sh_ranges):
            for jsh0, jsh1, nj in sh_ranges[:ip+1]:
                i0, i1 = ao_loc[ish0], ao_loc[ish1]
                j0, j1 = ao_loc[jsh0], ao_loc[jsh1]
                jk_blk_slices.append((i0,i1,j0,j1))

                eri = fint(int2e, mol._atm, mol._bas, mol._env,
                           shls_slice=(0,nbas,ish0,ish1, jsh0,jsh1,0,nbas),
                           aosym='s1', ao_loc=ao_loc, cintopt=ao2mopt._cintopt,
                           out=eribuf)
                tmp_i = numpy.ndarray((nocc,(i1-i0)*(j1-j0)*nao), buffer=buf_i)
                tmp_li = numpy.ndarray((nocc,nocc*(i1-i0)*(j1-j0)), buffer=buf_li)
                lib.ddot(orbo.T, eri.reshape(nao,(i1-i0)*(j1-j0)*nao), c=tmp_i)
                lib.ddot(orbo.T, tmp_i.reshape(nocc*(i1-i0)*(j1-j0),nao).T, c=tmp_li)
                tmp_li = tmp_li.reshape(nocc,nocc,(i1-i0),(j1-j0))
                save(str(count), tmp_li.transpose(1,0,2,3))
                buf_li, buf1 = buf1, buf_li
                count += 1
                time1 = log.timer_debug1('partial ao2mo [%d:%d,%d:%d]' %
                                         (ish0,ish1,jsh0,jsh1), *time1)
    time1 = time0 = log.timer('mp2 ao2mo_ovov pass1', *time0)
    eri = eribuf = tmp_i = tmp_li = buf_i = buf_li = buf1 = None

    chunks = (nvir,nvir)
    h5dat = feri.create_dataset('ovov', (nocc*nvir,nocc*nvir), 'f8',
                                chunks=chunks)
    # jk_where is the sorting indices for the stacked (oO|pP) integrals in pass 2
    jk_where = []
    aoao_idx = numpy.arange(nao*nao).reshape(nao,nao)
    for i0, i1, j0, j1 in jk_blk_slices:
        # idx of pP in <oO|pP>
        jk_where.append(aoao_idx[i0:i1,j0:j1].ravel())
        if i0 != j0:
            # idx of pP in (<oO|pP>).transpose(1,0,3,2)
            jk_where.append(aoao_idx[j0:j1,i0:i1].ravel())
    jk_where = numpy.argsort(numpy.hstack(jk_where)).astype(numpy.int32)
    orbv = numpy.asarray(orbv, order='F')

    occblk = int(min(nocc, max(4, 250/nocc, max_memory*.9e6/8/(nao**2*nocc)/5)))
    def load(i0, eri):
        if i0 >= nocc:
            return
        i1 = min(i0+occblk, nocc)
        eri = eri[:(i1-i0)*nocc]
        p1 = 0
        for k, jk_slice in enumerate(jk_blk_slices):
            dat = numpy.asarray(ftmp[str(k)][i0:i1]).reshape((i1-i0)*nocc,-1)
            p0, p1 = p1, p1 + dat.shape[1]
            eri[:,p0:p1] = dat
            if jk_slice[0] != jk_slice[2]:
                dat = numpy.asarray(ftmp[str(k)][:,i0:i1])
                dat = dat.transpose(1,0,3,2).reshape((i1-i0)*nocc,-1)
                p0, p1 = p1, p1 + dat.shape[1]
                eri[:,p0:p1] = dat

    def save(i0, i1, dat):
        for i in range(i0, i1):
            h5dat[i*nvir:(i+1)*nvir] = dat[i-i0].reshape(nvir,nocc*nvir)

    buf_prefecth = numpy.empty((occblk*nocc,nao**2))
    buf = numpy.empty_like(buf_prefecth)
    buf1 = numpy.empty_like(buf_prefecth)
    bufw = numpy.empty((occblk*nocc,nvir**2))
    bufw1 = numpy.empty_like(bufw)
    with lib.call_in_background(load) as prefetch:
        with lib.call_in_background(save) as bsave:
            load(0, buf_prefecth)
            for i0, i1 in lib.prange(0, nocc, occblk):
                buf, buf_prefecth = buf_prefecth, buf
                eri = buf[:(i1-i0)*nocc]
                prefetch(i1, buf_prefecth)

                idx = numpy.arange(eri.shape[0], dtype=numpy.int32)
                dat = lib.take_2d(eri, idx, jk_where, out=buf1)
                dat = _ao2mo.nr_e2(dat, orbv, (0,nvir,0,nvir), 's1', 's1', out=bufw)
                bsave(i0, i1, dat.reshape(i1-i0,nocc,nvir,nvir).transpose(0,2,1,3))
                bufw, bufw1 = bufw1, bufw
                time1 = log.timer_debug1('pass2 ao2mo [%d:%d]' % (i0,i1), *time1)

    time0 = log.timer('mp2 ao2mo_ovov pass2', *time0)
    return h5dat
예제 #31
0
파일: addons.py 프로젝트: zwgsyntax/pyscf
def restore(symmetry, eri, norb, tao=None):
    r'''Convert the 2e integrals (in Chemist's notation) between different
    level of permutation symmetry (8-fold, 4-fold, or no symmetry)

    Args:
        symmetry : int or str
            code to present the target symmetry of 2e integrals

            | 's8' or '8' or 8 : 8-fold symmetry
            | 's4' or '4' or 4 : 4-fold symmetry
            | 's1' or '1' or 1 : no symmetry
            | 's2ij' or '2ij' : symmetric ij pair for (ij|kl) (TODO)
            | 's2ij' or '2kl' : symmetric kl pair for (ij|kl) (TODO)

            Note the 4-fold symmetry requires (ij|kl) == (ij|lk) == (ij|lk)
            while (ij|kl) != (kl|ij) is not required.

        eri : ndarray
            The symmetry of eri is determined by the size of eri and norb
        norb : int
            The symmetry of eri is determined by the size of eri and norb

    Returns:
        ndarray.  The shape depends on the target symmetry.

            | 8 : (norb*(norb+1)/2)*(norb*(norb+1)/2+1)/2
            | 4 : (norb*(norb+1)/2, norb*(norb+1)/2)
            | 1 : (norb, norb, norb, norb)

    Examples:

    >>> from pyscf import gto
    >>> from pyscf.scf import _vhf
    >>> from pyscf import ao2mo
    >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g')
    >>> eri = mol.intor('int2e')
    >>> eri1 = ao2mo.restore(1, eri, mol.nao_nr())
    >>> eri4 = ao2mo.restore(4, eri, mol.nao_nr())
    >>> eri8 = ao2mo.restore(8, eri, mol.nao_nr())
    >>> print(eri1.shape)
    (7, 7, 7, 7)
    >>> print(eri1.shape)
    (28, 28)
    >>> print(eri1.shape)
    (406,)
    '''
    targetsym = _stand_sym_code(symmetry)
    if targetsym not in ('8', '4', '1', '2kl', '2ij'):
        raise ValueError('symmetry = %s' % symmetry)

    if eri.dtype != numpy.double:
        raise RuntimeError('Complex integrals not supported')

    eri = numpy.asarray(eri, order='C')
    npair = norb*(norb+1)//2
    if eri.size == norb**4:  # s1
        if targetsym == '1':
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2kl':
            eri = lib.pack_tril(eri.reshape(norb**2,norb,norb))
            return eri.reshape(norb,norb,npair)
        elif targetsym == '2ij':
            eri = lib.pack_tril(eri.reshape(norb,norb,norb**2), axis=0)
            return eri.reshape(npair,norb,norb)
        else:
            return _convert('1', targetsym, eri, norb)

    elif eri.size == npair**2:  # s4
        if targetsym == '4':
            return eri.reshape(npair,npair)
        elif targetsym == '8':
            return lib.pack_tril(eri.reshape(npair,npair))
        elif targetsym == '2kl':
            return lib.unpack_tril(eri, lib.SYMMETRIC, axis=0)
        elif targetsym == '2ij':
            return lib.unpack_tril(eri, lib.SYMMETRIC, axis=-1)
        else:
            return _convert('4', targetsym, eri, norb)

    elif eri.size == npair*(npair+1)//2: # 8-fold
        if targetsym == '8':
            return eri.ravel()
        elif targetsym == '4':
            return lib.unpack_tril(eri.ravel(), lib.SYMMETRIC)
        elif targetsym == '2kl':
            return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=0)
        elif targetsym == '2ij':
            return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=-1)
        else:
            return _convert('8', targetsym, eri, norb)

    elif eri.size == npair*norb**2 and eri.shape[0] == npair:  # s2ij
        if targetsym == '2ij':
            return eri.reshape(npair,norb,norb)
        elif targetsym == '8':
            eri = lib.pack_tril(eri.reshape(npair,norb,norb))
            return lib.pack_tril(eri)
        elif targetsym == '4':
            return lib.pack_tril(eri.reshape(npair,norb,norb))
        elif targetsym == '1':
            eri = lib.unpack_tril(eri.reshape(npair,norb**2), lib.SYMMETRIC, axis=0)
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2kl':
            tril2sq = lib.square_mat_in_trilu_indices(norb)
            trilidx = numpy.tril_indices(norb)
            eri = lib.take_2d(eri.reshape(npair,norb**2), tril2sq.ravel(),
                              trilidx[0]*norb+trilidx[1])
            return eri.reshape(norb,norb,npair)

    elif eri.size == npair*norb**2 and eri.shape[-1] == npair:  # s2kl
        if targetsym == '2kl':
            return eri.reshape(norb,norb,npair)
        elif targetsym == '8':
            eri = lib.pack_tril(eri.reshape(norb,norb,npair), axis=0)
            return lib.pack_tril(eri)
        elif targetsym == '4':
            return lib.pack_tril(eri.reshape(norb,norb,npair), axis=0)
        elif targetsym == '1':
            eri = lib.unpack_tril(eri.reshape(norb**2,npair), lib.SYMMETRIC, axis=-1)
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2ij':
            tril2sq = lib.square_mat_in_trilu_indices(norb)
            trilidx = numpy.tril_indices(norb)
            eri = lib.take_2d(eri.reshape(norb**2,npair),
                              trilidx[0]*norb+trilidx[1], tril2sq.ravel())
            return eri.reshape(npair,norb,norb)

    else:
        raise RuntimeError('eri.size = %d, norb = %d' % (eri.size, norb))
예제 #32
0
파일: ucisd.py 프로젝트: quansilong/pyscf
def overlap(cibra, ciket, nmo, nocc, s=None):
    '''Overlap between two CISD wavefunctions.

    Args:
        s : a list of 2D arrays
            The overlap matrix of non-orthogonal one-particle basis
    '''
    if s is None:
        return dot(cibra, ciket, nmo, nocc)

    if isinstance(nmo, (int, numpy.integer)):
        nmoa = nmob = nmo
    else:
        nmoa, nmob = nmo
    nocca, noccb = nocc
    nvira, nvirb = nmoa - nocca, nmob - noccb

    bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, (nmoa, nmob), nocc)
    ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, (nmoa, nmob), nocc)

    ooidx = numpy.tril_indices(nocca, -1)
    vvidx = numpy.tril_indices(nvira, -1)
    bra2aa = lib.take_2d(bra2[0].reshape(nocca**2, nvira**2),
                         ooidx[0] * nocca + ooidx[1],
                         vvidx[0] * nvira + vvidx[1])
    ket2aa = lib.take_2d(ket2[0].reshape(nocca**2, nvira**2),
                         ooidx[0] * nocca + ooidx[1],
                         vvidx[0] * nvira + vvidx[1])

    ooidx = numpy.tril_indices(noccb, -1)
    vvidx = numpy.tril_indices(nvirb, -1)
    bra2bb = lib.take_2d(bra2[2].reshape(noccb**2, nvirb**2),
                         ooidx[0] * noccb + ooidx[1],
                         vvidx[0] * nvirb + vvidx[1])
    ket2bb = lib.take_2d(ket2[2].reshape(noccb**2, nvirb**2),
                         ooidx[0] * noccb + ooidx[1],
                         vvidx[0] * nvirb + vvidx[1])

    nova = nocca * nvira
    novb = noccb * nvirb
    occlist0a = numpy.arange(nocca).reshape(1, nocca)
    occlist0b = numpy.arange(noccb).reshape(1, noccb)
    occlistsa = numpy.repeat(occlist0a, 1 + nova + bra2aa.size, axis=0)
    occlistsb = numpy.repeat(occlist0b, 1 + novb + bra2bb.size, axis=0)
    occlist0a = occlistsa[:1]
    occlist1a = occlistsa[1:1 + nova]
    occlist2a = occlistsa[1 + nova:]
    occlist0b = occlistsb[:1]
    occlist1b = occlistsb[1:1 + novb]
    occlist2b = occlistsb[1 + novb:]

    ia = 0
    for i in range(nocca):
        for a in range(nocca, nmoa):
            occlist1a[ia, i] = a
            ia += 1
    ia = 0
    for i in range(noccb):
        for a in range(noccb, nmob):
            occlist1b[ia, i] = a
            ia += 1

    ia = 0
    for i in range(nocca):
        for j in range(i):
            for a in range(nocca, nmoa):
                for b in range(nocca, a):
                    occlist2a[ia, i] = a
                    occlist2a[ia, j] = b
                    ia += 1
    ia = 0
    for i in range(noccb):
        for j in range(i):
            for a in range(noccb, nmob):
                for b in range(noccb, a):
                    occlist2b[ia, i] = a
                    occlist2b[ia, j] = b
                    ia += 1

    na = len(occlistsa)
    trans_a = numpy.empty((na, na))
    for i, idx in enumerate(occlistsa):
        s_sub = s[0][idx].T.copy()
        minors = s_sub[occlistsa]
        trans_a[i, :] = numpy.linalg.det(minors)
    nb = len(occlistsb)
    trans_b = numpy.empty((nb, nb))
    for i, idx in enumerate(occlistsb):
        s_sub = s[1][idx].T.copy()
        minors = s_sub[occlistsb]
        trans_b[i, :] = numpy.linalg.det(minors)

    # Mimic the transformation einsum('ab,ap->pb', FCI, trans).
    # The wavefunction FCI has the [excitation_alpha,excitation_beta]
    # representation.  The zero blocks like FCI[S_alpha,D_beta],
    # FCI[D_alpha,D_beta], are explicitly excluded.
    bra_mat = numpy.zeros((na, nb))
    bra_mat[0, 0] = bra0
    bra_mat[1:1 + nova, 0] = bra1[0].ravel()
    bra_mat[0, 1:1 + novb] = bra1[1].ravel()
    bra_mat[1 + nova:, 0] = bra2aa.ravel()
    bra_mat[0, 1 + novb:] = bra2bb.ravel()
    bra_mat[1:1 + nova, 1:1 + novb] = bra2[1].transpose(0, 2, 1,
                                                        3).reshape(nova, novb)
    c_s = lib.einsum('ab,ap,bq->pq', bra_mat, trans_a, trans_b)
    ovlp = c_s[0, 0] * ket0
    ovlp += numpy.dot(c_s[1:1 + nova, 0], ket1[0].ravel())
    ovlp += numpy.dot(c_s[0, 1:1 + novb], ket1[1].ravel())
    ovlp += numpy.dot(c_s[1 + nova:, 0], ket2aa.ravel())
    ovlp += numpy.dot(c_s[0, 1 + novb:], ket2bb.ravel())
    ovlp += numpy.einsum(
        'ijab,iajb->', ket2[1],
        c_s[1:1 + nova, 1:1 + novb].reshape(nocca, nvira, noccb, nvirb))
    return ovlp
예제 #33
0
def contract_2e(eri,
                fcivec,
                norb,
                nelec,
                link_index=None,
                orbsym=None,
                wfnsym=0):
    if orbsym is None:
        return direct_spin1.contract_2e(eri, fcivec, norb, nelec, link_index)

    eri = ao2mo.restore(4, eri, norb)
    neleca, nelecb = _unpack_nelec(nelec)
    link_indexa, link_indexb = direct_spin1._unpack(norb, nelec, link_index)
    na, nlinka = link_indexa.shape[:2]
    nb, nlinkb = link_indexb.shape[:2]
    eri_irs, rank_eri, irrep_eri = reorder_eri(eri, norb, orbsym)

    strsa = cistring.gen_strings4orblist(range(norb), neleca)
    aidx, link_indexa = gen_str_irrep(strsa, orbsym, link_indexa, rank_eri,
                                      irrep_eri)
    if neleca == nelecb:
        bidx, link_indexb = aidx, link_indexa
    else:
        strsb = cistring.gen_strings4orblist(range(norb), nelecb)
        bidx, link_indexb = gen_str_irrep(strsb, orbsym, link_indexb, rank_eri,
                                          irrep_eri)

    Tirrep = ctypes.c_void_p * TOTIRREPS
    linka_ptr = Tirrep(
        *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa])
    linkb_ptr = Tirrep(
        *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexb])
    eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs])
    dimirrep = (ctypes.c_int * TOTIRREPS)(*[x.shape[0] for x in eri_irs])
    fcivec_shape = fcivec.shape
    fcivec = fcivec.reshape((na, nb), order='C')
    ci1new = numpy.zeros_like(fcivec)
    nas = (ctypes.c_int * TOTIRREPS)(*[x.size for x in aidx])
    nbs = (ctypes.c_int * TOTIRREPS)(*[x.size for x in bidx])

    # aa, ab
    ci0 = []
    ci1 = []
    for ir in range(TOTIRREPS):
        ma, mb = aidx[ir].size, bidx[wfnsym ^ ir].size
        ci0.append(numpy.zeros((ma, mb)))
        ci1.append(numpy.zeros((ma, mb)))
        if ma > 0 and mb > 0:
            lib.take_2d(fcivec, aidx[ir], bidx[wfnsym ^ ir], out=ci0[ir])
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nas, nbs,
                                ctypes.c_int(nlinka), ctypes.c_int(nlinkb),
                                linka_ptr, linkb_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, ci1[ir], aidx[ir], bidx[wfnsym ^ ir])


# bb, ba
    ci0T = []
    for ir in range(TOTIRREPS):
        mb, ma = bidx[ir].size, aidx[wfnsym ^ ir].size
        ci0T.append(numpy.zeros((mb, ma)))
        if ma > 0 and mb > 0:
            lib.transpose(ci0[wfnsym ^ ir], out=ci0T[ir])
    ci0, ci0T = ci0T, None
    ci1 = [numpy.zeros_like(x) for x in ci0]
    ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0])
    ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1])
    libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs,
                                ctypes.c_int(norb), nbs, nas,
                                ctypes.c_int(nlinkb), ctypes.c_int(nlinka),
                                linkb_ptr, linka_ptr, dimirrep,
                                ctypes.c_int(wfnsym))
    for ir in range(TOTIRREPS):
        if ci0[ir].size > 0:
            lib.takebak_2d(ci1new, lib.transpose(ci1[ir]), aidx[wfnsym ^ ir],
                           bidx[ir])
    return ci1new.reshape(fcivec_shape)
예제 #34
0
파일: ucisd.py 프로젝트: chrinide/pyscf
def overlap(cibra, ciket, nmo, nocc, s=None):
    '''Overlap between two CISD wavefunctions.

    Args:
        s : a list of 2D arrays
            The overlap matrix of non-orthogonal one-particle basis
    '''
    if s is None:
        return dot(cibra, ciket, nmo, nocc)

    if isinstance(nmo, (int, numpy.integer)):
        nmoa = nmob = nmo
    else:
        nmoa, nmob = nmo
    nocca, noccb = nocc
    nvira, nvirb = nmoa - nocca, nmob - noccb

    bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, (nmoa,nmob), nocc)
    ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, (nmoa,nmob), nocc)

    ooidx = numpy.tril_indices(nocca, -1)
    vvidx = numpy.tril_indices(nvira, -1)
    bra2aa = lib.take_2d(bra2[0].reshape(nocca**2,nvira**2),
                         ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1])
    ket2aa = lib.take_2d(ket2[0].reshape(nocca**2,nvira**2),
                         ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1])

    ooidx = numpy.tril_indices(noccb, -1)
    vvidx = numpy.tril_indices(nvirb, -1)
    bra2bb = lib.take_2d(bra2[2].reshape(noccb**2,nvirb**2),
                         ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1])
    ket2bb = lib.take_2d(ket2[2].reshape(noccb**2,nvirb**2),
                         ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1])

    nova = nocca * nvira
    novb = noccb * nvirb
    occlist0a = numpy.arange(nocca).reshape(1,nocca)
    occlist0b = numpy.arange(noccb).reshape(1,noccb)
    occlistsa = numpy.repeat(occlist0a, 1+nova+bra2aa.size, axis=0)
    occlistsb = numpy.repeat(occlist0b, 1+novb+bra2bb.size, axis=0)
    occlist0a = occlistsa[:1]
    occlist1a = occlistsa[1:1+nova]
    occlist2a = occlistsa[1+nova:]
    occlist0b = occlistsb[:1]
    occlist1b = occlistsb[1:1+novb]
    occlist2b = occlistsb[1+novb:]

    ia = 0
    for i in range(nocca):
        for a in range(nocca, nmoa):
            occlist1a[ia,i] = a
            ia += 1
    ia = 0
    for i in range(noccb):
        for a in range(noccb, nmob):
            occlist1b[ia,i] = a
            ia += 1

    ia = 0
    for i in range(nocca):
        for j in range(i):
            for a in range(nocca, nmoa):
                for b in range(nocca, a):
                    occlist2a[ia,i] = a
                    occlist2a[ia,j] = b
                    ia += 1
    ia = 0
    for i in range(noccb):
        for j in range(i):
            for a in range(noccb, nmob):
                for b in range(noccb, a):
                    occlist2b[ia,i] = a
                    occlist2b[ia,j] = b
                    ia += 1

    na = len(occlistsa)
    trans_a = numpy.empty((na,na))
    for i, idx in enumerate(occlistsa):
        s_sub = s[0][idx].T.copy()
        minors = s_sub[occlistsa]
        trans_a[i,:] = numpy.linalg.det(minors)
    nb = len(occlistsb)
    trans_b = numpy.empty((nb,nb))
    for i, idx in enumerate(occlistsb):
        s_sub = s[1][idx].T.copy()
        minors = s_sub[occlistsb]
        trans_b[i,:] = numpy.linalg.det(minors)

    # Mimic the transformation einsum('ab,ap->pb', FCI, trans).
    # The wavefunction FCI has the [excitation_alpha,excitation_beta]
    # representation.  The zero blocks like FCI[S_alpha,D_beta],
    # FCI[D_alpha,D_beta], are explicitly excluded.
    bra_mat = numpy.zeros((na,nb))
    bra_mat[0,0] = bra0
    bra_mat[1:1+nova,0] = bra1[0].ravel()
    bra_mat[0,1:1+novb] = bra1[1].ravel()
    bra_mat[1+nova:,0] = bra2aa.ravel()
    bra_mat[0,1+novb:] = bra2bb.ravel()
    bra_mat[1:1+nova,1:1+novb] = bra2[1].transpose(0,2,1,3).reshape(nova,novb)
    c_s = lib.einsum('ab,ap,bq->pq', bra_mat, trans_a, trans_b)
    ovlp  =  c_s[0,0] * ket0
    ovlp += numpy.dot(c_s[1:1+nova,0], ket1[0].ravel())
    ovlp += numpy.dot(c_s[0,1:1+novb], ket1[1].ravel())
    ovlp += numpy.dot(c_s[1+nova:,0] , ket2aa.ravel())
    ovlp += numpy.dot(c_s[0,1+novb:] , ket2bb.ravel())
    ovlp += numpy.einsum('ijab,iajb->', ket2[1],
                         c_s[1:1+nova,1:1+novb].reshape(nocca,nvira,noccb,nvirb))
    return ovlp
예제 #35
0
파일: uccsd_rdm.py 프로젝트: chrinide/pyscf
def _gamma2_outcore(cc, t1, t2, l1, l2, h5fobj, compress_vvvv=False):
    t1a, t1b = t1
    t2aa, t2ab, t2bb = t2
    l1a, l1b = l1
    l2aa, l2ab, l2bb = l2

    tauaa = t2aa + numpy.einsum('ia,jb->ijab', 2*t1a, t1a)
    tauab = t2ab + numpy.einsum('ia,jb->ijab',   t1a, t1b)
    taubb = t2bb + numpy.einsum('ia,jb->ijab', 2*t1b, t1b)
    miajb = einsum('ikac,kjcb->iajb', l2aa, t2aa)
    miajb+= einsum('ikac,jkbc->iajb', l2ab, t2ab)
    miaJB = einsum('ikac,kjcb->iajb', l2aa, t2ab)
    miaJB+= einsum('ikac,kjcb->iajb', l2ab, t2bb)
    mIAjb = einsum('kica,jkbc->iajb', l2bb, t2ab)
    mIAjb+= einsum('kica,kjcb->iajb', l2ab, t2aa)
    mIAJB = einsum('ikac,kjcb->iajb', l2bb, t2bb)
    mIAJB+= einsum('kica,kjcb->iajb', l2ab, t2ab)
    miAjB = einsum('ikca,jkcb->iajb', l2ab, t2ab)
    mIaJb = einsum('kiac,kjbc->iajb', l2ab, t2ab)

    goovv = (l2aa.conj() + tauaa) * .25
    goOvV = (l2ab.conj() + tauab) * .5
    gOOVV = (l2bb.conj() + taubb) * .25

    tmpa  = einsum('kc,kica->ia', l1a, t2aa)
    tmpa += einsum('kc,ikac->ia', l1b, t2ab)
    tmpb  = einsum('kc,kica->ia', l1b, t2bb)
    tmpb += einsum('kc,kica->ia', l1a, t2ab)
    goovv += einsum('ia,jb->ijab', tmpa, t1a)
    goOvV += einsum('ia,jb->ijab', tmpa, t1b) * .5
    goOvV += einsum('ia,jb->jiba', tmpb, t1a) * .5
    gOOVV += einsum('ia,jb->ijab', tmpb, t1b)

    tmpa = einsum('kc,kb->cb', l1a, t1a)
    tmpb = einsum('kc,kb->cb', l1b, t1b)
    goovv += einsum('cb,ijca->ijab', tmpa, t2aa) * .5
    goOvV -= einsum('cb,ijac->ijab', tmpb, t2ab) * .5
    goOvV -= einsum('cb,jica->jiba', tmpa, t2ab) * .5
    gOOVV += einsum('cb,ijca->ijab', tmpb, t2bb) * .5
    tmpa = einsum('kc,jc->kj', l1a, t1a)
    tmpb = einsum('kc,jc->kj', l1b, t1b)
    goovv += einsum('kiab,kj->ijab', tauaa, tmpa) * .5
    goOvV -= einsum('ikab,kj->ijab', tauab , tmpb) * .5
    goOvV -= einsum('kiba,kj->jiba', tauab , tmpa) * .5
    gOOVV += einsum('kiab,kj->ijab', taubb, tmpb) * .5

    tmpa  = numpy.einsum('ldjd->lj', miajb)
    tmpa += numpy.einsum('ldjd->lj', miAjB)
    tmpb  = numpy.einsum('ldjd->lj', mIAJB)
    tmpb += numpy.einsum('ldjd->lj', mIaJb)
    goovv -= einsum('lj,liba->ijab', tmpa, tauaa) * .25
    goOvV -= einsum('lj,ilab->ijab', tmpb, tauab) * .25
    goOvV -= einsum('lj,liba->jiba', tmpa, tauab) * .25
    gOOVV -= einsum('lj,liba->ijab', tmpb, taubb) * .25
    tmpa  = numpy.einsum('ldlb->db', miajb)
    tmpa += numpy.einsum('ldlb->db', mIaJb)
    tmpb  = numpy.einsum('ldlb->db', mIAJB)
    tmpb += numpy.einsum('ldlb->db', miAjB)
    goovv -= einsum('db,jida->ijab', tmpa, tauaa) * .25
    goOvV -= einsum('db,ijad->ijab', tmpb, tauab) * .25
    goOvV -= einsum('db,jida->jiba', tmpa, tauab) * .25
    gOOVV -= einsum('db,jida->ijab', tmpb, taubb) * .25

    goovv -= einsum('ldia,ljbd->ijab', miajb, tauaa) * .5
    goovv += einsum('LDia,jLbD->ijab', mIAjb, t2ab ) * .5
    gOOVV -= einsum('ldia,ljbd->ijab', mIAJB, taubb) * .5
    gOOVV += einsum('ldia,ljdb->ijab', miaJB, t2ab ) * .5
    goOvV -= einsum('LDia,LJBD->iJaB', mIAjb, taubb) * .25
    goOvV += einsum('ldia,lJdB->iJaB', miajb, t2ab ) * .25
    goOvV -= einsum('ldIA,ljbd->jIbA', miaJB, tauaa) * .25
    goOvV += einsum('LDIA,jLbD->jIbA', mIAJB, t2ab ) * .25
    goOvV += einsum('lDiA,lJbD->iJbA', miAjB, tauab) * .5
    goOvV += einsum('LdIa,jd,LB->jIaB', mIaJb, t1a, t1b) * .5

    tmpaa = einsum('klcd,ijcd->ijkl', l2aa, tauaa) * .25**2
    tmpbb = einsum('klcd,ijcd->ijkl', l2bb, taubb) * .25**2
    tmpabab = einsum('kLcD,iJcD->iJkL', l2ab, tauab) * .5
    goovv += einsum('ijkl,klab->ijab', tmpaa, tauaa)
    goOvV += einsum('ijkl,klab->ijab', tmpabab, tauab)
    gOOVV += einsum('ijkl,klab->ijab', tmpbb, taubb)
    goovv = goovv.conj()
    goOvV = goOvV.conj()
    gOOVV = gOOVV.conj()

    gvvvv = einsum('ijab,ijcd->abcd', tauaa, l2aa) * .125
    gvVvV = einsum('ijab,ijcd->abcd', tauab, l2ab) * .25
    gVVVV = einsum('ijab,ijcd->abcd', taubb, l2bb) * .125

    goooo = einsum('ijab,klab->ijkl', l2aa, tauaa) * .125
    goOoO = einsum('ijab,klab->ijkl', l2ab, tauab) * .25
    gOOOO = einsum('ijab,klab->ijkl', l2bb, taubb) * .125

    gooov = einsum('jkba,ib->jkia', tauaa, -0.25 * l1a)
    goOoV = einsum('jkba,ib->jkia', tauab, -0.5  * l1a)
    gOoOv = einsum('kjab,ib->jkia', tauab, -0.5  * l1b)
    gOOOV = einsum('jkba,ib->jkia', taubb, -0.25 * l1b)

    gooov += einsum('iljk,la->jkia', goooo, t1a)
    goOoV += einsum('iljk,la->jkia', goOoO, t1b) * 2
    gOoOv += einsum('likj,la->jkia', goOoO, t1a) * 2
    gOOOV += einsum('iljk,la->jkia', gOOOO, t1b)

    tmpa  = numpy.einsum('icjc->ij', miajb) * .25
    tmpa += numpy.einsum('icjc->ij', miAjB) * .25
    tmpb  = numpy.einsum('icjc->ij', mIAJB) * .25
    tmpb += numpy.einsum('icjc->ij', mIaJb) * .25
    gooov -= einsum('ij,ka->jkia', tmpa, t1a)
    goOoV -= einsum('ij,ka->jkia', tmpa, t1b)
    gOoOv -= einsum('ij,ka->jkia', tmpb, t1a)
    gOOOV -= einsum('ij,ka->jkia', tmpb, t1b)

    gooov += einsum('icja,kc->jkia', miajb, .5 * t1a)
    goOoV += einsum('icja,kc->jkia', miAjB, .5 * t1b)
    goOoV -= einsum('icJA,kc->kJiA', miaJB, .5 * t1a)
    gOoOv += einsum('icja,kc->jkia', mIaJb, .5 * t1a)
    gOoOv -= einsum('ICja,KC->KjIa', mIAjb, .5 * t1b)
    gOOOV += einsum('icja,kc->jkia', mIAJB, .5 * t1b)

    gooov = gooov.conj()
    goOoV = goOoV.conj()
    gOoOv = gOoOv.conj()
    gOOOV = gOOOV.conj()
    gooov += einsum('jkab,ib->jkia', l2aa, .25*t1a)
    goOoV -= einsum('jkba,ib->jkia', l2ab, .5 *t1a)
    gOoOv -= einsum('kjab,ib->jkia', l2ab, .5 *t1b)
    gOOOV += einsum('jkab,ib->jkia', l2bb, .25*t1b)

    govvv = einsum('ja,ijcb->iacb', .25 * l1a, tauaa)
    goVvV = einsum('ja,ijcb->iacb', .5  * l1b, tauab)
    gOvVv = einsum('ja,jibc->iacb', .5  * l1a, tauab)
    gOVVV = einsum('ja,ijcb->iacb', .25 * l1b, taubb)

    govvv += einsum('bcad,id->iabc', gvvvv, t1a)
    goVvV -= einsum('bcda,id->iabc', gvVvV, t1a) * 2
    gOvVv -= einsum('cbad,id->iabc', gvVvV, t1b) * 2
    gOVVV += einsum('bcad,id->iabc', gVVVV, t1b)

    tmpa  = numpy.einsum('kakb->ab', miajb) * .25
    tmpa += numpy.einsum('kakb->ab', mIaJb) * .25
    tmpb  = numpy.einsum('kakb->ab', mIAJB) * .25
    tmpb += numpy.einsum('kakb->ab', miAjB) * .25
    govvv += einsum('ab,ic->iacb', tmpa, t1a)
    goVvV += einsum('ab,ic->iacb', tmpb, t1a)
    gOvVv += einsum('ab,ic->iacb', tmpa, t1b)
    gOVVV += einsum('ab,ic->iacb', tmpb, t1b)

    govvv += einsum('kaib,kc->iabc', miajb, .5 * t1a)
    goVvV += einsum('KAib,KC->iAbC', mIAjb, .5 * t1b)
    goVvV -= einsum('kAiB,kc->iAcB', miAjB, .5 * t1a)
    gOvVv += einsum('kaIB,kc->IaBc', miaJB, .5 * t1a)
    gOvVv -= einsum('KaIb,KC->IaCb', mIaJb, .5 * t1b)
    gOVVV += einsum('kaib,kc->iabc', mIAJB, .5 * t1b)
    govvv = govvv.conj()
    goVvV = goVvV.conj()
    gOvVv = gOvVv.conj()
    gOVVV = gOVVV.conj()
    govvv += einsum('ijbc,ja->iabc', l2aa, .25*t1a)
    goVvV += einsum('iJbC,JA->iAbC', l2ab, .5 *t1b)
    gOvVv += einsum('jIcB,ja->IaBc', l2ab, .5 *t1a)
    gOVVV += einsum('ijbc,ja->iabc', l2bb, .25*t1b)

    govvo = einsum('ia,jb->ibaj', l1a, t1a)
    goVvO = einsum('ia,jb->ibaj', l1a, t1b)
    gOvVo = einsum('ia,jb->ibaj', l1b, t1a)
    gOVVO = einsum('ia,jb->ibaj', l1b, t1b)

    govvo += numpy.einsum('iajb->ibaj', miajb)
    goVvO += numpy.einsum('iajb->ibaj', miaJB)
    gOvVo += numpy.einsum('iajb->ibaj', mIAjb)
    gOVVO += numpy.einsum('iajb->ibaj', mIAJB)
    goVoV = numpy.einsum('iajb->ibja', miAjB)
    gOvOv = numpy.einsum('iajb->ibja', mIaJb)

    govvo -= einsum('ikac,jc,kb->ibaj', l2aa, t1a, t1a)
    goVvO -= einsum('iKaC,JC,KB->iBaJ', l2ab, t1b, t1b)
    gOvVo -= einsum('kIcA,jc,kb->IbAj', l2ab, t1a, t1a)
    gOVVO -= einsum('ikac,jc,kb->ibaj', l2bb, t1b, t1b)
    goVoV += einsum('iKcA,jc,KB->iBjA', l2ab, t1a, t1b)
    gOvOv += einsum('kIaC,JC,kb->IbJa', l2ab, t1b, t1a)

    dovov = goovv.transpose(0,2,1,3) - goovv.transpose(0,3,1,2)
    dvvvv = gvvvv.transpose(0,2,1,3) - gvvvv.transpose(0,3,1,2)
    doooo = goooo.transpose(0,2,1,3) - goooo.transpose(0,3,1,2)
    dovvv = govvv.transpose(0,2,1,3) - govvv.transpose(0,3,1,2)
    dooov = gooov.transpose(0,2,1,3) - gooov.transpose(1,2,0,3)
    dovvo = govvo.transpose(0,2,1,3)
    dovov =(dovov + dovov.transpose(2,3,0,1)) * .5
    dvvvv = dvvvv + dvvvv.transpose(1,0,3,2).conj()
    doooo = doooo + doooo.transpose(1,0,3,2).conj()
    dovvo =(dovvo + dovvo.transpose(3,2,1,0).conj()) * .5
    doovv =-dovvo.transpose(0,3,2,1)
    dvvov = None

    dOVOV = gOOVV.transpose(0,2,1,3) - gOOVV.transpose(0,3,1,2)
    dVVVV = gVVVV.transpose(0,2,1,3) - gVVVV.transpose(0,3,1,2)
    dOOOO = gOOOO.transpose(0,2,1,3) - gOOOO.transpose(0,3,1,2)
    dOVVV = gOVVV.transpose(0,2,1,3) - gOVVV.transpose(0,3,1,2)
    dOOOV = gOOOV.transpose(0,2,1,3) - gOOOV.transpose(1,2,0,3)
    dOVVO = gOVVO.transpose(0,2,1,3)
    dOVOV =(dOVOV + dOVOV.transpose(2,3,0,1)) * .5
    dVVVV = dVVVV + dVVVV.transpose(1,0,3,2).conj()
    dOOOO = dOOOO + dOOOO.transpose(1,0,3,2).conj()
    dOVVO =(dOVVO + dOVVO.transpose(3,2,1,0).conj()) * .5
    dOOVV =-dOVVO.transpose(0,3,2,1)
    dVVOV = None

    dovOV = goOvV.transpose(0,2,1,3)
    dvvVV = gvVvV.transpose(0,2,1,3) * 2
    dooOO = goOoO.transpose(0,2,1,3) * 2
    dovVV = goVvV.transpose(0,2,1,3)
    dooOV = goOoV.transpose(0,2,1,3)
    dovVO = goVvO.transpose(0,2,1,3)

    dOVvv = gOvVv.transpose(0,2,1,3)
    dOOov = gOoOv.transpose(0,2,1,3)
    dOVvo = gOvVo.transpose(0,2,1,3)
    dooVV = goVoV.transpose(0,2,1,3)
    dOOvv = gOvOv.transpose(0,2,1,3)

    dvvVV = dvvVV + dvvVV.transpose(1,0,3,2).conj()
    dooOO = dooOO + dooOO.transpose(1,0,3,2).conj()
    dovVO = (dovVO + dOVvo.transpose(3,2,1,0).conj()) * .5
    dooVV =-(dooVV + dooVV.transpose(1,0,3,2).conj()) * .5
    dvvOV = None

    dOVov = None
    dVVvv = None
    dOOoo = None
    dOVvo =  dovVO.transpose(3,2,1,0).conj()
    dOOvv =-(dOOvv + dOOvv.transpose(1,0,3,2).conj()) * .5
    dVVov = None

    if compress_vvvv:
        nocca, noccb, nvira, nvirb = t2ab.shape
        idxa = numpy.tril_indices(nvira)
        idxa = idxa[0] * nvira + idxa[1]
        idxb = numpy.tril_indices(nvirb)
        idxb = idxb[0] * nvirb + idxb[1]
        dvvvv = dvvvv + dvvvv.transpose(1,0,2,3)
        dvvvv = lib.take_2d(dvvvv.reshape(nvira**2,nvira**2), idxa, idxa)
        dvvvv *= .5
        dvvVV = dvvVV + dvvVV.transpose(1,0,2,3)
        dvvVV = lib.take_2d(dvvVV.reshape(nvira**2,nvirb**2), idxa, idxb)
        dvvVV *= .5
        dVVVV = dVVVV + dVVVV.transpose(1,0,2,3)
        dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2,nvirb**2), idxb, idxb)
        dVVVV *= .5

    return ((dovov, dovOV, dOVov, dOVOV),
            (dvvvv, dvvVV, dVVvv, dVVVV),
            (doooo, dooOO, dOOoo, dOOOO),
            (doovv, dooVV, dOOvv, dOOVV),
            (dovvo, dovVO, dOVvo, dOVVO),
            (dvvov, dvvOV, dVVov, dVVOV),
            (dovvv, dovVV, dOVvv, dOVVV),
            (dooov, dooOV, dOOov, dOOOV))
예제 #36
0
파일: uccsd.py 프로젝트: wmizukami/pyscf
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None):
    cput0 = (time.clock(), time.time())
    eris = _ChemistsERIs()
    eris._common_init_(mycc, mo_coeff)

    nocca, noccb = mycc.nocc
    nmoa, nmob = mycc.nmo
    nvira, nvirb = nmoa-nocca, nmob-noccb

    moa = eris.mo_coeff[0]
    mob = eris.mo_coeff[1]
    nmoa = moa.shape[1]
    nmob = mob.shape[1]

    if callable(ao2mofn):
        eri_aa = ao2mofn(moa).reshape([nmoa]*4)
        eri_bb = ao2mofn(mob).reshape([nmob]*4)
        eri_ab = ao2mofn((moa,moa,mob,mob))
    else:
        eri_aa = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, moa), nmoa)
        eri_bb = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, mob), nmob)
        eri_ab = ao2mo.general(mycc._scf._eri, (moa,moa,mob,mob), compact=False)
    eri_ba = eri_ab.reshape(nmoa,nmoa,nmob,nmob).transpose(2,3,0,1)

    eri_aa = eri_aa.reshape(nmoa,nmoa,nmoa,nmoa)
    eri_ab = eri_ab.reshape(nmoa,nmoa,nmob,nmob)
    eri_ba = eri_ba.reshape(nmob,nmob,nmoa,nmoa)
    eri_bb = eri_bb.reshape(nmob,nmob,nmob,nmob)
    eris.oooo = eri_aa[:nocca,:nocca,:nocca,:nocca].copy()
    eris.ovoo = eri_aa[:nocca,nocca:,:nocca,:nocca].copy()
    eris.ovov = eri_aa[:nocca,nocca:,:nocca,nocca:].copy()
    eris.oovv = eri_aa[:nocca,:nocca,nocca:,nocca:].copy()
    eris.ovvo = eri_aa[:nocca,nocca:,nocca:,:nocca].copy()
    eris.ovvv = eri_aa[:nocca,nocca:,nocca:,nocca:].copy()
    eris.vvvv = eri_aa[nocca:,nocca:,nocca:,nocca:].copy()

    eris.OOOO = eri_bb[:noccb,:noccb,:noccb,:noccb].copy()
    eris.OVOO = eri_bb[:noccb,noccb:,:noccb,:noccb].copy()
    eris.OVOV = eri_bb[:noccb,noccb:,:noccb,noccb:].copy()
    eris.OOVV = eri_bb[:noccb,:noccb,noccb:,noccb:].copy()
    eris.OVVO = eri_bb[:noccb,noccb:,noccb:,:noccb].copy()
    eris.OVVV = eri_bb[:noccb,noccb:,noccb:,noccb:].copy()
    eris.VVVV = eri_bb[noccb:,noccb:,noccb:,noccb:].copy()

    eris.ooOO = eri_ab[:nocca,:nocca,:noccb,:noccb].copy()
    eris.ovOO = eri_ab[:nocca,nocca:,:noccb,:noccb].copy()
    eris.ovOV = eri_ab[:nocca,nocca:,:noccb,noccb:].copy()
    eris.ooVV = eri_ab[:nocca,:nocca,noccb:,noccb:].copy()
    eris.ovVO = eri_ab[:nocca,nocca:,noccb:,:noccb].copy()
    eris.ovVV = eri_ab[:nocca,nocca:,noccb:,noccb:].copy()
    eris.vvVV = eri_ab[nocca:,nocca:,noccb:,noccb:].copy()

    #eris.OOoo = eri_ba[:noccb,:noccb,:nocca,:nocca].copy()
    eris.OVoo = eri_ba[:noccb,noccb:,:nocca,:nocca].copy()
    #eris.OVov = eri_ba[:noccb,noccb:,:nocca,nocca:].copy()
    eris.OOvv = eri_ba[:noccb,:noccb,nocca:,nocca:].copy()
    eris.OVvo = eri_ba[:noccb,noccb:,nocca:,:nocca].copy()
    eris.OVvv = eri_ba[:noccb,noccb:,nocca:,nocca:].copy()
    #eris.VVvv = eri_ba[noccb:,noccb:,nocca:,nocca:].copy()

    if not callable(ao2mofn):
        ovvv = eris.ovvv.reshape(nocca*nvira,nvira,nvira)
        eris.ovvv = lib.pack_tril(ovvv).reshape(nocca,nvira,nvira*(nvira+1)//2)
        eris.vvvv = ao2mo.restore(4, eris.vvvv, nvira)

        OVVV = eris.OVVV.reshape(noccb*nvirb,nvirb,nvirb)
        eris.OVVV = lib.pack_tril(OVVV).reshape(noccb,nvirb,nvirb*(nvirb+1)//2)
        eris.VVVV = ao2mo.restore(4, eris.VVVV, nvirb)

        ovVV = eris.ovVV.reshape(nocca*nvira,nvirb,nvirb)
        eris.ovVV = lib.pack_tril(ovVV).reshape(nocca,nvira,nvirb*(nvirb+1)//2)
        vvVV = eris.vvVV.reshape(nvira**2,nvirb**2)
        idxa = np.tril_indices(nvira)
        idxb = np.tril_indices(nvirb)
        eris.vvVV = lib.take_2d(vvVV, idxa[0]*nvira+idxa[1], idxb[0]*nvirb+idxb[1])

        OVvv = eris.OVvv.reshape(noccb*nvirb,nvira,nvira)
        eris.OVvv = lib.pack_tril(OVvv).reshape(noccb,nvirb,nvira*(nvira+1)//2)
    return eris
예제 #37
0
파일: rccsd.py 프로젝트: zwang123/pyscf
def _make_eris_outcore(mycc, mo_coeff=None):
    cput0 = (time.clock(), time.time())
    log = logger.Logger(mycc.stdout, mycc.verbose)
    eris = _ChemistsERIs()
    eris._common_init_(mycc, mo_coeff)

    mol = mycc.mol
    mo_coeff = eris.mo_coeff
    nocc = eris.nocc
    nao, nmo = mo_coeff.shape
    nvir = nmo - nocc
    orbo = mo_coeff[:, :nocc]
    orbv = mo_coeff[:, nocc:]
    nvpair = nvir * (nvir + 1) // 2
    eris.feri1 = lib.H5TmpFile()
    eris.oooo = eris.feri1.create_dataset('oooo', (nocc, nocc, nocc, nocc),
                                          'f8')
    eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc, nvir, nocc, nocc),
                                          'f8',
                                          chunks=(nocc, 1, nocc, nocc))
    eris.ovov = eris.feri1.create_dataset('ovov', (nocc, nvir, nocc, nvir),
                                          'f8',
                                          chunks=(nocc, 1, nocc, nvir))
    eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc, nvir, nvir, nocc),
                                          'f8',
                                          chunks=(nocc, 1, nvir, nocc))
    eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc, nvir, nvir, nvir),
                                          'f8',
                                          chunks=(nocc, 1, nvir, nvir))
    eris.oovv = eris.feri1.create_dataset('oovv', (nocc, nocc, nvir, nvir),
                                          'f8',
                                          chunks=(nocc, nocc, 1, nvir))
    eris.vvvv = eris.feri1.create_dataset('vvvv', (nvir, nvir, nvir, nvir),
                                          'f8')
    max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0])

    ftmp = lib.H5TmpFile()
    ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log)
    eri = ftmp['eri_mo']

    nocc_pair = nocc * (nocc + 1) // 2
    tril2sq = lib.square_mat_in_trilu_indices(nmo)
    oo = eri[:nocc_pair]
    eris.oooo[:] = ao2mo.restore(1, oo[:, :nocc_pair], nocc)
    oovv = lib.take_2d(oo, tril2sq[:nocc, :nocc].ravel(),
                       tril2sq[nocc:, nocc:].ravel())
    eris.oovv[:] = oovv.reshape(nocc, nocc, nvir, nvir)
    oo = oovv = None

    tril2sq = lib.square_mat_in_trilu_indices(nmo)
    blksize = min(nvir, max(BLKMIN, int(max_memory * 1e6 / 8 / nmo**3 / 2)))
    for p0, p1 in lib.prange(0, nvir, blksize):
        q0, q1 = p0 + nocc, p1 + nocc
        off0 = q0 * (q0 + 1) // 2
        off1 = q1 * (q1 + 1) // 2
        buf = lib.unpack_tril(eri[off0:off1])

        tmp = buf[tril2sq[q0:q1, :nocc] - off0]
        eris.ovoo[:, p0:p1] = tmp[:, :, :nocc, :nocc].transpose(1, 0, 2, 3)
        eris.ovvo[:, p0:p1] = tmp[:, :, nocc:, :nocc].transpose(1, 0, 2, 3)
        eris.ovov[:, p0:p1] = tmp[:, :, :nocc, nocc:].transpose(1, 0, 2, 3)
        eris.ovvv[:, p0:p1] = tmp[:, :, nocc:, nocc:].transpose(1, 0, 2, 3)

        tmp = buf[tril2sq[q0:q1, nocc:q1] - off0]
        eris.vvvv[p0:p1, :p1] = tmp[:, :, nocc:, nocc:]
        if p0 > 0:
            eris.vvvv[:p0, p0:p1] = tmp[:, :p0, nocc:,
                                        nocc:].transpose(1, 0, 2, 3)
        buf = tmp = None
    log.timer('CCSD integral transformation', *cput0)
    return eris
예제 #38
0
def _gamma2_intermediates(mycc, t1, t2, l1, l2, eris=None,
                          compress_vvvv=False):
    d2 = uccsd_rdm._gamma2_intermediates(mycc, t1, t2, l1, l2)

    if eris is None: eris = mycc.ao2mo()

    dovov, dovOV, dOVov, dOVOV = d2[0]
    dvvvv, dvvVV, dVVvv, dVVVV = d2[1]
    doooo, dooOO, dOOoo, dOOOO = d2[2]
    doovv, dooVV, dOOvv, dOOVV = d2[3]
    dovvo, dovVO, dOVvo, dOVVO = d2[4]
    dvvov, dvvOV, dVVov, dVVOV = d2[5]
    dovvv, dovVV, dOVvv, dOVVV = d2[6]
    dooov, dooOV, dOOov, dOOOV = d2[7]

    t1a, t1b = t1
    t2aa, t2ab, t2bb = t2
    nocca, noccb, nvira, nvirb = t2ab.shape
    nmoa = eris.focka.shape[0]
    nmob = eris.fockb.shape[0]
    mo_ea, mo_eb = eris.mo_energy
    eia = mo_ea[:nocca,None] - mo_ea[nocca:]
    eIA = mo_eb[:noccb,None] - mo_eb[noccb:]
    fvo = eris.focka[nocca:,:nocca]
    fVO = eris.fockb[noccb:,:noccb]

    # aaa
    d3 = lib.direct_sum('ia+jb+kc->ijkabc', eia, eia, eia)
    w = numpy.einsum('ijae,kceb->ijkabc', t2aa, numpy.asarray(eris.get_ovvv()).conj())
    w-= numpy.einsum('mkbc,iajm->ijkabc', t2aa, numpy.asarray(eris.ovoo.conj()))
    v = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.ovov).conj(), t1a)
    v+= numpy.einsum('jkbc,ai->ijkabc', t2aa, fvo) * .5

    rw = r6(p6(w)) / d3
    wvd = r6(p6(w * 2 + v)) / d3
    dovov += numpy.einsum('ia,ijkabc->jbkc', t1a, rw.conj()) * 0.25
# *(1/8) instead of (1/4) because ooov appears 4 times in the 2pdm tensor due
# to symmetrization, and its contribution is scaled by 1/2 in Tr(H,2pdm)
    dooov -= numpy.einsum('mkbc,ijkabc->jmia', t2aa, wvd.conj()) * .125
    dovvv += numpy.einsum('kjcf,ijkabc->iafb', t2aa, wvd.conj()) * .125

    # bbb
    d3 = lib.direct_sum('ia+jb+kc->ijkabc', eIA, eIA, eIA)
    w = numpy.einsum('ijae,kceb->ijkabc', t2bb, numpy.asarray(eris.get_OVVV()).conj())
    w-= numpy.einsum('imab,kcjm->ijkabc', t2bb, numpy.asarray(eris.OVOO.conj()))
    v = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.OVOV).conj(), t1b)
    v+= numpy.einsum('jkbc,ai->ijkabc', t2bb, fVO) * .5

    rw = r6(p6(w)) / d3
    wvd = r6(p6(w * 2 + v)) / d3
    dOVOV += numpy.einsum('ia,ijkabc->jbkc', t1b, rw.conj()) * .25
    dOOOV -= numpy.einsum('mkbc,ijkabc->jmia', t2bb, wvd.conj()) * .125
    dOVVV += numpy.einsum('kjcf,ijkabc->iafb', t2bb, wvd.conj()) * .125

    # baa
    d3 = lib.direct_sum('ia+jb+kc->ijkabc', eIA, eia, eia)
    w  = numpy.einsum('jIeA,kceb->IjkAbc', t2ab, numpy.asarray(eris.get_ovvv()).conj()) * 2
    w += numpy.einsum('jIbE,kcEA->IjkAbc', t2ab, numpy.asarray(eris.get_ovVV()).conj()) * 2
    w += numpy.einsum('jkbe,IAec->IjkAbc', t2aa, numpy.asarray(eris.get_OVvv()).conj())
    w -= numpy.einsum('mIbA,kcjm->IjkAbc', t2ab, numpy.asarray(eris.ovoo).conj()) * 2
    w -= numpy.einsum('jMbA,kcIM->IjkAbc', t2ab, numpy.asarray(eris.ovOO).conj()) * 2
    w -= numpy.einsum('jmbc,IAkm->IjkAbc', t2aa, numpy.asarray(eris.OVoo).conj())
    v  = numpy.einsum('jbkc,IA->IjkAbc', numpy.asarray(eris.ovov).conj(), t1b)
    v += numpy.einsum('kcIA,jb->IjkAbc', numpy.asarray(eris.ovOV).conj(), t1a)
    v += numpy.einsum('kcIA,jb->IjkAbc', numpy.asarray(eris.ovOV).conj(), t1a)
    v += numpy.einsum('jkbc,AI->IjkAbc', t2aa, fVO) * .5
    v += numpy.einsum('kIcA,bj->IjkAbc', t2ab, fvo) * 2

    rw = r4(w) / d3
    wvd = r4(w * 2 + v) / d3
    dovvv += numpy.einsum('jiea,ijkabc->kceb', t2ab, wvd.conj()) * .25
    dovVV += numpy.einsum('jibe,ijkabc->kcea', t2ab, wvd.conj()) * .25
    dOVvv += numpy.einsum('jkbe,ijkabc->iaec', t2aa, wvd.conj()) * .125
    dooov -= numpy.einsum('miba,ijkabc->jmkc', t2ab, wvd.conj()) * .25
    dOOov -= numpy.einsum('jmba,ijkabc->imkc', t2ab, wvd.conj()) * .25
    dooOV -= numpy.einsum('jmbc,ijkabc->kmia', t2aa, wvd.conj()) * .125
    dovov += numpy.einsum('ia,ijkabc->jbkc', t1b, rw.conj()) * .25
    #dOVov += numpy.einsum('jb,ijkabc->iakc', t1a, rw.conj()) * .25
    dovOV += numpy.einsum('jb,ijkabc->kcia', t1a, rw.conj()) * .25

    # bba
    d3 = lib.direct_sum('ia+jb+kc->ijkabc', eia, eIA, eIA)
    w  = numpy.einsum('ijae,kceb->ijkabc', t2ab, numpy.asarray(eris.get_OVVV()).conj()) * 2
    w += numpy.einsum('ijeb,kcea->ijkabc', t2ab, numpy.asarray(eris.get_OVvv()).conj()) * 2
    w += numpy.einsum('jkbe,iaec->ijkabc', t2bb, numpy.asarray(eris.get_ovVV()).conj())
    w -= numpy.einsum('imab,kcjm->ijkabc', t2ab, numpy.asarray(eris.OVOO).conj()) * 2
    w -= numpy.einsum('mjab,kcim->ijkabc', t2ab, numpy.asarray(eris.OVoo).conj()) * 2
    w -= numpy.einsum('jmbc,iakm->ijkabc', t2bb, numpy.asarray(eris.ovOO).conj())
    v  = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.OVOV).conj(), t1a)
    v += numpy.einsum('iakc,jb->ijkabc', numpy.asarray(eris.ovOV).conj(), t1b)
    v += numpy.einsum('iakc,jb->ijkabc', numpy.asarray(eris.ovOV).conj(), t1b)
    v += numpy.einsum('JKBC,ai->iJKaBC', t2bb, fvo) * .5
    v += numpy.einsum('iKaC,BJ->iJKaBC', t2ab, fVO) * 2

    rw = r4(w) / d3
    wvd = r4(w * 2 + v) / d3
    dOVVV += numpy.einsum('ijae,ijkabc->kceb', t2ab, wvd.conj()) * .25
    dOVvv += numpy.einsum('ijeb,ijkabc->kcea', t2ab, wvd.conj()) * .25
    dovVV += numpy.einsum('jkbe,ijkabc->iaec', t2bb, wvd.conj()) * .125
    dOOOV -= numpy.einsum('imab,ijkabc->jmkc', t2ab, wvd.conj()) * .25
    dooOV -= numpy.einsum('mjab,ijkabc->imkc', t2ab, wvd.conj()) * .25
    dOOov -= numpy.einsum('jmbc,ijkabc->kmia', t2bb, wvd.conj()) * .125
    dOVOV += numpy.einsum('ia,ijkabc->jbkc', t1a, rw.conj()) * .25
    dovOV += numpy.einsum('jb,ijkabc->iakc', t1b, rw.conj()) * .25
    #dOVov += numpy.einsum('jb,ijkabc->kcia', t1b, rw.conj()) * .25

    if compress_vvvv:
        nmoa, nmob = mycc.nmo
        nocca, noccb, nvira, nvirb = t2ab.shape
        idxa = numpy.tril_indices(nvira)
        idxa = idxa[0] * nvira + idxa[1]
        idxb = numpy.tril_indices(nvirb)
        idxb = idxb[0] * nvirb + idxb[1]
        dvvvv = dvvvv + dvvvv.transpose(1,0,2,3)
        dvvvv = lib.take_2d(dvvvv.reshape(nvira**2,nvira**2), idxa, idxa)
        dvvvv *= .5
        dvvVV = dvvVV + dvvVV.transpose(1,0,2,3)
        dvvVV = lib.take_2d(dvvVV.reshape(nvira**2,nvirb**2), idxa, idxb)
        dVVVV = dVVVV + dVVVV.transpose(1,0,2,3)
        dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2,nvirb**2), idxb, idxb)
        dVVVV *= .5

        d2 = ((dovov, dovOV, dOVov, dOVOV),
              (dvvvv, dvvVV, dVVvv, dVVVV),
              (doooo, dooOO, dOOoo, dOOOO),
              (doovv, dooVV, dOOvv, dOOVV),
              (dovvo, dovVO, dOVvo, dOVVO),
              (dvvov, dvvOV, dVVov, dVVOV),
              (dovvv, dovVV, dOVvv, dOVVV),
              (dooov, dooOV, dOOov, dOOOV))

    return d2
예제 #39
0
파일: addons.py 프로젝트: chrinide/pyscf
def restore(symmetry, eri, norb, tao=None):
    r'''Convert the 2e integrals (in Chemist's notation) between different
    level of permutation symmetry (8-fold, 4-fold, or no symmetry)

    Args:
        symmetry : int or str
            code to present the target symmetry of 2e integrals

            | 's8' or '8' or 8 : 8-fold symmetry
            | 's4' or '4' or 4 : 4-fold symmetry
            | 's1' or '1' or 1 : no symmetry
            | 's2ij' or '2ij' : symmetric ij pair for (ij|kl) (TODO)
            | 's2ij' or '2kl' : symmetric kl pair for (ij|kl) (TODO)

            Note the 4-fold symmetry requires (ij|kl) == (ij|lk) == (ij|lk)
            while (ij|kl) != (kl|ij) is not required.

        eri : ndarray
            The symmetry of eri is determined by the size of eri and norb
        norb : int
            The symmetry of eri is determined by the size of eri and norb

    Returns:
        ndarray.  The shape depends on the target symmetry.

            | 8 : (norb*(norb+1)/2)*(norb*(norb+1)/2+1)/2
            | 4 : (norb*(norb+1)/2, norb*(norb+1)/2)
            | 1 : (norb, norb, norb, norb)

    Examples:

    >>> from pyscf import gto
    >>> from pyscf.scf import _vhf
    >>> from pyscf import ao2mo
    >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g')
    >>> eri = mol.intor('int2e')
    >>> eri1 = ao2mo.restore(1, eri, mol.nao_nr())
    >>> eri4 = ao2mo.restore(4, eri, mol.nao_nr())
    >>> eri8 = ao2mo.restore(8, eri, mol.nao_nr())
    >>> print(eri1.shape)
    (7, 7, 7, 7)
    >>> print(eri1.shape)
    (28, 28)
    >>> print(eri1.shape)
    (406,)
    '''
    targetsym = _stand_sym_code(symmetry)
    if targetsym not in ('8', '4', '1', '2kl', '2ij'):
        raise ValueError('symmetry = %s' % symmetry)

    if eri.dtype != numpy.double:
        raise RuntimeError('Complex integrals not supported')

    eri = numpy.asarray(eri, order='C')
    npair = norb*(norb+1)//2
    if eri.size == norb**4:  # s1
        if targetsym == '1':
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2kl':
            eri = lib.pack_tril(eri.reshape(norb**2,norb,norb))
            return eri.reshape(norb,norb,npair)
        elif targetsym == '2ij':
            eri = lib.pack_tril(eri.reshape(norb,norb,norb**2), axis=0)
            return eri.reshape(npair,norb,norb)
        else:
            return _convert('1', targetsym, eri, norb)

    elif eri.size == npair**2:  # s4
        if targetsym == '4':
            return eri.reshape(npair,npair)
        elif targetsym == '8':
            return lib.pack_tril(eri.reshape(npair,npair))
        elif targetsym == '2kl':
            return lib.unpack_tril(eri, lib.SYMMETRIC, axis=0)
        elif targetsym == '2ij':
            return lib.unpack_tril(eri, lib.SYMMETRIC, axis=-1)
        else:
            return _convert('4', targetsym, eri, norb)

    elif eri.size == npair*(npair+1)//2: # 8-fold
        if targetsym == '8':
            return eri.ravel()
        elif targetsym == '4':
            return lib.unpack_tril(eri.ravel(), lib.SYMMETRIC)
        elif targetsym == '2kl':
            return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=0)
        elif targetsym == '2ij':
            return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=-1)
        else:
            return _convert('8', targetsym, eri, norb)

    elif eri.size == npair*norb**2 and eri.shape[0] == npair:  # s2ij
        if targetsym == '2ij':
            return eri.reshape(npair,norb,norb)
        elif targetsym == '8':
            eri = lib.pack_tril(eri.reshape(npair,norb,norb))
            return lib.pack_tril(eri)
        elif targetsym == '4':
            return lib.pack_tril(eri.reshape(npair,norb,norb))
        elif targetsym == '1':
            eri = lib.unpack_tril(eri.reshape(npair,norb**2), lib.SYMMETRIC, axis=0)
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2kl':
            tril2sq = lib.square_mat_in_trilu_indices(norb)
            trilidx = numpy.tril_indices(norb)
            eri = lib.take_2d(eri.reshape(npair,norb**2), tril2sq.ravel(),
                              trilidx[0]*norb+trilidx[1])
            return eri.reshape(norb,norb,npair)

    elif eri.size == npair*norb**2 and eri.shape[-1] == npair:  # s2kl
        if targetsym == '2kl':
            return eri.reshape(norb,norb,npair)
        elif targetsym == '8':
            eri = lib.pack_tril(eri.reshape(norb,norb,npair), axis=0)
            return lib.pack_tril(eri)
        elif targetsym == '4':
            return lib.pack_tril(eri.reshape(norb,norb,npair), axis=0)
        elif targetsym == '1':
            eri = lib.unpack_tril(eri.reshape(norb**2,npair), lib.SYMMETRIC, axis=-1)
            return eri.reshape(norb,norb,norb,norb)
        elif targetsym == '2ij':
            tril2sq = lib.square_mat_in_trilu_indices(norb)
            trilidx = numpy.tril_indices(norb)
            eri = lib.take_2d(eri.reshape(norb**2,npair),
                              trilidx[0]*norb+trilidx[1], tril2sq.ravel())
            return eri.reshape(npair,norb,norb)

    else:
        raise RuntimeError('eri.size = %d, norb = %d' % (eri.size, norb))
예제 #40
0
def contract_2e(eri, civec_strs, norb, nelec, link_index=None):
    ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec)
    if link_index is None:
        link_index = _all_linkstr_index(ci_strs, norb, nelec)
    cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index
    na, nlinka = cd_indexa.shape[:2]
    nb, nlinkb = cd_indexb.shape[:2]

    eri = ao2mo.restore(1, eri, norb)
    eri1 = eri.transpose(0, 2, 1, 3) - eri.transpose(0, 2, 3, 1)
    idx, idy = numpy.tril_indices(norb, -1)
    idx = idx * norb + idy
    eri1 = lib.take_2d(eri1.reshape(norb**2, -1), idx, idx) * 2
    fcivec = ci_coeff.reshape(na, nb)
    # (bb|bb)
    if nelec[1] > 1:
        mb, mlinkb = dd_indexb.shape[:2]
        fcivecT = lib.transpose(fcivec)
        ci1T = numpy.zeros((nb, na))
        libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p),
                                   fcivecT.ctypes.data_as(ctypes.c_void_p),
                                   ci1T.ctypes.data_as(ctypes.c_void_p),
                                   ctypes.c_int(norb), ctypes.c_int(nb),
                                   ctypes.c_int(na), ctypes.c_int(mb),
                                   ctypes.c_int(mlinkb),
                                   dd_indexb.ctypes.data_as(ctypes.c_void_p))
        ci1 = lib.transpose(ci1T, out=fcivecT)
    else:
        ci1 = numpy.zeros_like(fcivec)
    # (aa|aa)
    if nelec[0] > 1:
        ma, mlinka = dd_indexa.shape[:2]
        libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p),
                                   fcivec.ctypes.data_as(ctypes.c_void_p),
                                   ci1.ctypes.data_as(ctypes.c_void_p),
                                   ctypes.c_int(norb), ctypes.c_int(na),
                                   ctypes.c_int(nb), ctypes.c_int(ma),
                                   ctypes.c_int(mlinka),
                                   dd_indexa.ctypes.data_as(ctypes.c_void_p))

    # Adding h_ps below to because contract_2e function computes the
    # contraction  "E_{pq}E_{rs} V_{pqrs} |CI>" (~ p^+ q r^+ s |CI>) while
    # the actual contraction for (aa|aa) and (bb|bb) part is
    # "p^+ r^+ s q V_{pqrs} |CI>". To make (aa|aa) and (bb|bb) code reproduce
    # "p^+ q r^+ s |CI>", we employ the identity
    #    p^+ q r^+ s = p^+ r^+ s q  +  delta(qr) p^+ s
    # the second term is the source of h_ps
    h_ps = numpy.einsum('pqqs->ps', eri)
    eri1 = eri * 2
    for k in range(norb):
        eri1[:, :, k, k] += h_ps / nelec[0]
        eri1[k, k, :, :] += h_ps / nelec[1]
    eri1 = ao2mo.restore(4, eri1, norb)
    # (bb|aa)
    libfci.SCIcontract_2e_bbaa(eri1.ctypes.data_as(ctypes.c_void_p),
                               fcivec.ctypes.data_as(ctypes.c_void_p),
                               ci1.ctypes.data_as(ctypes.c_void_p),
                               ctypes.c_int(norb), ctypes.c_int(na),
                               ctypes.c_int(nb), ctypes.c_int(nlinka),
                               ctypes.c_int(nlinkb),
                               cd_indexa.ctypes.data_as(ctypes.c_void_p),
                               cd_indexb.ctypes.data_as(ctypes.c_void_p))

    return _as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)