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)