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)
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)