Ejemplo n.º 1
0
def eaccsd_diag(eom, imds=None):
    if imds is None: imds = eom.make_imds()
    t1, t2 = imds.t1, imds.t2
    nocc, nvir = t1.shape
    foo = imds.eris.foo
    fvv = imds.eris.fvv
    Hr1 = imds.Lvv.diagonal()
    Hr1 = tensor(Hr1)

    if eom.partition == 'mp':
        jab = fvv.diagonal()[None, :, None]
        jab = jab + fvv.diagonal()[None, None, :]
        jab = jab - foo.diagonal()[:, None, None]
        Hr2 = tensor(jab)
    else:
        jab = imds.Lvv.diagonal().reshape(1, nvir, 1)
        jab = jab + imds.Lvv.diagonal().reshape(1, 1, nvir)
        jab = jab - imds.Loo.diagonal().reshape(nocc, 1, 1)
        wab = np.einsum("abab->ab", imds.Wvvvv.array)
        wjb = np.einsum('jbjb->jb', imds.Wovov.array)
        wjb2 = np.einsum('jbbj->jb', imds.Wovvo.array)
        wja = np.einsum('jaja->ja', imds.Wovov.array)
        jab = jab + wab.reshape(1, nvir, nvir)
        jab = jab - wjb.reshape(nocc, 1, nvir)
        jab = jab + 2 * wjb2.reshape(nocc, 1, nvir)
        jab -= np.einsum('jb,ab->jab', wjb2, np.eye(nvir))
        jab = jab - wja.reshape(nocc, nvir, 1)
        Hr2 = tensor(jab)
        Hr2 -= 2 * lib.einsum('ijab,ijab->jab', t2, imds.Woovv)
        Hr2 += lib.einsum('ijab,ijba->jab', t2, imds.Woovv)
    vector = eom.amplitudes_to_vector(Hr1, Hr2)
    return vector
Ejemplo n.º 2
0
def ipccsd_diag(eom, imds=None):
    if imds is None: imds = eom.make_imds()
    t1, t2 = imds.t1, imds.t2
    nocc, nvir = t1.shape
    foo = imds.eris.foo
    fvv = imds.eris.fvv

    Hr1 = -imds.Loo.diagonal()
    Hr1 = tensor(Hr1)
    if eom.partition == 'mp':
        ijb = -foo.diagonal().reshape(nocc, 1, 1)
        ijb = ijb - foo.diagonal().reshape(1, nocc, 1)
        ijb = ijb + fvv.diagonal().reshape(1, 1, nvir)
        Hr2 = tensor(ijb)
    else:
        wij = np.einsum('ijij->ij', imds.Woooo.array)
        wjb = np.einsum('jbjb->jb', imds.Wovov.array)
        wjb2 = np.einsum('jbbj->jb', imds.Wovvo.array)
        wib = np.einsum('ibib->ib', imds.Wovov.array)
        ijb = imds.Lvv.diagonal().reshape(1, 1, nvir)
        ijb = ijb - imds.Loo.diagonal().reshape(nocc, 1, 1)
        ijb = ijb - imds.Loo.diagonal().reshape(1, nocc, 1)
        #print(ijb.shape, wjb.shape)
        ijb = ijb + wij.reshape(nocc, nocc, 1)
        ijb = ijb - wjb.reshape(1, nocc, nvir)
        ijb = ijb + 2 * wjb2.reshape(1, nocc, nvir)
        ijb = ijb - np.einsum('ij,jb->ijb', np.eye(nocc), wjb2)
        ijb = ijb - wib.reshape(nocc, 1, nvir)
        Hr2 = tensor(ijb)
        Hr2 -= 2. * lib.einsum('ijcb,jibc->ijb', t2, imds.Woovv)
        Hr2 += lib.einsum('ijcb,ijbc->ijb', t2, imds.Woovv)
    vector = eom.amplitudes_to_vector(Hr1, Hr2)
    return vector
Ejemplo n.º 3
0
def get_range_symten(A,split,l,q=2):
    '''
    Compute a range that approximates the range of tensor A
    Reference: Algorithm 4.4 of https://arxiv.org/abs/0909.4061

    args:
        A: symtensor
            The symtensor whose range we are finding
        split: int
            The index along which the svd will be done
        l: int
            The number of vectors to be used (output will be size m x l)

    kwargs:
        q: int
            The number of iterations to perform (default = 2)

    returns:
        Q: symtensor
            An orthonormal tensor whose range
            approximates the range of the input tensor A
    '''
    # Get tensor dimensions
    ndiml = split
    ndimr = A.ndim-split

    # Generate Random Gaussian Matrix
    Omega = make_omega(A,split,l)

    # Initial Setup
    einstr = STR[:ndiml+ndimr]+','\
             +STR[ndiml:ndiml+ndimr+1]+'->'\
             +STR[:ndiml]+STR[ndiml+ndimr:ndiml+ndimr+1]
    Y = einsum(einstr,A,Omega)
    Q = orthonormal_ten(Y,ndiml)
    #Q = orthonormal_ten_slow(Y,ndiml)

    # Loop through iterations
    for i in range(q):

        # First step
        einstr =  STR[:ndiml+ndimr]+','\
                 +STR[:ndiml]+STR[ndiml+ndimr:ndiml+ndimr+1]+'->'\
                 +STR[ndiml:ndiml+ndimr+1]
        Y = einsum(einstr,A,Q)
        Q = orthonormal_ten(Y,ndimr)

        # Second Step
        einstr = STR[:ndiml+ndimr]+','\
                 +STR[ndiml:ndiml+ndimr+1]+'->'\
                 +STR[:ndiml]+STR[ndiml+ndimr:ndiml+ndimr+1]
        Y = einsum(einstr,A,Q)
        Q = orthonormal_ten(Y,ndiml)

    # Return Result
    return Q
Ejemplo n.º 4
0
def energy(cc, t1, t2, eris):
    log = Logger(cc.stdout, cc.verbose)
    nkpts = len(cc.kpts)
    e = 2 * lib.einsum('ia,ia', eris.fov, t1)
    tau = lib.einsum('ia,jb->ijab', t1, t1)
    tau += t2
    e += 2 * lib.einsum('ijab,iajb', tau, eris.ovov)
    e += -lib.einsum('ijab,ibja', tau, eris.ovov)
    if abs(e.imag) > 1e-4:
        log.warn('Non-zero imaginary part found in KRCCSD energy %s', e)
    return e.real / nkpts
Ejemplo n.º 5
0
 def init_amps(self, eris):
     time0 = time.clock(), time.time()
     log = Logger(self.stdout, self.verbose)
     nocc = self.nocc
     nvir = self.nmo - nocc
     kpts = self.kpts
     nkpts = self.nkpts
     gvec = self._scf.cell.reciprocal_vectors()
     sym1 = ['+-', [
         kpts,
     ] * 2, None, gvec]
     t1 = lib.zeros([nocc, nvir], eris.dtype, sym1)
     t2 = eris.ovov.transpose(0, 2, 1, 3).conj() / eris.eijab
     self.emp2 = 2 * lib.einsum('ijab,iajb', t2, eris.ovov)
     self.emp2 -= lib.einsum('ijab,ibja', t2, eris.ovov)
     self.emp2 = self.emp2.real / nkpts
     log.info('Init t2, MP2 energy (with fock eigenvalue shift) = %.15g',
              self.emp2)
     log.timer('init mp2', *time0)
     return self.emp2, t1, t2
Ejemplo n.º 6
0
def rsvd_symten(A,split,k,q=2,nover=2):
    '''
    Compute the svd of a tensor using the randomized svd algorithm
    detailed in https://arxiv.org/abs/0909.4061. Here, we use algorithm
    4.4 for step A and algorithm 5.1 for step B

    args:
        A: symtensor
            The matrix whose range we are finding
        split: int
            The index along which the svd will be done
        l: int
            The number of vectors to be used (output will be size m x l)

    kwargs:
        q: int
            The number of iterations to perform (default = 2)
        nover: int
            The number of extra vectors to be used (will be truncated off 
            at the end)

    returns:
        Q: symtensor
            The resulting unitary U tensor from SVD
        R: symtensor
            The resulting S*V tensor from SVD
    '''
    # Do Step A
    Q = get_range_symten(A,split,k+nover,q=q)

    # Do Step B
    ndiml = split
    ndimr = A.ndim-split
    einstr =  STR[:ndiml+1] + ','\
             +STR[:ndiml] + STR[ndiml+1:ndiml+ndimr+1] + '->'\
             +STR[ndiml:ndiml+ndimr+1]
    B = einsum(einstr,Q,A)

    # Truncate from l to  k
    Q = truncate(Q,Q.ndim-1,k)
    B = truncate(B,0,k)

    # Return Result
    return Q,B
Ejemplo n.º 7
0
def eaccsd_matvec(eom, vector, kshift, imds=None, diag=None):
    # Ref: Nooijen and Bartlett, J. Chem. Phys. 102, 3629 (1994) Eqs.(30)-(31)
    if imds is None: imds = eom.make_imds()
    r1, r2 = eom.vector_to_amplitudes(vector, kshift)

    # Eq. (30)
    # 1p-1p block
    Hr1 = lib.einsum('ac,c->a', imds.Lvv, r1)
    # 1p-2p1h block
    Hr1 += lib.einsum('ld,lad->a', 2. * imds.Fov, r2)
    Hr1 += lib.einsum('ld,lda->a', -imds.Fov, r2)
    Hr1 += 2 * lib.einsum('alcd,lcd->a', imds.Wvovv, r2)
    Hr1 += -lib.einsum('aldc,lcd->a', imds.Wvovv, r2)
    # Eq. (31)
    # 2p1h-1p block
    Hr2 = lib.einsum('abcj,c->jab', imds.Wvvvo, r1)
    # 2p1h-2p1h block
    if eom.partition == 'mp':
        foo = imds.eris.foo
        fvv = imds.eris.fvv
        Hr2 += lib.einsum('ac,jcb->jab', fvv, r2)
        Hr2 += lib.einsum('bd,jad->jab', fvv, r2)
        Hr2 += -lib.einsum('lj,lab->jab', foo, r2)
    elif eom.partition == 'full':
        Hr2 += eom._eaccsd_diag_matrix2 * r2
    else:
        Hr2 += lib.einsum('ac,jcb->jab', imds.Lvv, r2)
        Hr2 += lib.einsum('bd,jad->jab', imds.Lvv, r2)
        Hr2 += -lib.einsum('lj,lab->jab', imds.Loo, r2)
        Hr2 += 2 * lib.einsum('lbdj,lad->jab', imds.Wovvo, r2)
        Hr2 += -lib.einsum('lbjd,lad->jab', imds.Wovov, r2)
        Hr2 += -lib.einsum('lajc,lcb->jab', imds.Wovov, r2)
        Hr2 += -lib.einsum('lbcj,lca->jab', imds.Wovvo, r2)

        Hr2 += lib.einsum('abcd,jcd->jab', imds.Wvvvv, r2)
        tmp = (2 * lib.einsum('klcd,lcd->k', imds.Woovv, r2) -
               lib.einsum('kldc,lcd->k', imds.Woovv, r2))
        Hr2 += -lib.einsum('k,kjab->jab', tmp, imds.t2)

    vector = eom.amplitudes_to_vector(Hr1, Hr2)
    return vector
Ejemplo n.º 8
0
def ipccsd_matvec(eom, vector, kshift, imds=None, diag=None):
    # Ref: Nooijen and Snijders, J. Chem. Phys. 102, 1681 (1995) Eqs.(8)-(9)
    if imds is None: imds = eom.make_imds()
    r1, r2 = eom.vector_to_amplitudes(vector, kshift)

    # 1h-1h block
    Hr1 = -lib.einsum('ki,k->i', imds.Loo, r1)
    #1h-2h1p block
    Hr1 += 2 * lib.einsum('ld,ild->i', imds.Fov, r2)
    Hr1 += -lib.einsum('kd,kid->i', imds.Fov, r2)
    Hr1 += -2 * lib.einsum('klid,kld->i', imds.Wooov, r2)
    Hr1 += lib.einsum('lkid,kld->i', imds.Wooov, r2)

    # 2h1p-1h block
    Hr2 = -lib.einsum('kbij,k->ijb', imds.Wovoo, r1)
    # 2h1p-2h1p block
    if eom.partition == 'mp':
        foo = self.eris.foo
        fvv = self.eris.fvv
        Hr2 += lib.einsum('bd,ijd->ijb', fvv, r2)
        Hr2 += -lib.einsum('ki,kjb->ijb', foo, r2)
        Hr2 += -lib.einsum('lj,ilb->ijb', foo, r2)
    elif eom.partition == 'full':
        Hr2 += self._ipccsd_diag_matrix2 * r2
    else:
        Hr2 += lib.einsum('bd,ijd->ijb', imds.Lvv, r2)
        Hr2 += -lib.einsum('ki,kjb->ijb', imds.Loo, r2)
        Hr2 += -lib.einsum('lj,ilb->ijb', imds.Loo, r2)
        Hr2 += lib.einsum('klij,klb->ijb', imds.Woooo, r2)
        Hr2 += 2 * lib.einsum('lbdj,ild->ijb', imds.Wovvo, r2)
        Hr2 += -lib.einsum('kbdj,kid->ijb', imds.Wovvo, r2)
        Hr2 += -lib.einsum('lbjd,ild->ijb', imds.Wovov, r2)  #typo in Ref
        Hr2 += -lib.einsum('kbid,kjd->ijb', imds.Wovov, r2)
        tmp = 2 * lib.einsum('lkdc,kld->c', imds.Woovv, r2)
        tmp += -lib.einsum('kldc,kld->c', imds.Woovv, r2)
        Hr2 += -lib.einsum('c,ijcb->ijb', tmp, imds.t2)

    vector = eom.amplitudes_to_vector(Hr1, Hr2)
    return vector
Ejemplo n.º 9
0
    backend='numpy')
# put image into symtensor
A = np.array(mpl.image.imread(fname))
shape = A.shape
Aog = A.copy()
Aog2 = A.copy()
Aog3 = A.copy()
A = np.reshape(A, (-1))
nelem = np.prod(ten1.array.shape)
A = A[:nelem]
ten1.array = np.reshape(A, ten1.array.shape)
ten1.enforce_sym()

# Use existing SVD w/o trunc -----------------------------------------------
U, S, V = symsvd(ten1, [[0, 1, 2], [3, 4]])
A2 = einsum('ijkl,lmn->ijkmn', U, einsum('jk,klm->jlm', S, V))
Aog = np.reshape(Aog, (-1))
Aog[:nelem] = np.reshape(A2.array, (-1))
Aog = np.reshape(Aog, shape)
f = plt.figure()
plt.imshow(Aog)

# Use existing SVD w/ trunc -----------------------------------------------
U, S, V = symsvd(ten1, [[0, 1, 2], [3, 4]], truncate_mbd=k)
A2 = einsum('ijkl,lmn->ijkmn', U, einsum('jk,klm->jlm', S, V))
Aog2 = np.reshape(Aog2, (-1))
Aog2[:nelem] = np.reshape(A2.array, (-1))
Aog2 = np.reshape(Aog2, shape)
f = plt.figure()
plt.imshow(Aog2)