Пример #1
0
def from_fcivec(ci0, norb, nelec, frozen=0):
    '''Extract CISD coefficients from FCI coefficients'''
    if frozen is not 0:
        raise NotImplementedError
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

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

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

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

    return amplitudes_to_cisdvec(c0, (c1a,c1b), (c2aa,c2ab,c2bb))
Пример #2
0
def from_fcivec(ci0, norb, nelec, frozen=0):
    '''Extract CISD coefficients from FCI coefficients'''
    if frozen is not 0:
        raise NotImplementedError
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

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

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

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

    return amplitudes_to_cisdvec(c0, (c1a,c1b), (c2aa,c2ab,c2bb))
Пример #3
0
def to_fcivec(cisdvec, norb, nelec, frozen=0):
    '''Convert CISD coefficients to FCI coefficients'''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

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

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

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

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

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

    if nfroza == nfrozb == 0:
        return fcivec

    assert(norb < 63)

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

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

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

    sub_strsa = strsa[core_a_mask & (count_a == nocca)]
    sub_strsb = strsb[core_b_mask & (count_b == noccb)]
    addrsa = cistring.strs2addr(norb, neleca, sub_strsa)
    addrsb = cistring.strs2addr(norb, nelecb, sub_strsb)
    fcivec1 = numpy.zeros((na,nb))
    fcivec1[addrsa[:,None],addrsb] = fcivec
    fcivec1[parity_a,:] *= -1
    fcivec1[:,parity_b] *= -1
    return fcivec1
Пример #4
0
from pyscf.ci.cisd import tn_addrs_signs

mol = gto.Mole()
mol.atom = [
    ['O', ( 0., 0.    , 0.   )],
    ['H', ( 0., -0.857, 0.587)],
    ['H', ( 0., 0.757 , 0.687)],]
mol.basis = '321g'
mol.build()
mf = scf.RHF(mol).run()
e, fcivec = fci.FCI(mf).kernel(verbose=5)

nmo = mol.nao
nocc = mol.nelectron // 2

t1addrs, t1signs = tn_addrs_signs(nmo, nocc, 1)
t2addrs, t2signs = tn_addrs_signs(nmo, nocc, 2)
t3addrs, t3signs = tn_addrs_signs(nmo, nocc, 3)
t4addrs, t4signs = tn_addrs_signs(nmo, nocc, 4)

# CIS includes two types of amplitudes: alpha -> alpha and beta -> beta
cis_a = fcivec[t1addrs, 0] * t1signs
cis_b = fcivec[0, t1addrs] * t1signs

# CID has:
#    alpha,alpha -> alpha,alpha
#    alpha,beta  -> alpha,beta
#    beta ,beta  -> beta ,beta
# For alpha,alpha -> alpha,alpha excitations, the redundant coefficients are
# excluded. The number of coefficients is nocc*(nocc-1)//2 * nvir*(nvir-1)//2,
# which corresponds to C2_{ijab}, i > j and a > b.
Пример #5
0
def to_fcivec(cisdvec, norb, nelec, frozen=0):
    '''Convert CISD coefficients to FCI coefficients'''
    if isinstance(nelec, (int, numpy.number)):
        nelecb = nelec//2
        neleca = nelec - nelecb
    else:
        neleca, nelecb = nelec

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

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

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

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

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

    if nfroza == nfrozb == 0:
        return fcivec

    assert(norb < 63)

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

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

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

    sub_strsa = strsa[core_a_mask & (count_a == nocca)]
    sub_strsb = strsb[core_b_mask & (count_b == noccb)]
    addrsa = cistring.strs2addr(norb, neleca, sub_strsa)
    addrsb = cistring.strs2addr(norb, nelecb, sub_strsb)
    fcivec1 = numpy.zeros((na,nb))
    fcivec1[addrsa[:,None],addrsb] = fcivec
    fcivec1[parity_a,:] *= -1
    fcivec1[:,parity_b] *= -1
    return fcivec1