def make_rdm12s(fcivec, norb, nelec, link_index=None, reorder=True): r'''Spin separated 1- and 2-particle density matrices. The return values include two lists, a list of 1-particle density matrices and a list of 2-particle density matrices. The density matrices are: (alpha,alpha), (beta,beta) for 1-particle density matrices; (alpha,alpha,alpha,alpha), (alpha,alpha,beta,beta), (beta,beta,beta,beta) for 2-particle density matrices. 1pdm[p,q] = :math:`\langle q^\dagger p\rangle`; 2pdm[p,q,r,s] = :math:`\langle p^\dagger r^\dagger s q\rangle`. Energy should be computed as E = einsum('pq,qp', h1, 1pdm) + 1/2 * einsum('pqrs,pqrs', eri, 2pdm) where h1[p,q] = <p|h|q> and eri[p,q,r,s] = (pq|rs) ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCIrdm12kern_a', fcivec, fcivec, norb, nelec, link_index, 1) dm1b, dm2bb = rdm.make_rdm12_spin1('FCIrdm12kern_b', fcivec, fcivec, norb, nelec, link_index, 1) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', fcivec, fcivec, norb, nelec, link_index, 0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2bb)
def trans_rdm12s(cibra, ciket, norb, nelec, link_index=None, reorder=True): r'''Spin separated 1- and 2-particle transition density matrices. The return values include two lists, a list of 1-particle transition density matrices and a list of 2-particle transition density matrices. The density matrices are: (alpha,alpha), (beta,beta) for 1-particle transition density matrices; (alpha,alpha,alpha,alpha), (alpha,alpha,beta,beta), (beta,beta,alpha,alpha), (beta,beta,beta,beta) for 2-particle transition density matrices. 1pdm[p,q] = :math:`\langle q^\dagger p\rangle`; 2pdm[p,q,r,s] = :math:`\langle p^\dagger r^\dagger s q\rangle`. ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCItdm12kern_a', cibra, ciket, norb, nelec, link_index, 2) dm1b, dm2bb = rdm.make_rdm12_spin1('FCItdm12kern_b', cibra, ciket, norb, nelec, link_index, 2) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', cibra, ciket, norb, nelec, link_index, 0) _, dm2ba = rdm.make_rdm12_spin1('FCItdm12kern_ab', ciket, cibra, norb, nelec, link_index, 0) dm2ba = dm2ba.transpose(3,2,1,0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb)
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 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 neleca, nelecb = _unpack(nelec) 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 trans_rdm12s(cibra, ciket, norb, nelec, link_index=None, reorder=True): r'''Spin separated 1- and 2-particle transition density matrices. The return values include two lists, a list of 1-particle transition density matrices and a list of 2-particle transition density matrices. The density matrices are: (alpha,alpha), (beta,beta) for 1-particle transition density matrices; (alpha,alpha,alpha,alpha), (alpha,alpha,beta,beta), (beta,beta,alpha,alpha), (beta,beta,beta,beta) for 2-particle transition density matrices. 1pdm[p,q] = :math:`\langle q^\dagger p\rangle`; 2pdm[p,q,r,s] = :math:`\langle p^\dagger r^\dagger s q\rangle`. ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCItdm12kern_a', cibra, ciket, norb, nelec, link_index, 2) dm1b, dm2bb = rdm.make_rdm12_spin1('FCItdm12kern_b', cibra, ciket, norb, nelec, link_index, 2) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', cibra, ciket, norb, nelec, link_index, 0) _, dm2ba = rdm.make_rdm12_spin1('FCItdm12kern_ab', ciket, cibra, norb, nelec, link_index, 0) dm2ba = dm2ba.transpose(3, 2, 1, 0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb)
def make_rdm12s(fcivec, norb, nelec, link_index=None, reorder=True): dm1a, dm2aa = rdm.make_rdm12_spin1('FCIrdm12kern_a', fcivec, fcivec, norb, nelec, link_index, 1) dm1b, dm2bb = rdm.make_rdm12_spin1('FCIrdm12kern_b', fcivec, fcivec, norb, nelec, link_index, 1) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', fcivec, fcivec, norb, nelec, link_index, 0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2bb)
def spin_square(ci, norb, nelec, mo_coeff=None, ovlp=1): # <CI|S+*S-|CI> = neleca + \delta_{ik}\delta_{jl}Gamma_{iakb,jbla} # <CI|S-*S+|CI> = nelecb + \delta_{ik}\delta_{jl}Gamma_{ibka,jalb} # <CI|Sz*Sz|CI> = \delta_{ik}\delta_{jl}(Gamma_{iaka,jala} - Gamma_{iaka,jblb} # -Gamma_{ibkb,jala} + Gamma_{ibkb,jblb}) # + (neleca+nelecb)/4 if isinstance(nelec, (int, numpy.integer)): neleca = nelecb = nelec // 2 else: neleca, nelecb = nelec 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]) (dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ direct_spin1.make_rdm12s(ci, 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(ci, norb, nelec) dm2abba = _make_rdm2_abba(ci, 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 trans_rdm12s(cibra, ciket, norb, nelec, link_index=None, reorder=True): dm1a, dm2aa = rdm.make_rdm12_spin1('FCItdm12kern_a', cibra, ciket, norb, nelec, link_index, 2) dm1b, dm2bb = rdm.make_rdm12_spin1('FCItdm12kern_b', cibra, ciket, norb, nelec, link_index, 2) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', cibra, ciket, norb, nelec, link_index, 0) _, dm2ba = rdm.make_rdm12_spin1('FCItdm12kern_ab', ciket, cibra, norb, nelec, link_index, 0) dm2ba = dm2ba.transpose(3,2,1,0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb)
def make_rdm12e(fcivec, nsite, nelec): '''1-electron and 2-electron density matrices dm_pq = <|p^+ q|> dm_{pqrs} = <|p^+ r^+ q s|> (note 2pdm is ordered in chemist notation) ''' neleca, nelecb = _unpack_nelec(nelec) link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) na = cistring.num_strings(nsite, neleca) nb = cistring.num_strings(nsite, nelecb) ci0 = fcivec.reshape(na, nb, -1) rdm1 = numpy.zeros((nsite, nsite)) rdm2 = numpy.zeros((nsite, nsite, nsite, nsite)) for str0 in range(na): t1 = numpy.zeros((nsite, nsite, nb) + ci0.shape[2:]) for a, i, str1, sign in link_indexa[str0]: t1[i, a, :] += sign * ci0[str1, :] for k, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1[i, a, k] += sign * ci0[str0, str1] rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1) # i^+ j|0> => <0|j^+ i, so swap i and j #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1) tmp = lib.dot(t1.reshape(nsite**2, -1), t1.reshape(nsite**2, -1).T) rdm2 += tmp.reshape((nsite, ) * 4).transpose(1, 0, 2, 3) rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True) return rdm1, rdm2
def trans_rdm12s(cibra, ciket, norb, nelec, link_index=None, reorder=True): '''Spin separated transition 1- and 2-particle density matrices. ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCItdm12kern_a', cibra, ciket, norb, nelec, link_index, 2) dm1b, dm2bb = rdm.make_rdm12_spin1('FCItdm12kern_b', cibra, ciket, norb, nelec, link_index, 2) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', cibra, ciket, norb, nelec, link_index, 0) _, dm2ba = rdm.make_rdm12_spin1('FCItdm12kern_ab', ciket, cibra, norb, nelec, link_index, 0) dm2ba = dm2ba.transpose(3,2,1,0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb)
def make_rdm12e(fcivec, nsite, nelec): '''1-electron and 2-electron density matrices dm_pq = <|p^+ q|> dm_{pqrs} = <|p^+ r^+ q s|> (note 2pdm is ordered in chemist notation) ''' neleca, nelecb = _unpack_nelec(nelec) link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) na = cistring.num_strings(nsite, neleca) nb = cistring.num_strings(nsite, nelecb) ci0 = fcivec.reshape(na,nb,-1) rdm1 = numpy.zeros((nsite,nsite)) rdm2 = numpy.zeros((nsite,nsite,nsite,nsite)) for str0 in range(na): t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:]) for a, i, str1, sign in link_indexa[str0]: t1[i,a,:] += sign * ci0[str1,:] for k, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1[i,a,k] += sign * ci0[str0,str1] rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1) # i^+ j|0> => <0|j^+ i, so swap i and j #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1) tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T) rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3) rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True) return rdm1, rdm2
def trans_rdm12s(cibra, ciket, norb, nelec, link_index=None, reorder=True): '''Spin separated transition 1- and 2-particle density matrices. ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCItdm12kern_a', cibra, ciket, norb, nelec, link_index, 2) dm1b, dm2bb = rdm.make_rdm12_spin1('FCItdm12kern_b', cibra, ciket, norb, nelec, link_index, 2) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', cibra, ciket, norb, nelec, link_index, 0) _, dm2ba = rdm.make_rdm12_spin1('FCItdm12kern_ab', ciket, cibra, norb, nelec, link_index, 0) dm2ba = dm2ba.transpose(3, 2, 1, 0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb)
def trans_rdm12(cibra, ciket, norb, nelec, link_index=None, reorder=True): #(dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb) = \ # trans_rdm12s(cibra, ciket, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ba+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCItdm12kern_sf', cibra, ciket, norb, nelec, link_index, 2) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True): # dm1, dm2 = rdm.make_rdm12('FCIrdm12kern_spin0', fcivec, fcivec, # norb, nelec, link_index, 1) # NOT use FCIrdm12kern_spin0 because for small system, the kernel may call # direct diagonalization, which may not fulfil fcivec = fcivet.T dm1, dm2 = rdm.make_rdm12("FCIrdm12kern_sf", fcivec, fcivec, norb, nelec, link_index, 1) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, True) return dm1, dm2
def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True): #(dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ # make_rdm12s(fcivec, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ab.transpose(2,3,0,1)+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCIrdm12kern_sf', fcivec, fcivec, norb, nelec, link_index, 1) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def make_rdm12s(fcivec, norb, nelec, link_index=None, reorder=True): r'''Spin searated 1- and 2-particle density matrices, (alpha,beta) for 1-particle density matrices. (alpha,alpha,alpha,alpha), (alpha,alpha,beta,beta), (beta,beta,beta,beta) for 2-particle density matrices. NOTE the 2pdm is :math:`\langle p^\dagger q^\dagger s r\rangle` but is stored as [p,r,q,s] ''' dm1a, dm2aa = rdm.make_rdm12_spin1('FCIrdm12kern_a', fcivec, fcivec, norb, nelec, link_index, 1) dm1b, dm2bb = rdm.make_rdm12_spin1('FCIrdm12kern_b', fcivec, fcivec, norb, nelec, link_index, 1) _, dm2ab = rdm.make_rdm12_spin1('FCItdm12kern_ab', fcivec, fcivec, norb, nelec, link_index, 0) if reorder: dm1a, dm2aa = rdm.reorder_rdm(dm1a, dm2aa, inplace=True) dm1b, dm2bb = rdm.reorder_rdm(dm1b, dm2bb, inplace=True) return (dm1a, dm1b), (dm2aa, dm2ab, dm2bb)
def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True): #dm1, dm2 = rdm.make_rdm12('FCIrdm12kern_spin0', fcivec, fcivec, # norb, nelec, link_index, 1) # NOT use FCIrdm12kern_spin0 because for small system, the kernel may call # direct diagonalization, which may not fulfil fcivec = fcivet.T dm1, dm2 = rdm.make_rdm12('FCIrdm12kern_sf', fcivec, fcivec, norb, nelec, link_index, 1) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, True) return dm1, dm2
def trans_rdm12(cibra, ciket, norb, nelec, link_index=None, reorder=True): '''Spin traced transition 1- and 2-particle density matrices. ''' #(dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb) = \ # trans_rdm12s(cibra, ciket, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ba+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCItdm12kern_sf', cibra, ciket, norb, nelec, link_index, 2) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True): r'''Spin traced 1- and 2-particle density matrices, NOTE the 2pdm is :math:`\langle p^\dagger q^\dagger s r\rangle` but is stored as [p,r,q,s] ''' #(dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ # make_rdm12s(fcivec, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ab.transpose(2,3,0,1)+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCIrdm12kern_sf', fcivec, fcivec, norb, nelec, link_index, 1) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def trans_rdm12(cibra, ciket, norb, nelec, link_index=None, reorder=True): r'''Spin traced transition 1- and 2-particle transition density matrices. 1pdm[p,q] = :math:`\langle q^\dagger p\rangle`; 2pdm[p,q,r,s] = :math:`\langle p^\dagger r^\dagger s q\rangle`. ''' #(dm1a, dm1b), (dm2aa, dm2ab, dm2ba, dm2bb) = \ # trans_rdm12s(cibra, ciket, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ba+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCItdm12kern_sf', cibra, ciket, norb, nelec, link_index, 2) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def make_rdm12(civec, norb, nelec, link_index=None, reorder=True): if isinstance(nelec, (int, numpy.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec assert (neleca == nelecb) if link_index is None: link_index = cistring.gen_linkstr_index(range(norb), neleca) na = cistring.num_strings(norb, neleca) t1 = numpy.zeros((norb, na)) t2 = numpy.zeros((norb, norb, na)) #:for str0, tab in enumerate(link_index): #: for a, i, str1, sign in tab: #: if a == i: #: t1[i,str1] += civec[str0] #: else: #: t2[a,i,str1] += civec[str0] link1 = link_index[link_index[:, :, 0] == link_index[:, :, 1]].reshape(na, -1, 4) link2 = link_index[link_index[:, :, 0] != link_index[:, :, 1]].reshape( na, -1, 4) t1[link1[:, :, 1], link1[:, :, 2]] = civec[:, None] t2[link2[:, :, 0], link2[:, :, 1], link2[:, :, 2]] = civec[:, None] idx = numpy.arange(norb) dm2 = numpy.zeros([norb] * 4) # Assign to dm2[i,j,i,j] dm2[idx[:, None], idx, idx[:, None], idx] += 2 * numpy.einsum('ijp,p->ij', t2, civec) # Assign to dm2[i,j,j,i] dm2[idx[:, None], idx, idx, idx[:, None]] += 2 * numpy.einsum('ijp,ijp->ij', t2, t2) # Assign to dm2[i,i,j,j] dm2[idx[:, None], idx[:, None], idx, idx] += 4 * numpy.einsum('ip,jp->ij', t1, t1) dm1 = numpy.einsum('ijkk->ij', dm2) / (neleca + nelecb) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def make_rdm12(fcivec, norb, nelec, link_index=None, reorder=True): r'''Spin traced 1- and 2-particle density matrices. 1pdm[p,q] = :math:`\langle q_\alpha^\dagger p_\alpha \rangle + \langle q_\beta^\dagger p_\beta \rangle`; 2pdm[p,q,r,s] = :math:`\langle p_\alpha^\dagger r_\alpha^\dagger s_\alpha q_\alpha\rangle + \langle p_\beta^\dagger r_\alpha^\dagger s_\alpha q_\beta\rangle + \langle p_\alpha^\dagger r_\beta^\dagger s_\beta q_\alpha\rangle + \langle p_\beta^\dagger r_\beta^\dagger s_\beta q_\beta\rangle`. Energy should be computed as E = einsum('pq,qp', h1, 1pdm) + 1/2 * einsum('pqrs,pqrs', eri, 2pdm) where h1[p,q] = <p|h|q> and eri[p,q,r,s] = (pq|rs) ''' #(dm1a, dm1b), (dm2aa, dm2ab, dm2bb) = \ # make_rdm12s(fcivec, norb, nelec, link_index, reorder) #return dm1a+dm1b, dm2aa+dm2ab+dm2ab.transpose(2,3,0,1)+dm2bb dm1, dm2 = rdm.make_rdm12_spin1('FCIrdm12kern_sf', fcivec, fcivec, norb, nelec, link_index, 1) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, inplace=True) return dm1, dm2
def trans_rdm12(cibra, ciket, norb, nelec, link_index=None, reorder=True): dm1, dm2 = rdm.make_rdm12('FCItdm12kern_sf', cibra, ciket, norb, nelec, link_index, 2) if reorder: dm1, dm2 = rdm.reorder_rdm(dm1, dm2, True) return dm1, dm2
def make_rdm2_baab(fcivec, norb, nelec): dm2 = _make_rdm2_baab(fcivec, norb, nelec) dm1b = rdm.make_rdm1_spin1('FCImake_rdm1b', fcivec, fcivec, norb, nelec) dm1b, dm2 = rdm.reorder_rdm(dm1b, dm2, inplace=True) return dm2
def make_rdm2_abba(fcivec, norb, nelec): dm2 = _make_rdm2_abba(fcivec, norb, nelec) dm1a = rdm.make_rdm1_spin1('FCImake_rdm1a', fcivec, fcivec, norb, nelec) dm1a, dm2 = rdm.reorder_rdm(dm1a, dm2, inplace=True) return dm2
def make_rdm2_baab(fcivec, norb, nelec): assert(fcivec.flags.c_contiguous) dm2 = _make_rdm2_baab(fcivec, norb, nelec) dm1b = rdm.make_rdm1_spin1('FCImake_rdm1b', fcivec, fcivec, norb, nelec) dm1b, dm2 = rdm.reorder_rdm(dm1b, dm2, inplace=True) return dm2