def ftsolver(h1e,g2e,norb,nelec,T,mu=0,symm='UHF', Tmin=1.e-3,\ dcompl=False,**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver h1e = h1e[0] g2e = g2e[1] elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if isinstance(nelec, (int, np.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec na = cistring.num_strings(norb, neleca) nb = cistring.num_strings(norb, nelecb) nelec = (neleca, nelecb) ne = neleca + nelecb ndim = na * nb if T < Tmin: e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) z = np.exp(-(e - mu * ne) / T) return np.asarray(RDM1) * ndim, np.asarray(RDM2) * ndim, e * ndim ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver) rdm1, rdm2 = [], [] RDM1 = np.zeros((2, norb, norb)) RDM2 = np.zeros((3, norb, norb, norb, norb)) Z = np.sum(np.exp(-(ew - mu * ne) / T)) E = np.sum(np.exp(-(ew - mu * ne) / T) * ew) # not normalized #print Z, E for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, nelec) RDM1 += np.asarray(dm1) * np.exp(-(ew[i] - mu * ne) / T) RDM2 += np.asarray(dm2) * np.exp(-(ew[i] - mu * ne) / T) if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) RDM1 /= Z RDM2 /= Z E /= Z return RDM1, RDM2, E
def spin_square(fcivec, norb, nelec, mo_coeff=None, ovlp=1): r'''General spin square operator. ... math:: <CI|S_+*S_-|CI> &= n_\alpha + \delta_{ik}\delta_{jl}Gamma_{i\alpha k\beta ,j\beta l\alpha } \\ <CI|S_-*S_+|CI> &= n_\beta + \delta_{ik}\delta_{jl}Gamma_{i\beta k\alpha ,j\alpha l\beta } \\ <CI|S_z*S_z|CI> &= \delta_{ik}\delta_{jl}(Gamma_{i\alpha k\alpha ,j\alpha l\alpha } - Gamma_{i\alpha k\alpha ,j\beta l\beta } - Gamma_{i\beta k\beta ,j\alpha l\alpha} + Gamma_{i\beta k\beta ,j\beta l\beta}) + (n_\alpha+n_\beta)/4 Given the overlap betwen non-degenerate alpha and beta orbitals, this function can compute the expectation value spin square operator for UHF-FCI wavefunction ''' from pyscf.fci import direct_spin1 if isinstance(mo_coeff, numpy.ndarray) and mo_coeff.ndim == 2: mo_coeff = (mo_coeff, mo_coeff) elif mo_coeff is None: mo_coeff = (numpy.eye(norb), ) * 2 # projected overlap matrix elements for partial trace if isinstance(ovlp, numpy.ndarray): ovlpaa = reduce(numpy.dot, (mo_coeff[0].T, ovlp, mo_coeff[0])) ovlpbb = reduce(numpy.dot, (mo_coeff[1].T, ovlp, mo_coeff[1])) ovlpab = reduce(numpy.dot, (mo_coeff[0].T, ovlp, mo_coeff[1])) ovlpba = reduce(numpy.dot, (mo_coeff[1].T, ovlp, mo_coeff[0])) else: ovlpaa = numpy.dot(mo_coeff[0].T, mo_coeff[0]) ovlpbb = numpy.dot(mo_coeff[1].T, mo_coeff[1]) ovlpab = numpy.dot(mo_coeff[0].T, mo_coeff[1]) ovlpba = numpy.dot(mo_coeff[1].T, mo_coeff[0]) # if ovlp=1, ssz = (neleca-nelecb)**2 * .25 (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ direct_spin1.make_rdm12s(fcivec, norb, nelec) ssz =(_bi_trace(dm2aa, ovlpaa, ovlpaa) - _bi_trace(dm2ab, ovlpaa, ovlpbb) + _bi_trace(dm2bb, ovlpbb, ovlpbb) - _bi_trace(dm2ab, ovlpaa, ovlpbb)) * .25 \ +(_trace(dm1a, ovlpaa) + _trace(dm1b, ovlpbb)) *.25 dm2baab = _make_rdm2_baab(fcivec, norb, nelec) dm2abba = _make_rdm2_abba(fcivec, norb, nelec) dm2baab = rdm.reorder_rdm(dm1b, dm2baab, inplace=True)[1] dm2abba = rdm.reorder_rdm(dm1a, dm2abba, inplace=True)[1] ssxy =(_bi_trace(dm2abba, ovlpab, ovlpba) + _bi_trace(dm2baab, ovlpba, ovlpab) \ + _trace(dm1a, ovlpaa) + _trace(dm1b, ovlpbb)) * .5 ss = ssxy + ssz s = numpy.sqrt(ss + .25) - .5 multip = s * 2 + 1 return ss, multip
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 = select_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) ci0 = select_ci.to_fci(ci_coeff, norb, (nelec, nelec)) dm1ref, dm2ref = direct_spin1.make_rdm12s(ci0, norb, (nelec, nelec)) dm1 = select_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 = select_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 = select_ci._as_SCIvector( numpy.random.random((len(strsa), len(strsb))), ci_strs) ci1 = select_ci.to_fci(ci1_coeff, norb, (nelec, nelec)) dm1ref, dm2ref = direct_spin1.trans_rdm12s(ci1, ci0, norb, (nelec, nelec)) dm1 = select_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 spin_square(fcivec, norb, nelec, mo_coeff=None, ovlp=1): from pyscf.fci import direct_spin1 if mo_coeff is None: mo_coeff = (numpy.eye(norb), ) * 2 (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ direct_spin1.make_rdm12s(fcivec, norb, nelec) return spin_square_general(dm1a, dm1b, dm2aa, dm2ab, dm2bb, mo_coeff, ovlp)
def rdm12s_ft_smpl(h1e, g2e, norb, nelec, T, \ m=50, nsmpl=20000, Tmin=1e-3, symm='RHF', **kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if T < Tmin: e, c = fcisolver.kernel(h1e, g2e, norb, nelec) dm1, dm2 = fcisolver.make_rdm12s(c, norb, nelec) dm1 = numpy.asarray(dm1) dm2 = numpy.asarray(dm2) else: h2e = fcisolver.absorb_h1e(h1e, g2e, norb, nelec, .5) if symm is 'SOC': na = cistring.num_strings(norb, nelec) ci0 = numpy.random.randn(na) else: na = cistring.num_strings(norb, nelec // 2) ci0 = numpy.random.randn(na * na) hdiag = fcisolver.make_hdiag(h1e, g2e, norb, nelec) hdiag = hdiag - hdiag[0] disp = numpy.exp(T) * 0.5 ci0 = ci0 / numpy.linalg.norm(ci0) def hop(c): hc = fcisolver.contract_2e(h2e, c, norb, nelec) return hc.reshape(-1) def qud(v1): dm1, dm2 = fcisolver.make_rdm12s(v1, norb, nelec) return dm1, dm2 dm1, dm2, e = ftsmpl.ft_smpl_rdm12s(qud, hop, ci0, T, norb, nsamp=nsmpl, M=m) if symm is 'UHF': return dm1, dm2, e elif len(dm1.shape) == 3: return numpy.sum(dm1, axis=0), numpy.sum(dm2, axis=0), e else: return dm1, dm2, e
def make_rdm12s(fcivec, norb, nelec, link_index=None, reorder=True): return direct_spin1.make_rdm12s(fcivec, norb, nelec, link_index, reorder)
def make_rdm2_abba(fcivec, norb, nelec): from pyscf.fci import direct_spin1 dm2aa, dm2ab, dm2bb = direct_spin1.make_rdm12s(fcivec, norb, nelec)[1] dm2abba = -dm2ab.transpose(0, 3, 2, 1) return dm2abba
def make_rdm2_baab(fcivec, norb, nelec): from pyscf.fci import direct_spin1 dm2aa, dm2ab, dm2bb = direct_spin1.make_rdm12s(fcivec, norb, nelec)[1] dm2baab = -dm2ab.transpose(2, 1, 0, 3) return dm2baab
def rdm12s_fted(h1e,g2e,norb,nelec,T,symm='RHF',Tmin=1.e-3,\ dcompl=False,**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver) ndim = len(ew) rdm1, rdm2 = [], [] RDM1, RDM2 = fcisolver.make_rdm12s(ev[:, 0].copy(), norb, nelec) RDM1 = np.asarray(RDM1, dtype=np.complex128) RDM2 = np.asarray(RDM2, dtype=np.complex128) if T < Tmin: if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) if not dcompl: return RDM1.real, RDM2.real, ew[0].real return RDM1, RDM2, ew[0] ew -= ew[0] Z = np.sum(np.exp(-ew / T)) E = np.sum(np.exp(-ew / T) * ew) / Z for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, nelec) rdm1.append(np.asarray(dm1, dtype=np.complex128)) rdm2.append(np.asarray(dm2, dtype=np.complex128)) # rdm1 = np.asarray(rdm1) # rdm2 = np.asarray(rdm2) # RDM1 = np.sum(rdm1*np.exp(-1.j*ew/T))/Z # RDM2 = np.sum(rdm2*np.exp(-1.j*ew/T))/Z RDM1 *= 0. RDM2 *= 0. for i in range(ndim): RDM1 += rdm1[i] * np.exp(-ew[i] / T) RDM2 += rdm2[i] * np.exp(-ew[i] / T) RDM1 /= Z RDM2 /= Z if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) if not dcompl: E = (E + ew[0]).real RDM1 = RDM1.real RDM2 = RDM2.real return RDM1, RDM2, E
def rdm12s_fted(h1e,g2e,norb,nelec,T,symm='RHF',Tmin=1.e-3,\ dcompl=False,**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver) RDM1, RDM2 = fcisolver.make_rdm12s(ev[:, 0].copy(), norb, nelec) RDM1 = np.asarray(RDM1, dtype=np.complex128) RDM2 = np.asarray(RDM2, dtype=np.complex128) if T < Tmin: if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) if not dcompl: return RDM1.real, RDM2.real, ew[0].real return RDM1, RDM2, ew[0] ews, evs = solve_spectrum(h1e, g2e, norb, fcisolver) mu = solve_mu(h1e, g2e, norb, nelec, fcisolver, T, mu0=0., ews=ews) Z = 0. E = 0. RDM1 *= 0. RDM2 *= 0. for na in range(0, norb + 1): for nb in range(0, norb + 1): ne = na + nb ndim = len(ews[na, nb]) Z += np.sum(np.exp((-ews[na, nb] + mu * ne) / T)) E += np.sum(np.exp((-ews[na, nb] + mu * ne) / T) * ews[na, nb]) for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(evs[na, nb][:, i].copy(), norb, (na, nb)) dm1 = np.asarray(dm1, dtype=np.complex128) dm2 = np.asarray(dm2, dtype=np.complex128) RDM1 += dm1 * np.exp((ne * mu - ews[na, nb][i]) / T) RDM2 += dm2 * np.exp((ne * mu - ews[na, nb][i]) / T) E /= Z RDM1 /= Z RDM2 /= Z if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) if not dcompl: E = E.real RDM1 = RDM1.real RDM2 = RDM2.real return RDM1, RDM2, E
def rdm12s_fted(h1e,g2e,norb,nelec,beta,mu=0.0,bmax=1e3, \ dcompl=False,**kwargs): ''' Return the expectation values of energy, RDM1 and RDM2 at temperature T. ''' # make sure the Hamiltonians have the correct shape # if (type(h1e) is tuple) or (type(h1e) is list): # h1e = h1e[0] # g2e = g2e[0] Z = 0. E = 0. RDM1 = np.zeros((norb, norb)) RDM2_0 = np.zeros((norb, norb, norb, norb)) RDM2_1 = np.zeros((norb, norb, norb, norb)) if beta > bmax: e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) return np.asarray(RDM1), np.asarray(RDM2), e # check for overflow e0, _ = fcisolver.kernel(h1e, g2e, norb, norb) exp_max = (-e0 + mu * norb) * beta if (exp_max > 700): exp_shift = exp_max - 500 else: exp_shift = 0 # Calculating E, RDM1, Z N = 0 # na =/= nb for na in range(0, norb + 1): for nb in range(na + 1, norb + 1): ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) * 2 E += np.sum(np.exp(exp_) * ew) * 2 N += ne * np.sum(np.exp(exp_)) * 2 for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, (na, nb)) RDM1 += (dm1[0] + dm1[1]) * np.exp(exp_[i]) RDM2_0 += (dm2[0] + dm2[2]) * np.exp(exp_[i]) RDM2_1 += (dm2[1] + np.transpose(dm2[1], (2, 3, 0, 1))) * np.exp( exp_[i]) for na in range(0, norb + 1): nb = na ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) E += np.sum(np.exp(exp_) * ew) N += ne * np.sum(np.exp(exp_)) for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, (na, nb)) RDM1 += dm1[0] * np.exp(exp_[i]) RDM2_0 += dm2[0] * np.exp(exp_[i]) RDM2_1 += dm2[1] * np.exp(exp_[i]) E /= Z N /= Z RDM1 /= Z RDM2_0 /= Z RDM2_1 /= Z log.result("The expectation of electron number:") log.result("N(total) = %10.10f" % N) RDM1 = np.asarray([RDM1, RDM1]) RDM2 = np.asarray([RDM2_0, RDM2_1, RDM2_0]) log.result("FTED energy: %10.12f" % E) # RDM2 order: aaaa, aabb, bbbb return RDM1, RDM2, E
def qud(v1): dm1, dm2 = fcisolver.make_rdm12s(v1, norb, nelec) return dm1, dm2
def make_dm12(ci0, norb, nelec): def des(ci0, norb, nelec, ap_id, spin): if spin == 0: ci1 = addons.des_a(ci0, norb, nelec, ap_id) ne = nelec[0] - 1, nelec[1] else: ci1 = addons.des_b(ci0, norb, nelec, ap_id) ne = nelec[0], nelec[1] - 1 return ci1, ne def cre(ci0, norb, nelec, ap_id, spin): if spin == 0: ci1 = addons.cre_a(ci0, norb, nelec, ap_id) ne = nelec[0] + 1, nelec[1] else: ci1 = addons.cre_b(ci0, norb, nelec, ap_id) ne = nelec[0], nelec[1] + 1 return ci1, ne dm1 = numpy.zeros((norb, 2, norb, 2)) for i in range(norb): for j in range(norb): for i1 in range(2): for j1 in range(2): if i1 == j1: ne = nelec ci1, ne = des(ci0, norb, ne, j, j1) ci1, ne = cre(ci1, norb, ne, i, i1) dm1[i, i1, j, j1] = numpy.dot(ci0.ravel(), ci1.ravel()) dm2 = numpy.zeros((norb, 2, norb, 2, norb, 2, norb, 2)) for i in range(norb): for j in range(norb): for k in range(norb): for l in range(norb): for i1 in range(2): for j1 in range(2): for k1 in range(2): for l1 in range(2): if i1 + j1 == k1 + l1: ci1, ne = ci0, nelec ci1, ne = des(ci1, norb, ne, k, k1) ci1, ne = des(ci1, norb, ne, l, l1) ci1, ne = cre(ci1, norb, ne, j, j1) ci1, ne = cre(ci1, norb, ne, i, i1) dm2[i, i1, j, j1, k, k1, l, l1] = numpy.dot( ci0.ravel(), ci1.ravel()) if 0: dm1a = numpy.einsum('iajb->ij', dm1) dm2a = numpy.einsum('iajbkalb->ijkl', dm2) print abs(numpy.einsum('ipjp->ij', dm2a) / (sum(nelec) - 1) - dm1a).sum() (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ direct_spin1.make_rdm12s(ci0, norb, nelec) print abs(dm1a - dm1[:, 0, :, 0]).sum() print abs(dm2aa - dm2[:, 0, :, 0, :, 0, :, 0].transpose(0, 2, 1, 3)).sum() print abs(dm2ab - dm2[:, 0, :, 1, :, 0, :, 1].transpose(0, 2, 1, 3)).sum() print abs( dm2ab.transpose(2, 3, 0, 1) - dm2[:, 1, :, 0, :, 1, :, 0].transpose(0, 2, 1, 3)).sum() print abs(dm2bb - dm2[:, 1, :, 1, :, 1, :, 1].transpose(0, 2, 1, 3)).sum() dm2baab = spin_op.make_rdm2_baab(ci0, norb, nelec) dm2abba = spin_op.make_rdm2_abba(ci0, norb, nelec) print abs(dm2baab - dm2[:, 1, :, 0, :, 0, :, 1].transpose(0, 2, 1, 3)).sum() print abs(dm2abba - dm2[:, 0, :, 1, :, 1, :, 0].transpose(0, 2, 1, 3)).sum() return dm1, dm2
one_sf, two_sf = find_full_casscf_12rdm(mc.fcisolver, mf.mo_coeff, 'spinfree_TwoRDM.1', norb, nelec) assert (numpy.allclose( two_sf[:n_occorbs, :n_occorbs, :n_occorbs, :n_occorbs], spinfree_2)) mc2 = mcscf.CASCI(mf, 6, 6) # mc2.canonicalization = False mc2.fcisolver = direct_spin1.FCISolver(mol) emc2, e_cas2, fcivec2 = mc2.kernel()[:3] #ss_tot = spin_op.spin_square(fcivec2, norb, nelec)[0] # print 'ss_tot exact: ',ss_tot (dm1a_, dm1b_), (dm2aa_, dm2ab_, dm2bb_) = direct_spin1.make_rdm12s(fcivec2, norb, nelec, reorder=False) #f_dbg = dbg_ss_frac(dm1, dm2, norb, mo_cas, ovlp) # dm2baab(pq,rs) = <p(beta)* q(alpha) r(alpha)* s(beta) dm2baab_ = spin_op._make_rdm2_baab(fcivec2, norb, nelec) # dm2abba(pq,rs) = <q(alpha)* p(beta) s(beta)* r(alpha) dm2abba_ = spin_op._make_rdm2_abba(fcivec2, norb, nelec) ss_tot = spin_op.spin_square(fcivec2, norb, nelec)[0] f_opt_act = opt_ss_frac(dm1a_, dm1b_, dm2aa_, dm2ab_, dm2bb_, dm2baab_, dm2abba_, norb, nelec, mo_cas, ovlp) f_mag_act = opt_mag_frac(dm1a_, dm1b_, norb, nelec, mo_cas, ovlp) if DoNECI: f_opt_full = opt_ss_frac(dm1a, dm1b, dm2aa, dm2ab, dm2bb, dm2baab, dm2abba, n_occorbs, nelec_full, occorbs, ovlp)
def rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=50,Tmin=1e-3,\ dcompl=False,symm='RHF',**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if symm != 'UHF' and isinstance(h1e, tuple): h1e = h1e[0] g2e = g2e[1] if T < Tmin: # only for half-filling e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) return numpy.asarray(RDM1), numpy.asarray(RDM2), e # loop over na and nb Z = 0. E = 0. RDM1 = numpy.zeros((2, norb, norb), dtype=numpy.complex128) RDM2 = numpy.zeros((3, norb, norb, norb, norb), dtype=numpy.complex128) #for ns in range(1): # rdm1,rdm2,e,z = lanczos_grand.ft_solver(h1e,g2e,fcisolver,norb,nelec,T,mu=0,m=m) # RDM1 += rdm1 # RDM2 += rdm2 # E += e # Z += z # calculate the number of states nstate = 0. dN = 0 for na in range(norb / 2 - dN, norb / 2 + dN + 1): for nb in range(norb / 2 - dN, norb / 2 + dN + 1): nstate += cistring.num_strings(norb, na) * cistring.num_strings( norb, nb) for na in range(norb / 2 - dN, norb / 2 + dN + 1): for nb in range(na, norb / 2 + dN + 1): ne = (na, nb) ntot = na + nb nci = cistring.num_strings(norb, na) * cistring.num_strings( norb, nb) factor = numpy.exp(0 * (ntot - norb) / T) if nci < 1e2: rdm1, rdm2, e, z = ed_canonical.ftsolver(h1e, g2e, fcisolver, norb, ne, T, mu, symm='UHF') Z += z / nstate * factor E += e / nstate * factor RDM1 += rdm1 / nstate * factor RDM2 += rdm2 / nstate * factor else: rdm1, rdm2, e, z = lanczos_grand.ft_solver( h1e, g2e, fcisolver, norb, ne, T, mu) Z += z * (nci / nstate) * factor E += e * (nci / nstate) * factor RDM1 += rdm1 * (nci / nstate) * factor RDM2 += rdm2 * (nci / nstate) * factor #if nb > na: # Z += 2*(nci/nstate)*z*factor # E += 2*(nci/nstate)*e*factor # RDM1 += (nci/nstate)*rdm1*factor # RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor # RDM2 += 2*(nci/nstate)*rdm2*factor #else: # Z += (nci/nstate)*z*factor # E += (nci/nstate)*e*factor # RDM1 += (nci/nstate)*rdm1*factor # #RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor/2. # RDM2 += (nci/nstate)*rdm2*factor # E /= Z RDM1 /= Z RDM2 /= Z if not dcompl: E = E.real RDM1 = RDM1.real RDM2 = RDM2.real return RDM1, RDM2, E
if __name__ == '__main__': from pyscf.fci import direct_uhf as fcisolver norb = 12 nelec = (norb / 2, norb / 2) u = 4.0 T = 0.05 mu = 2 h1e = numpy.zeros((norb, norb)) for i in range(norb): h1e[i, (i + 1) % norb] = -1.0 h1e[i, (i - 1) % norb] = -1.0 #h1e[0,-1] = 0. #h1e[-1,0] = 0. g2e_ = numpy.zeros((norb, ) * 4) for i in range(norb): g2e_[i, i, i, i] = u h1e = (h1e, h1e) g2e = (numpy.zeros((norb, ) * 4), g2e_, numpy.zeros((norb, ) * 4)) rdm1, rdm2, e = rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=200,Tmin=1e-3,\ dcompl=False,symm='UHF') e0, v = fcisolver.kernel(h1e, g2e, norb, nelec, nroots=1) rdm10, rdm20 = fcisolver.make_rdm12s(v, norb, nelec) print e / norb - e0 / norb print numpy.linalg.norm(rdm1 - rdm10) print numpy.linalg.norm(rdm2 - rdm20) print rdm1[0][:4, :4] print rdm10[0][:4, :4]