Ejemplo n.º 1
0
def to_fci(cisdvec, nelec, orbspin):
    from pyscf import fci
    nocc = nelec
    norb = len(orbspin)
    c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nocc, norb - nocc)
    oidxa = orbspin[:nocc] == 0
    oidxb = orbspin[:nocc] == 1
    vidxa = orbspin[nocc:] == 0
    vidxb = orbspin[nocc:] == 1
    c1a = c1[oidxa][:, vidxa]
    c1b = c1[oidxb][:, vidxb]
    c2aa = c2[oidxa][:, oidxa][:, :, vidxa][:, :, :, vidxa]
    c2bb = c2[oidxb][:, oidxb][:, :, vidxb][:, :, :, vidxb]
    c2ab = c2[oidxa][:, oidxb][:, :, vidxa][:, :, :, vidxb]
    nocca = numpy.count_nonzero(oidxa)
    noccb = numpy.count_nonzero(oidxb)
    nvira = numpy.count_nonzero(vidxa)
    nvirb = numpy.count_nonzero(vidxb)
    norba = nocca + nvira
    norbb = noccb + nvirb
    t1addra, t1signa = t1strs(norba, nocca)
    t1addrb, t1signb = t1strs(norbb, noccb)

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

    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 = t2strs(norba, nocca)
        fcivec[t2addra, 0] = c2aa[::-1].T.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 = t2strs(norbb, noccb)
        fcivec[0, t2addrb] = c2bb[::-1].T.ravel() * t2signb
    return fcivec
Ejemplo n.º 2
0
def from_fci(ci0, nelec, orbspin):
    from pyscf.cc.addons import spatial2spin
    nocc = nelec
    oidxa = orbspin[:nocc] == 0
    oidxb = orbspin[:nocc] == 1
    vidxa = orbspin[nocc:] == 0
    vidxb = orbspin[nocc:] == 1
    nocca = numpy.count_nonzero(oidxa)
    noccb = numpy.count_nonzero(oidxb)
    nvira = numpy.count_nonzero(vidxa)
    nvirb = numpy.count_nonzero(vidxb)
    norba = nocca + nvira
    norbb = noccb + nvirb
    t1addra, t1signa = t1strs(norba, nocca)
    t1addrb, t1signb = t1strs(norbb, noccb)

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

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

    cisdvec = amplitudes_to_cisdvec(c0, c1, c2)
    return cisdvec