def from_fci(ci0, nmoa_nmob, nocca_noccb): from pyscf import fci from pyscf.ci.cisd_slow import t2strs norba, norbb = nmoa_nmob nocca, noccb = nocca_noccb nvira = norba - nocca nvirb = norbb - noccb t1addra, t1signa = cisd.t1strs(norba, nocca) t1addrb, t1signb = cisd.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] c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra][:, t1addrb]) c2ab = c2ab.reshape(nvira, nocca, nvirb, noccb).transpose(1, 3, 0, 2) c2ab = c2ab[::-1, ::-1] t2addra, t2signa = t2strs(norba, nocca) c2aa = (ci0[t2addra, 0] * t2signa).reshape(nvira * (nvira - 1) // 2, -1).T c2aa = _unpack_4fold(c2aa[::-1], nocca, nvira) t2addrb, t2signb = t2strs(norbb, noccb) c2bb = (ci0[0, t2addrb] * t2signb).reshape(nvirb * (nvirb - 1) // 2, -1).T c2bb = _unpack_4fold(c2bb[::-1], noccb, nvirb) return amplitudes_to_cisdvec(c0, (c1a, c1b), (c2aa, c2ab, c2bb))
def from_fcivec(ci0, norb, nelec, frozen=0): from pyscf.ci.gcisd import t2strs if frozen is not 0: raise NotImplementedError if isinstance(nelec, (int, numpy.number)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec norba = norbb = norb nocc = nocca, noccb = neleca, nelecb nvira = norba - nocca nvirb = norbb - noccb t1addra, t1signa = cisd.t1strs(norba, nocca) t1addrb, t1signb = cisd.t1strs(norbb, noccb) na = cistring.num_strings(norba, nocca) nb = cistring.num_strings(norbb, noccb) ci0 = ci0.reshape(na, nb) c0 = ci0[0, 0] c1a = ((ci0[t1addra, 0] * t1signa).reshape(nvira, nocca).T)[::-1] c1b = ((ci0[0, t1addrb] * t1signb).reshape(nvirb, noccb).T)[::-1] c2ab = numpy.einsum('i,j,ij->ij', t1signa, t1signb, ci0[t1addra][:, t1addrb]) c2ab = c2ab.reshape(nvira, nocca, nvirb, noccb).transpose(1, 3, 0, 2) c2ab = c2ab[::-1, ::-1] t2addra, t2signa = t2strs(norba, nocca) c2aa = (ci0[t2addra, 0] * t2signa).reshape(nvira * (nvira - 1) // 2, -1).T c2aa = _unpack_4fold(c2aa[::-1], nocca, nvira) t2addrb, t2signb = t2strs(norbb, noccb) c2bb = (ci0[0, t2addrb] * t2signb).reshape(nvirb * (nvirb - 1) // 2, -1).T c2bb = _unpack_4fold(c2bb[::-1], noccb, nvirb) return amplitudes_to_cisdvec(c0, (c1a, c1b), (c2aa, c2ab, c2bb))
def to_fci(cisdvec, nmoa_nmob, nocca_noccb): from pyscf import fci from pyscf.ci.cisd_slow import t2strs norba, norbb = nmoa_nmob nocca, noccb = nocca_noccb nvira = norba - nocca nvirb = norbb - noccb c0, c1, c2 = cisdvec_to_amplitudes(cisdvec, nmoa_nmob, nocca_noccb) c1a, c1b = c1 c2aa, c2ab, c2bb = c2 t1addra, t1signa = cisd.t1strs(norba, nocca) t1addrb, t1signb = cisd.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 to_fcivec(cisdvec, norb, nelec, frozen=0): from pyscf.ci.gcisd import t2strs 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.t1strs(nmoa, nocca) t1addrb, t1signb = cisd.t1strs(nmob, noccb) 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[::-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(nmoa, 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(nmob, noccb) fcivec[0, t2addrb] = c2bb[::-1].T.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