def kernel(self, h1e, eri, norb, nelec, ci0=None, tol=None, lindep=None, max_cycle=None, max_space=None, nroots=None, davidson_only=None, pspace_size=None, orbsym=None, wfnsym=None, ecore=0, **kwargs): if nroots is None: nroots = self.nroots if orbsym is None: orbsym = self.orbsym if wfnsym is None: wfnsym = self.wfnsym if self.verbose >= logger.WARN: self.check_sanity() with lib.temporary_env(self, orbsym=orbsym, wfnsym=wfnsym): e, c = selected_ci.kernel_float_space(self, h1e, eri, norb, nelec, ci0, tol, lindep, max_cycle, max_space, nroots, davidson_only, ecore=ecore, **kwargs) if wfnsym is not None: wfnsym0 = self.guess_wfnsym(norb, nelec, ci0, orbsym, wfnsym, **kwargs) strsa, strsb = c._strs if nroots > 1: for i, ci in enumerate(c): ci = addons._symmetrize_wfn(ci, strsa, strsb, self.orbsym, wfnsym0) c[i] = selected_ci._as_SCIvector(ci, c._strs) else: ci = addons._symmetrize_wfn(c, strsa, strsb, self.orbsym, wfnsym0) c = selected_ci._as_SCIvector(ci, c._strs) self.eci, self.ci = e, c return e, c
def test_rdm(self): norb, nelec = 10, 4 strs = cistring.gen_strings4orblist(range(norb), nelec) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .6 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .7 strsb = strs[mask] ci_strs = (strsa, strsb) ci_coeff = selected_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) ci0 = selected_ci.to_fci(ci_coeff, norb, (nelec, nelec)) dm1ref, dm2ref = direct_spin1.make_rdm12s(ci0, norb, (nelec, nelec)) dm1 = selected_ci.make_rdm1s(ci_coeff, norb, (nelec, nelec)) self.assertAlmostEqual(abs(dm1[0] - dm1ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm1[1] - dm1ref[1]).sum(), 0, 9) dm2 = selected_ci.make_rdm2s(ci_coeff, norb, (nelec, nelec)) self.assertAlmostEqual(abs(dm2[0] - dm2ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm2[1] - dm2ref[1]).sum(), 0, 9) self.assertAlmostEqual(abs(dm2[2] - dm2ref[2]).sum(), 0, 9) ci1_coeff = selected_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) ci1 = selected_ci.to_fci(ci1_coeff, norb, (nelec, nelec)) dm1ref, dm2ref = direct_spin1.trans_rdm12s(ci1, ci0, norb, (nelec, nelec)) dm1 = selected_ci.trans_rdm1s(ci1_coeff, ci_coeff, norb, (nelec, nelec)) self.assertAlmostEqual(abs(dm1[0] - dm1ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm1[1] - dm1ref[1]).sum(), 0, 9)
def test_rdm_2e(self): norb, nelec = 10, 1 strs = cistring.make_strings(range(norb), nelec) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .6 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .7 strsb = strs[mask] ci_strs = (strsa, strsb) ci_coeff = selected_ci._as_SCIvector(numpy.random.random((len(strsa),len(strsb))), ci_strs) ci0 = selected_ci.to_fci(ci_coeff, norb, (nelec,nelec)) dm1ref, dm2ref = direct_spin1.make_rdm12s(ci0, norb, (nelec,nelec)) dm1 = selected_ci.make_rdm1s(ci_coeff, norb, (nelec,nelec)) self.assertAlmostEqual(abs(dm1[0]-dm1ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm1[1]-dm1ref[1]).sum(), 0, 9) dm2 = selected_ci.make_rdm2s(ci_coeff, norb, (nelec,nelec)) self.assertAlmostEqual(abs(dm2[0]-dm2ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm2[1]-dm2ref[1]).sum(), 0, 9) self.assertAlmostEqual(abs(dm2[2]-dm2ref[2]).sum(), 0, 9) ci1_coeff = selected_ci._as_SCIvector(numpy.random.random((len(strsa),len(strsb))), ci_strs) ci1 = selected_ci.to_fci(ci1_coeff, norb, (nelec,nelec)) dm1ref, dm2ref = direct_spin1.trans_rdm12s(ci1, ci0, norb, (nelec,nelec)) dm1 = selected_ci.trans_rdm1s(ci1_coeff, ci_coeff, norb, (nelec,nelec)) self.assertAlmostEqual(abs(dm1[0]-dm1ref[0]).sum(), 0, 9) self.assertAlmostEqual(abs(dm1[1]-dm1ref[1]).sum(), 0, 9)
def test_contract_2e_symm(self): norb, nelec = 7, (4, 4) strs = cistring.gen_strings4orblist(range(norb), nelec[0]) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .3 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .2 strsb = strs[mask] ci_strs = (strsa, strsb) civec_strs = selected_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) orbsym = (numpy.random.random(norb) * 4).astype(int) nn = norb * (norb + 1) // 2 eri = ao2mo.restore(1, (numpy.random.random(nn * (nn + 1) // 2) - .2)**3, norb) oosym = orbsym[:, None] ^ orbsym oosym = oosym.reshape(-1, 1) ^ oosym.ravel() eri[oosym.reshape([norb] * 4) != 0] = 0 ci0 = fci.selected_ci.to_fci(civec_strs, norb, nelec) ci0 = fci.addons.symmetrize_wfn(ci0, norb, nelec, orbsym) civec_strs = fci.selected_ci.from_fci(ci0, civec_strs._strs, norb, nelec) e1 = numpy.dot( civec_strs.ravel(), selected_ci_symm.contract_2e(eri, civec_strs, norb, nelec, orbsym=orbsym).ravel()) e2 = numpy.dot( ci0.ravel(), direct_spin1_symm.contract_2e(eri, ci0, norb, nelec, orbsym=orbsym).ravel()) self.assertAlmostEqual(e1, e2, 9)
def test_spin0_contract_2e_symm(self): norb, nelec = 7, (4,4) strs = cistring.make_strings(range(norb), nelec[0]) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .3 strsa = strs[mask] ci_strs = (strsa, strsa) na = len(strsa) ci_coeff = numpy.random.random((na,na)) ci_coeff = ci_coeff + ci_coeff.T civec_strs = selected_ci._as_SCIvector(ci_coeff, ci_strs) orbsym = (numpy.random.random(norb) * 4).astype(int) nn = norb*(norb+1)//2 eri = ao2mo.restore(1, (numpy.random.random(nn*(nn+1)//2)-.2)**3, norb) oosym = orbsym[:,None] ^ orbsym oosym = oosym.reshape(-1,1) ^ oosym.ravel() eri[oosym.reshape([norb]*4)!=0] = 0 ci0 = fci.selected_ci.to_fci(civec_strs, norb, nelec) ci0 = fci.addons.symmetrize_wfn(ci0, norb, nelec, orbsym) civec_strs = fci.selected_ci.from_fci(ci0, civec_strs._strs, norb, nelec) myci = selected_ci_spin0_symm.SCI() e1 = numpy.dot(civec_strs.ravel(), myci.contract_2e(eri, civec_strs, norb, nelec, orbsym=orbsym).ravel()) e2 = numpy.dot(ci0.ravel(), direct_spin1_symm.contract_2e(eri, ci0, norb, nelec, orbsym=orbsym).ravel()) self.assertAlmostEqual(e1, e2, 9)
def test_guess_wfnsym(self): norb, nelec = 7, (4, 4) strs = cistring.make_strings(range(norb), nelec[0]) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .3 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .2 strsb = strs[mask] ci_strs = (strsa, strsb) ci0 = selected_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) fake_mol = gto.M() fake_mol.groupname = 'C2v' cis = selected_ci_symm.SelectedCI(fake_mol) cis.orbsym = orbsym = (numpy.random.random(norb) * 4).astype(int) self.assertEqual(cis.guess_wfnsym(norb, nelec), 0) self.assertEqual(cis.guess_wfnsym(norb, nelec, ci0), 3) self.assertEqual(cis.guess_wfnsym(norb, nelec, ci0, wfnsym=0), 0) self.assertEqual(cis.guess_wfnsym(norb, nelec, ci0, wfnsym='B2'), 3) ci0[:] = 0 self.assertRaises(RuntimeError, cis.guess_wfnsym, norb, nelec, ci0, wfnsym=1)
def get_init_guess(self, ci_strs, norb, nelec, nroots, hdiag): '''Initial guess is the single Slater determinant ''' wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.wfnsym) airreps = direct_spin1_symm._gen_strs_irrep(ci_strs[0], self.orbsym) birreps = direct_spin1_symm._gen_strs_irrep(ci_strs[1], self.orbsym) ci0 = direct_spin1_symm._get_init_guess(airreps, birreps, nroots, hdiag, self.orbsym, wfnsym) return [selected_ci._as_SCIvector(x, ci_strs) for x in ci0]
def get_init_guess(self, ci_strs, norb, nelec, nroots, hdiag): '''Initial guess is the single Slater determinant ''' wfnsym = direct_spin1_symm._id_wfnsym(self, norb, nelec, self.orbsym, self.wfnsym) airreps = direct_spin1_symm._gen_strs_irrep(ci_strs[0], self.orbsym) birreps = direct_spin1_symm._gen_strs_irrep(ci_strs[1], self.orbsym) ci0 = direct_spin1_symm._get_init_guess(airreps, birreps, nroots, hdiag, self.orbsym, wfnsym) return [selected_ci._as_SCIvector(x, ci_strs) for x in ci0]
def contract_2e(self, eri, civec_strs, norb, nelec, link_index=None, orbsym=None, **kwargs): if orbsym is None: orbsym = self.orbsym if getattr(civec_strs, '_strs', None) is not None: self._strs = civec_strs._strs else: assert(civec_strs.size == len(self._strs[0])*len(self._strs[1])) civec_strs = selected_ci._as_SCIvector(civec_strs, self._strs) return contract_2e(eri, civec_strs, norb, nelec, link_index, orbsym)
def contract_2e(self, eri, civec_strs, norb, nelec, link_index=None, **kwargs): # The argument civec_strs is a CI vector in function FCISolver.contract_2e. # Save and patch self._strs to make this contract_2e function compatible to # FCISolver.contract_2e. if hasattr(civec_strs, '_strs'): self._strs = civec_strs._strs else: assert(civec_strs.size == len(self._strs[0])*len(self._strs[1])) civec_strs = selected_ci._as_SCIvector(civec_strs, self._strs) return contract_2e(eri, civec_strs, norb, nelec, link_index)
def contract_2e(self, eri, civec_strs, norb, nelec, link_index=None, **kwargs): # The argument civec_strs is a CI vector in function FCISolver.contract_2e. # Save and patch self._strs to make this contract_2e function compatible to # FCISolver.contract_2e. if getattr(civec_strs, '_strs', None) is not None: self._strs = civec_strs._strs else: assert(civec_strs.size == len(self._strs[0])*len(self._strs[1])) civec_strs = selected_ci._as_SCIvector(civec_strs, self._strs) return contract_2e(eri, civec_strs, norb, nelec, link_index)
def test_spin0_contract(self): myci = selected_ci_spin0.SCI() civec_strs = selected_ci._as_SCIvector(spin0_ci_coeff, spin0_ci_strs) ci0 = selected_ci.to_fci(civec_strs, norb, nelec) e1 = numpy.dot(civec_strs.ravel(), myci.contract_2e(eri, civec_strs, norb, nelec).ravel()) eref = numpy.dot(ci0.ravel(), direct_spin1.contract_2e(eri, ci0, norb, nelec).ravel()) self.assertAlmostEqual(e1, eref, 9) e2 = numpy.dot(civec_strs.ravel(), myci.contract_2e(eri, spin0_ci_coeff, norb, nelec).ravel()) self.assertAlmostEqual(e2, eref, 9)
def contract_2e(self, eri, civec_strs, norb, nelec, link_index=None, orbsym=None, **kwargs): if orbsym is None: orbsym = self.orbsym if hasattr(civec_strs, '_strs'): self._strs = civec_strs._strs else: assert(civec_strs.size == len(self._strs[0])*len(self._strs[1])) civec_strs = selected_ci._as_SCIvector(civec_strs, self._strs) return contract_2e(eri, civec_strs, norb, nelec, link_index, orbsym)
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)
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)
def test_spin_square(self): norb, nelec = 10, 4 strs = cistring.make_strings(range(norb), nelec) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .6 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .7 strsb = strs[mask] ci_strs = (strsa, strsb) ci_coeff = selected_ci._as_SCIvector(numpy.random.random((len(strsa),len(strsb))), ci_strs) ci0 = selected_ci.to_fci(ci_coeff, norb, (nelec,nelec)) ss0 = selected_ci.spin_square(ci_coeff, norb, (nelec,nelec)) ss1 = spin_op.spin_square0(ci0, norb, (nelec,nelec)) self.assertAlmostEqual(ss0[0], ss1[0], 9)
def test_contract_2e_1(self): myci = selected_ci.SCI() nelec = (4,3) strsa = cistring.make_strings(range(norb), nelec[0]) strsb = cistring.make_strings(range(norb), nelec[1]) ci0 = selected_ci._as_SCIvector(numpy.random.random((len(strsa),len(strsb))), (strsa,strsb)) h2 = ao2mo.restore(1, eri, norb) c1 = myci.contract_2e(h2, ci0, norb, nelec) c2 = direct_spin1.contract_2e(h2, ci0, norb, nelec) self.assertAlmostEqual(float(abs(c1-c2).sum()), 0, 9) dm1_1 = myci.make_rdm1(c1, norb, nelec) dm1_2 = direct_spin1.make_rdm1(c2, norb, nelec) self.assertAlmostEqual(abs(dm1_1 - dm1_2).sum(), 0, 9) dm2_1 = myci.make_rdm12(c1, norb, nelec)[1] dm2_2 = direct_spin1.make_rdm12(c2, norb, nelec)[1] self.assertAlmostEqual(abs(dm2_1 - dm2_2).sum(), 0, 9)
def setUpModule(): global ci_strs, ci_coeff, civec_strs, eri, h1, spin0_ci_strs, spin0_ci_coeff global norb, nelec norb = 6 nelec = 6 na = cistring.num_strings(norb, nelec // 2) ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b1101]] numpy.random.seed(12) ci_coeff = (numpy.random.random( (len(ci_strs[0]), len(ci_strs[1]))) - .2)**3 civec_strs = selected_ci._as_SCIvector(ci_coeff, ci_strs) nn = norb * (norb + 1) // 2 eri = (numpy.random.random(nn * (nn + 1) // 2) - .2)**3 h1 = numpy.random.random((norb, norb)) h1 = h1 + h1.T spin0_ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b10101]] spin0_ci_coeff = ci_coeff + ci_coeff.T
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = selected_ci._unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = selected_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 = selected_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(selected_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
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = selected_ci._unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = selected_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 = selected_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(selected_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
from pyscf.fci import direct_spin1 from pyscf.fci import direct_spin1_symm from pyscf.fci import selected_ci from pyscf.fci import selected_ci_symm from pyscf.fci import spin_op from pyscf.fci import selected_ci_spin0 from pyscf.fci import selected_ci_spin0_symm from pyscf.fci import selected_ci_slow norb = 6 nelec = 6 na = cistring.num_strings(norb, nelec//2) ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b1101]] numpy.random.seed(12) ci_coeff = (numpy.random.random((len(ci_strs[0]),len(ci_strs[1])))-.2)**3 civec_strs = selected_ci._as_SCIvector(ci_coeff, ci_strs) nn = norb*(norb+1)//2 eri = (numpy.random.random(nn*(nn+1)//2)-.2)**3 h1 = numpy.random.random((norb,norb)) h1 = h1 + h1.T spin0_ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b10101]] spin0_ci_coeff = ci_coeff + ci_coeff.T def finger(a): return numpy.dot(a.ravel(), numpy.cos(numpy.arange(a.size))) def tearDownModule(): global ci_strs, ci_coeff, civec_strs, eri, h1, spin0_ci_strs, spin0_ci_coeff del ci_strs, ci_coeff, civec_strs, eri, h1, spin0_ci_strs, spin0_ci_coeff
from functools import reduce from pyscf import gto from pyscf import scf from pyscf import ao2mo from pyscf import symm from pyscf.fci import cistring norb, nelec = 7, (4, 4) strs = cistring.gen_strings4orblist(range(norb), nelec[0]) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .3 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .2 strsb = strs[mask] ci_strs = (strsa, strsb) civec_strs = selected_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) orbsym = (numpy.random.random(norb) * 4).astype(int) nn = norb * (norb + 1) // 2 eri = (numpy.random.random(nn * (nn + 1) // 2) - .2)**3 ci0 = selected_ci.to_fci(civec_strs, norb, nelec) ci0 = addons.symmetrize_wfn(ci0, norb, nelec, orbsym) civec_strs = selected_ci.from_fci(ci0, civec_strs._strs, norb, nelec) e1 = numpy.dot( civec_strs.ravel(), contract_2e(eri, civec_strs, norb, nelec, orbsym=orbsym).ravel()) e2 = numpy.dot( ci0.ravel(), direct_spin1_symm.contract_2e(eri, ci0, norb, nelec, orbsym=orbsym).ravel()) print(e1 - e2)
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 = cd_indexa.shape[:2] nb, nlinkb = cd_indexb.shape[:2] ma, mlinka = dd_indexa.shape[:2] mb, mlinkb = dd_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 eri1, dd_indexa, dimirrep = reorder4irrep(eri1, norb, dd_indexa, orbsym, -1) dd_indexb = reorder4irrep(eri1, norb, dd_indexb, orbsym, -1)[1] fcivec = ci_coeff.reshape(na, nb) # (bb|bb) if nelec[1] > 1: fcivecT = lib.transpose(fcivec) ci1T = numpy.zeros((nb, na)) libfci.SCIcontract_2e_aaaa_symm( 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), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) ci1 = lib.transpose(ci1T, out=fcivecT) else: ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: 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) 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) eri1, cd_indexa, dimirrep = reorder4irrep(eri1, norb, cd_indexa, orbsym) cd_indexb = reorder4irrep(eri1, norb, cd_indexb, orbsym)[1] # (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_indexb.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) return selected_ci._as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
from functools import reduce from pyscf import gto from pyscf import scf from pyscf import ao2mo from pyscf import symm from pyscf.fci import cistring norb, nelec = 7, (4,4) strs = cistring.gen_strings4orblist(range(norb), nelec[0]) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .3 strsa = strs[mask] mask = numpy.random.random(len(strs)) > .2 strsb = strs[mask] ci_strs = (strsa, strsb) civec_strs = selected_ci._as_SCIvector(numpy.random.random((len(strsa),len(strsb))), ci_strs) orbsym = (numpy.random.random(norb) * 4).astype(int) nn = norb*(norb+1)//2 eri = (numpy.random.random(nn*(nn+1)//2)-.2)**3 ci0 = selected_ci.to_fci(civec_strs, norb, nelec) ci0 = addons.symmetrize_wfn(ci0, norb, nelec, orbsym) civec_strs = selected_ci.from_fci(ci0, civec_strs._strs, norb, nelec) e1 = numpy.dot(civec_strs.ravel(), contract_2e(eri, civec_strs, norb, nelec, orbsym=orbsym).ravel()) e2 = numpy.dot(ci0.ravel(), direct_spin1_symm.contract_2e(eri, ci0, norb, nelec, orbsym=orbsym).ravel()) print(e1-e2) mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [
from pyscf import fci from pyscf import lib from pyscf.fci import cistring from pyscf.fci import direct_spin1 from pyscf.fci import direct_spin1_symm from pyscf.fci import selected_ci from pyscf.fci import selected_ci_symm from pyscf.fci import spin_op norb = 6 nelec = 6 na = cistring.num_strings(norb, nelec // 2) ci_strs = [[0b111, 0b1011, 0b10101], [0b111, 0b1011, 0b1101]] numpy.random.seed(12) ci_coeff = (numpy.random.random((len(ci_strs[0]), len(ci_strs[1]))) - .2)**3 civec_strs = selected_ci._as_SCIvector(ci_coeff, ci_strs) nn = norb * (norb + 1) // 2 eri = (numpy.random.random(nn * (nn + 1) // 2) - .2)**3 h1 = numpy.random.random((norb, norb)) h1 = h1 + h1.T def finger(a): return numpy.dot(a.ravel(), numpy.cos(numpy.arange(a.size))) class KnownValues(unittest.TestCase): def test_select_strs(self): myci = selected_ci.SCI() myci.select_cutoff = 1e-3 norb, nelec = 10, 4