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
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