Beispiel #1
0
 def get_wfn_response(self,
                      atmlst=None,
                      state=None,
                      verbose=None,
                      mo=None,
                      ci=None,
                      **kwargs):
     if state is None: state = self.state
     if atmlst is None: atmlst = self.atmlst
     if verbose is None: verbose = self.verbose
     if mo is None: mo = self.base.mo_coeff
     if ci is None: ci = self.base.ci
     ndet = self.na_states[state] * self.nb_states[state]
     fcasscf = self.make_fcasscf(state)
     fcasscf.mo_coeff = mo
     fcasscf.ci = ci[state]
     eris = fcasscf.ao2mo(mo)
     g_all_state = newton_casscf.gen_g_hop(fcasscf, mo, ci[state], eris,
                                           verbose)[0]
     g_all = np.zeros(self.nlag)
     g_all[:self.ngorb] = g_all_state[:self.ngorb]
     # No need to reshape or anything, just use the magic of repeated slicing
     offs = sum([
         na * nb
         for na, nb in zip(self.na_states[:state], self.nb_states[:state])
     ]) if state > 0 else 0
     g_all[self.ngorb:][offs:][:ndet] = g_all_state[self.ngorb:]
     return g_all
Beispiel #2
0
 def get_Aop_Adiag(self,
                   atmlst=None,
                   state=None,
                   verbose=None,
                   mo=None,
                   ci=None,
                   eris=None,
                   level_shift=None,
                   **kwargs):
     if state is None: state = self.state
     if atmlst is None: atmlst = self.atmlst
     if verbose is None: verbose = self.verbose
     if mo is None: mo = self.base.mo_coeff
     if ci is None: ci = self.base.ci
     if eris is None and self.eris is None:
         eris = self.eris = self.base.ao2mo(mo)
     elif eris is None:
         eris = self.eris
     if not isinstance(self.base, StateAverageMCSCFSolver) and isinstance(
             ci, list):
         ci = ci[0]
     fcasscf = self.make_fcasscf_sa()
     Aop, Adiag = newton_casscf.gen_g_hop(fcasscf, mo, ci, eris,
                                          verbose)[2:]
     # Eliminate the component of Aop (x) which is parallel to the state-average space
     # The Lagrange multiplier equations are not defined there
     return self.project_Aop(Aop, ci, state), Adiag
Beispiel #3
0
    def test_derivatives(self):
        np.random.seed(1)
        las = LASSCF(mf, (4, ),
                     (4, ), spin_sub=(1, )).set(max_cycle_macro=1,
                                                ah_level_shift=0).run()
        ugg = las.get_ugg()
        ci0_csf = np.random.rand(ugg.ncsf_sub[0][0])
        ci0_csf /= np.linalg.norm(ci0_csf)
        ci0 = ugg.ci_transformers[0][0].vec_csf2det(ci0_csf)
        las_gorb, las_gci = las.get_grad(mo_coeff=mf.mo_coeff, ci=[[ci0]])[:2]
        las_grad = np.append(las_gorb, las_gci)
        las_hess = las.get_hop(ugg=ugg, mo_coeff=mf.mo_coeff, ci=[[ci0]])
        self.assertAlmostEqual(lib.fp(las_grad), lib.fp(las_hess.get_grad()),
                               8)
        cas_grad, _, cas_hess, _ = newton_casscf.gen_g_hop(
            mc, mf.mo_coeff, ci0, mc.ao2mo(mf.mo_coeff))
        _pack_ci, _unpack_ci = newton_casscf._pack_ci_get_H(
            mc, mf.mo_coeff, ci0)[-2:]

        def pack_cas(kappa, ci1):
            return np.append(mc.pack_uniq_var(kappa), _pack_ci(ci1))

        def unpack_cas(x):
            return mc.unpack_uniq_var(x[:ugg.nvar_orb]), _unpack_ci(
                x[ugg.nvar_orb:])

        def cas2las(y, mode='hx'):
            yorb, yci = unpack_cas(y)
            yc = yci[0].ravel().dot(ci0.ravel())
            yci[0] -= yc * ci0
            yorb *= (0.5 if mode == 'hx' else 1)
            return ugg.pack(yorb, [yci])

        def las2cas(y, mode='x'):
            yorb, yci = ugg.unpack(y)
            yc = yci[0][0].ravel().dot(ci0.ravel())
            yci[0][0] -= yc * ci0
            yorb *= (0.5 if mode == 'x' else 1)
            return pack_cas(yorb, yci[0])

        cas_grad = cas2las(cas_grad)
        self.assertAlmostEqual(lib.fp(las_grad), lib.fp(cas_grad), 8)
        x = np.random.rand(ugg.nvar_tot)
        # orb on input
        x_las = x.copy()
        x_las[ugg.nvar_orb:] = 0.0
        x_cas = las2cas(x_las, mode='x')
        hx_las = las_hess._matvec(x_las)
        hx_cas = cas2las(cas_hess(x_cas), mode='x')
        self.assertAlmostEqual(lib.fp(hx_las), lib.fp(hx_cas), 8)
        # CI on input
        x_las = x.copy()
        x_las[:ugg.nvar_orb] = 0.0
        x_cas = las2cas(x_las, mode='hx')
        hx_las = las_hess._matvec(x_las)
        hx_cas = cas2las(cas_hess(x_cas), mode='hx')
        self.assertAlmostEqual(lib.fp(hx_las), lib.fp(hx_cas), 8)
Beispiel #4
0
 def test_gen_g_hop(self):
     mo = mc.mo_coeff
     gall, gop, hop, hdiag = newton_casscf.gen_g_hop(
         mc, mo, ci0, mc.ao2mo(mo))
     self.assertAlmostEqual(lib.finger(gall), 21.288022525148595, 8)
     self.assertAlmostEqual(lib.finger(hdiag), -4.6864640132374618, 8)
     x = numpy.random.random(gall.size)
     u, ci1 = newton_casscf.extract_rotation(mc, x, 1, ci0)
     self.assertAlmostEqual(lib.finger(gop(u, ci1)), -412.9441873541524, 8)
     self.assertAlmostEqual(lib.finger(hop(x)), 73.358310983341198, 8)
Beispiel #5
0
 def test_gen_g_hop(self):
     mo = mc.mo_coeff
     gall, gop, hop, hdiag = newton_casscf.gen_g_hop(
         mc, mo, ci0, mc.ao2mo(mo))
     self.assertAlmostEqual(lib.finger(gall), 6.3906103343021083, 8)
     self.assertAlmostEqual(lib.finger(hdiag), -7.9071928112940615, 8)
     x = numpy.random.random(gall.size)
     u, ci1 = newton_casscf.extract_rotation(mc, x, 1, ci0)
     self.assertAlmostEqual(lib.finger(gop(u, ci1)), -419.68206754700418, 8)
     self.assertAlmostEqual(lib.finger(hop(x)), 78.31792009930723, 8)
Beispiel #6
0
 def test_gen_g_hop(self):
     numpy.random.seed(1)
     mo = numpy.random.random(mf.mo_coeff.shape)
     ci0 = numpy.random.random((6,6))
     ci0/= numpy.linalg.norm(ci0)
     gall, gop, hop, hdiag = newton_casscf.gen_g_hop(mc, mo, ci0, mc.ao2mo(mo))
     self.assertAlmostEqual(lib.finger(gall), 21.288022525148595, 8)
     self.assertAlmostEqual(lib.finger(hdiag), -4.6864640132374618, 8)
     x = numpy.random.random(gall.size)
     u, ci1 = newton_casscf.extract_rotation(mc, x, 1, ci0)
     self.assertAlmostEqual(lib.finger(gop(u, ci1)), -412.9441873541524, 8)
     self.assertAlmostEqual(lib.finger(hop(x)), 73.358310983341198, 8)
Beispiel #7
0
 def test_sa_gen_g_hop(self):
     numpy.random.seed(1)
     mo = numpy.random.random(mf.mo_coeff.shape)
     ci0 = numpy.random.random((2, 36))
     ci0 /= numpy.linalg.norm(ci0, axis=1)[:, None]
     ci0 = list(ci0.reshape((2, 6, 6)))
     gall, gop, hop, hdiag = newton_casscf.gen_g_hop(
         sa, mo, ci0, sa.ao2mo(mo))
     self.assertAlmostEqual(lib.finger(gall), 32.46973284682045, 8)
     self.assertAlmostEqual(lib.finger(hdiag), -63.6527761153809, 8)
     x = numpy.random.random(gall.size)
     u, ci1 = newton_casscf.extract_rotation(sa, x, 1, ci0)
     self.assertAlmostEqual(lib.finger(gop(u, ci1)), -49.017079186126, 8)
     self.assertAlmostEqual(lib.finger(hop(x)), 169.47893548740288, 8)
Beispiel #8
0
 def test_derivatives (self):
     np.random.seed(1)
     las = LASSCF (mf, (4,), (4,), spin_sub=(1,)).set (max_cycle_macro=1, ah_level_shift=0)
     las.state_average_(weights=[0.5,0.5], charges=[0,0], spins=[0,2], smults=[1,3]).run ()
     ugg = las.get_ugg ()
     ci0_csf = [np.random.rand (ncsf) for ncsf in ugg.ncsf_sub[0]]
     ci0_csf = [c / np.linalg.norm (c) for c in ci0_csf]
     ci0 = [t.vec_csf2det (c) for t, c in zip (ugg.ci_transformers[0], ci0_csf)]
     las_gorb, las_gci = las.get_grad (mo_coeff=mf.mo_coeff, ci=[ci0])[:2]
     las_grad = np.append (las_gorb, las_gci)
     las_hess = las.get_hop (ugg=ugg, mo_coeff=mf.mo_coeff, ci=[ci0])
     self.assertAlmostEqual (lib.fp (las_grad), lib.fp (las_hess.get_grad ()), 8)
     cas_grad, _, cas_hess, _ = newton_casscf.gen_g_hop (mc, mf.mo_coeff, ci0, mc.ao2mo (mf.mo_coeff))
     _pack_ci, _unpack_ci = newton_casscf._pack_ci_get_H (mc, mf.mo_coeff, ci0)[-2:]
     def pack_cas (kappa, ci1):
         return np.append (mc.pack_uniq_var (kappa), _pack_ci (ci1))
     def unpack_cas (x):
         return mc.unpack_uniq_var (x[:ugg.nvar_orb]), _unpack_ci (x[ugg.nvar_orb:])
     def cas2las (y, mode='hx'):
         yorb, yci = unpack_cas (y)
         yci = [2 * (yc - c * c.ravel ().dot (yc.ravel ())) for c, yc in zip (ci0, yci)]
         yorb *= (0.5 if mode=='hx' else 1)
         return ugg.pack (yorb, [yci])
     def las2cas (y, mode='x'):
         yorb, yci = ugg.unpack (y)
         yci = [yc - c * c.ravel ().dot (yc.ravel ()) for c, yc in zip (ci0, yci[0])]
         yorb *= (0.5 if mode=='x' else 1)
         return pack_cas (yorb, yci)
     cas_grad = cas2las (cas_grad)
     self.assertAlmostEqual (lib.fp (las_grad), lib.fp (cas_grad), 8)
     x = np.random.rand (ugg.nvar_tot)
     # orb on input
     x_las = x.copy ()
     x_las[ugg.nvar_orb:] = 0.0
     x_cas = las2cas (x_las, mode='x')
     hx_las = las_hess._matvec (x_las)
     hx_cas = cas2las (cas_hess (x_cas), mode='x')
     self.assertAlmostEqual (lib.fp (hx_las), lib.fp (hx_cas), 8)
     # CI on input
     x_las = x.copy ()
     x_las[:ugg.nvar_orb] = 0.0
     x_cas = las2cas (x_las, mode='hx')
     hx_las = las_hess._matvec (x_las)
     hx_cas = cas2las (cas_hess (x_cas), mode='hx')
     self.assertAlmostEqual (lib.fp (hx_las), lib.fp (hx_cas), 8)
Beispiel #9
0
    def get_wfn_response(self,
                         atmlst=None,
                         state=None,
                         verbose=None,
                         mo=None,
                         ci=None,
                         veff1=None,
                         veff2=None,
                         **kwargs):
        if state is None: state = self.state
        if atmlst is None: atmlst = self.atmlst
        if verbose is None: verbose = self.verbose
        if mo is None: mo = self.base.mo_coeff
        if ci is None: ci = self.base.ci
        if (veff1 is None) or (veff2 is None):
            assert (False), kwargs
            veff1, veff2 = self.base.get_pdft_veff(mo,
                                                   ci[state],
                                                   incl_coul=True,
                                                   paaa_only=True)
        ndet = ci[state].size
        fcasscf = self.make_fcasscf(state)
        fcasscf.mo_coeff = mo
        fcasscf.ci = ci[state]

        def my_hcore():
            return self.base.get_hcore() + veff1

        fcasscf.get_hcore = my_hcore

        g_all_state = newton_casscf.gen_g_hop(fcasscf, mo, ci[state], veff2,
                                              verbose)[0]

        g_all = np.zeros(self.nlag)
        g_all[:self.ngorb] = g_all_state[:self.ngorb]
        # Eliminate gradient of self-rotation
        gci_state = g_all_state[self.ngorb:]
        ci_arr = np.asarray(ci).reshape(self.nroots, -1)
        gci_sa = np.dot(ci_arr[state], gci_state)
        gci_state -= gci_sa * gci_state
        gci = g_all[self.ngorb:].reshape(self.nroots, -1)
        gci[state] += gci_state

        return g_all
Beispiel #10
0
 def get_wfn_response(self,
                      atmlst=None,
                      iroot=None,
                      verbose=None,
                      mo=None,
                      ci=None,
                      **kwargs):
     if iroot is None: iroot = self.iroot
     if atmlst is None: atmlst = self.atmlst
     if verbose is None: verbose = self.verbose
     if mo is None: mo = self.base.mo_coeff
     if ci is None: ci = self.base.ci
     ndet = ci[iroot].size
     fcasscf = self.make_fcasscf()
     fcasscf.mo_coeff = mo
     fcasscf.ci = ci[iroot]
     eris = fcasscf.ao2mo(mo)
     g_all_iroot = newton_casscf.gen_g_hop(fcasscf, mo, ci[iroot], eris,
                                           verbose)[0]
     g_all = np.zeros(self.nlag)
     g_all[:self.ngorb] = g_all_iroot[:self.ngorb]
     # No need to reshape or anything, just use the magic of repeated slicing
     g_all[self.ngorb:][ndet * iroot:][:ndet] = g_all_iroot[self.ngorb:]
     return g_all
Beispiel #11
0
    mc.kernel ()
    #mo_coeff = mc.mo_coeff.copy ()
    print (mc.converged, mc.e_tot)
    las = LASSCFNoSymm (mf, (4,), ((2,2),), spin_sub=(1,))
    las.kernel (mo_coeff)

    mc.mo_coeff = mo_coeff.copy ()
    las.mo_coeff = mo_coeff.copy ()
    las.ci = [[mc.ci.copy ()]]

    nao, nmo = mo_coeff.shape
    ncore, ncas = mc.ncore, mc.ncas
    nocc = ncore + ncas
    eris = mc.ao2mo ()
    from pyscf.mcscf.newton_casscf import gen_g_hop, _pack_ci_get_H
    g_all_cas, g_update_cas, h_op_cas, hdiag_all_cas = gen_g_hop (mc, mo_coeff, mc.ci, eris)
    _pack_ci, _unpack_ci = _pack_ci_get_H (mc, mo_coeff, mc.ci)[-2:]
    nvar_orb_cas = np.count_nonzero (mc.uniq_var_indices (nmo, mc.ncore, mc.ncas, mc.frozen))
    nvar_tot_cas = g_all_cas.size
    def pack_cas (kappa, ci1):
        return np.append (mc.pack_uniq_var (kappa), _pack_ci (ci1))
    def unpack_cas (x):
        return mc.unpack_uniq_var (x[:nvar_orb_cas]), _unpack_ci (x[nvar_orb_cas:])

    ugg = las.get_ugg (las.mo_coeff, las.ci)
    h_op_las = las.get_hop (ugg=ugg)

    print ("Total # variables: {} CAS ; {} LAS".format (nvar_tot_cas, ugg.nvar_tot))
    print ("# orbital variables: {} CAS ; {} LAS".format (nvar_orb_cas, ugg.nvar_orb))

    gorb_cas, gci_cas = unpack_cas (g_all_cas)
Beispiel #12
0
def gen_g_hop(casscf, mo, ci0, eris, verbose=None):
    # MRH: I'm just going to pass this to the newton_casscf version and average/weight/change to and from CSF's post facto!
    ncas = casscf.ncas
    ncore = casscf.ncore
    nocc = ncas + ncore
    nelecas = casscf.nelecas
    neleca, nelecb = _unpack_nelec(nelecas)
    nmo = mo.shape[1]
    nroot = len(ci0)
    ndet = ci0[0].size
    norb = mo.shape[-1]
    ngorb = np.count_nonzero(
        casscf.uniq_var_indices(norb, ncore, ncas, casscf.frozen))
    weights_2d = np.asarray(casscf.weights)[:, None]
    weights_3d = np.asarray(casscf.weights)[:, None, None]
    mc_fci = casscf.fcisolver
    is_csf = isinstance(mc_fci, (
        csf.FCISolver,
        csf_symm.FCISolver,
    ))
    if is_csf:
        if hasattr(mc_fci, 'wfnsym') and hasattr(mc_fci, 'confsym'):
            idx_sym = mc_fci.confsym[mc_fci.econf_csf_mask] == mc_fci.wfnsym
        else:
            idx_sym = None
        smult = mc_fci.smult

    fcasscf = mc1step.CASSCF(casscf._scf, ncas, nelecas)
    fcasscf.fcisolver = casscf.ss_fcisolver
    gh_roots = [
        newton_casscf.gen_g_hop(fcasscf, mo, ci0_i, eris, verbose=verbose)
        for ci0_i in ci0
    ]

    def avg_orb_wgt_ci(x_roots):
        x_orb = sum([
            x_iroot[:ngorb] * w for x_iroot, w in zip(x_roots, casscf.weights)
        ])
        x_ci = np.stack([
            x_iroot[ngorb:] * w for x_iroot, w in zip(x_roots, casscf.weights)
        ],
                        axis=0)
        if is_csf:
            x_ci = csf.pack_sym_ci(
                transform_civec_det2csf(x_ci,
                                        ncas,
                                        neleca,
                                        nelecb,
                                        smult,
                                        csd_mask=mc_fci.csd_mask,
                                        do_normalize=False)[0], idx_sym)
        x_all = np.append(x_orb, x_ci.ravel()).ravel()
        return x_all

    g_all = avg_orb_wgt_ci([gh_iroot[0] for gh_iroot in gh_roots])
    hdiag_all = avg_orb_wgt_ci([gh_iroot[3] for gh_iroot in gh_roots])

    def g_update(u, fcivec):
        return avg_orb_wgt_ci(
            [gh_iroot[1](u, ci) for gh_iroot, ci in zip(gh_roots, fcivec)])

    def h_op(x):
        x_orb = x[:ngorb]
        x_ci = x[ngorb:].reshape(nroot, -1)
        if is_csf:
            x_ci = transform_civec_csf2det(csf.unpack_sym_ci(x_ci, idx_sym),
                                           ncas,
                                           neleca,
                                           nelecb,
                                           smult,
                                           csd_mask=mc_fci.csd_mask,
                                           do_normalize=False)[0]
        return avg_orb_wgt_ci([
            gh_iroot[2](np.append(x_orb, x_ci_iroot))
            for gh_iroot, x_ci_iroot in zip(gh_roots, x_ci)
        ])

    return g_all, g_update, h_op, hdiag_all