def test_2_2_sym(self): refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fock("o1o1")).set_random() b = empty_like(refstate.fock("v1v1")).set_random() no, _ = a.shape nv, _ = b.shape res = direct_sum("ij+ab", a, b) assert res.shape == (no, no, nv, nv) ref = a.to_ndarray()[:, :, None, None] + b.to_ndarray()[None, None, :, :] assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14) res = direct_sum("-ij+ab->jabi", a, b) assert res.shape == (no, nv, nv, no) ref = -a.to_ndarray()[:, :, None, None] + b.to_ndarray()[None, None, :, :] ref = ref.transpose((1, 2, 3, 0)) assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14) res = direct_sum("-ij-ab->abij", a, b) assert res.shape == (nv, nv, no, no) ref = -a.to_ndarray()[:, :, None, None] - b.to_ndarray()[None, None, :, :] ref = ref.transpose((2, 3, 0, 1)) assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14)
def test_nontrivial_trace(self): import libadcc refstate = cache.refstate["cn_sto3g"] oovv = empty_like(refstate.eri("o1o1v1v1")).set_random() ovov = empty_like(refstate.eri("o1v1o1v1")).set_random() noovv = oovv.to_ndarray() novov = ovov.to_ndarray() res = libadcc.trace("iaai", einsum("ijab,kcja->icbk", oovv, ovov)) ref = np.einsum("ijab,ibja->", noovv, novov) assert_allclose(res, ref, rtol=1e-10, atol=1e-14)
def template_nontrivial_contraction(self, case): refstate = cache.refstate[case] f_oo = empty_like(refstate.fock("o1o1")).set_random() f_vv = empty_like(refstate.fock("v1v1")).set_random() i1 = empty_like(refstate.fock("v1v1")).set_random() i2 = empty_like(refstate.fock("o1o1")).set_random() oovv = empty_like(refstate.eri("o1o1v1v1")).set_random() ovov = empty_like(refstate.eri("o1v1o1v1")).set_random() t2 = empty_like(refstate.eri("o1o1v1v1")).set_random() u1 = empty_like(refstate.fock("o1v1")).set_random() nf_oo = f_oo.to_ndarray() nf_vv = f_vv.to_ndarray() ni1 = i1.to_ndarray() ni2 = i2.to_ndarray() noovv = oovv.to_ndarray() novov = ovov.to_ndarray() nt2 = t2.to_ndarray() nu1 = u1.to_ndarray() # (Slightly) modified ADC(2) singles block equation res = (+einsum("ib,ab->ia", u1, f_vv + i1) - einsum("ij,ja->ia", f_oo - i2, u1) - einsum("jaib,jb->ia", ovov, u1) - 0.5 * einsum("ijab,jkbc,kc->ia", t2, oovv, u1) - 0.5 * einsum("ijab,jkbc,kc->ia", oovv, t2, u1)) ref = (+np.einsum("ib,ab->ia", nu1, nf_vv + ni1) - np.einsum("ij,ja->ia", nf_oo - ni2, nu1) - np.einsum("jaib,jb->ia", novov, nu1) - 0.5 * np.einsum("ijab,jkbc,kc->ia", nt2, noovv, nu1) - 0.5 * np.einsum("ijab,jkbc,kc->ia", noovv, nt2, nu1)) assert res.needs_evaluation assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14)
def template_nontrivial_addition(self, case): refstate = cache.refstate[case] mtcs = [ empty_like(refstate.fock("o1v1")).set_random(), empty_like(refstate.fock("v1o1")).set_random(), empty_like(refstate.fock("o1v1")).set_random() ] mnps = [m.to_ndarray() for m in mtcs] res = -3 * (2 * mtcs[0] + mtcs[1].T) * mtcs[2] ref = -3 * (2 * mnps[0] + mnps[1].T) * mnps[2] assert res.needs_evaluation assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14)
def test_matvec_adc2(self): ground_state = adcc.LazyMp(cache.refstate["h2o_sto3g"]) matrix = adcc.AdcMatrix("adc2", ground_state) cppmatrix = libadcc.AdcMatrix("adc2", ground_state) vectors = [adcc.guess_zero(matrix) for i in range(3)] for vec in vectors: vec["s"].set_random() vec["d"].set_random() v, w, x = vectors # Compute references: refv = adcc.empty_like(v) refw = adcc.empty_like(w) refx = adcc.empty_like(x) cppmatrix.compute_matvec(v.to_cpp(), refv.to_cpp()) cppmatrix.compute_matvec(w.to_cpp(), refw.to_cpp()) cppmatrix.compute_matvec(x.to_cpp(), refx.to_cpp()) # @ operator (1 vector) resv = matrix @ v diffv = refv - resv assert diffv["s"].dot(diffv["s"]) < 1e-12 assert diffv["d"].dot(diffv["d"]) < 1e-12 # @ operator (multiple vectors) resv, resw, resx = matrix @ [v, w, x] diffs = [refv - resv, refw - resw, refx - resx] for i in range(3): assert diffs[i]["s"].dot(diffs[i]["s"]) < 1e-12 assert diffs[i]["d"].dot(diffs[i]["d"]) < 1e-12 # compute matvec matrix.compute_matvec(v, resv) diffv = refv - resv assert diffv["s"].dot(diffv["s"]) < 1e-12 assert diffv["d"].dot(diffv["d"]) < 1e-12 matrix.compute_apply("ss", v["s"], resv["s"]) cppmatrix.compute_apply("ss", v["s"], refv["s"]) diffv = resv["s"] - refv["s"] assert diffv.dot(diffv) < 1e-12
def test_nontrivial_direct_sum(self): refstate = cache.refstate["cn_sto3g"] oeo = nosym_like(refstate.orbital_energies("o1")).set_random() oovv = empty_like(refstate.eri("o1o1v1v1")).set_random() oev = nosym_like(refstate.orbital_energies("v1")).set_random() interm = np.einsum("ijac,ijcb->ab", oovv.to_ndarray(), oovv.to_ndarray()) ref = (interm[:, :, None, None] - oeo.to_ndarray()[None, None, :, None] - oev.to_ndarray()[None, None, None, :]) ref = ref.transpose((2, 0, 3, 1)) res = direct_sum("ab-i-c->iacb", einsum("ijac,ijcb->ab", oovv, oovv), oeo, oev) assert_allclose(res.to_ndarray(), ref, rtol=1e-10, atol=1e-14)
def symmetrise(self, new_vectors, existing_subspace): """ Symmetrise a set of new vectors to be added to the subspace. new_vectors Vectors to symmetrise (updated in-place) existing_subspace Existing subspace to take as a template Returns: The updated new_vectors It should be noted: - No orthogonalisation is performed - Only new_vectors are operated upon, existing_subspace is assumed to be properly symmetrised already. - Does not add new_vectors to the existing_subspace object """ if not isinstance(existing_subspace[0], AmplitudeVector): raise TypeError("existing_subspace has to be an " "iterable of AmplitudeVector") for vec in new_vectors: if not isinstance(vec, AmplitudeVector): raise TypeError("new_vectors has to be an " "iterable of AmplitudeVector") for b in vec.blocks: if b not in self.sym_for_block: continue index_symm_func = self.sym_for_block[b] # Create an empty block from the subspace vectors # since this has the appropriate symmetry set up symmetrised = empty_like(existing_subspace[0][b]) # # symmetrise what we have (syntax is function(in, out) index_symm_func(vec[b], symmetrised) # # Substitute inside the passed amplitude vector vec[b] = symmetrised return new_vectors
def test_einsum_4_4_2(self): # (3, 4, 4) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1v1o1v1")) b = empty_like(refstate.eri("o1o1o1v1")) self.base_test("iajb,jikb->ka", a, b)
def test_einsum_4_4_4_pjoi(self): # (2, 4, 4) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1o1v1v1")) b = empty_like(refstate.eri("v1v1v1v1")) self.base_test("opvw,vijw->pjoi", a, b)
def test_einsum_2_4_2(self): # (2, 2, 4) in C++ refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fock("o1o1")) b = empty_like(refstate.eri("o1v1o1v1")) self.base_test("ij,ikjl->kl", a, b)
def test_einsum_2_2_0(self): refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.fock("o1o1")) b = empty_like(refstate.fock("o1v1")) self.base_test("ij,ka->kjai", a, b)
def test_diagonal_7(self): refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.ovov) b = empty_like(refstate.fvv) self.base_test("iaib,ba->ia", a, b)
def test_diagonal_5(self): refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.ovov) b = empty_like(refstate.foo) self.base_test("laib,il->aib", a, b)
def test_contract_4_4_4_pjoi(self): # (2, 4, 4) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1o1v1v1")) b = empty_like(refstate.eri("v1v1v1v1")) out = nosym_like(refstate.eri("o1v1o1v1")) self.base_test("opvw,vijw->pjoi", a, b, out)
def test_diagonal_2(self): refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1v1o1v1")) self.base_test("iaia->ai", a)
def test_diagonal_4(self): refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.ovov) self.base_test("iaja->ija", a)
def test_contract_4_4_2(self): # (3, 4, 4) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1v1o1v1")) b = empty_like(refstate.eri("o1o1o1v1")) out = nosym_like(refstate.fock("o1v1")) self.base_test("iajb,jikb->ka", a, b, out)
def test_diagonal_6(self): refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fov) b = empty_like(refstate.fvo) self.base_test("ai,ia->i", a, b)
def test_contract_2_1_1(self): # (1,2,1) in C++ refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fock("o1v1")) b = empty_like(refstate.orbital_energies("v1")) out = nosym_like(refstate.orbital_energies("o1")) self.base_test("ij,j->i", a, b, out)
def test_partial_trace(self): refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.ovov) b = empty_like(refstate.fvv) with pytest.raises(NotImplementedError, match=r"Partial traces.*"): einsum("iaib,ba->a", a, b)
def test_contract_2_4_2(self): # (2, 2, 4) in C++ refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fock("o1o1")) b = empty_like(refstate.eri("o1v1o1v1")) out = nosym_like(refstate.fock("v1v1")) self.base_test("ij,ikjl->kl", a, b, out)
def test_einsum_2_1_1(self): # (1,2,1) in C++ refstate = cache.refstate["h2o_sto3g"] a = empty_like(refstate.fock("o1v1")) b = empty_like(refstate.orbital_energies("v1")) self.base_test("ij,j->i", a, b)
def test_contract_4_2_4_perm(self): # (1, 4, 2) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1o1v1v1")) b = empty_like(refstate.fock("v1v1")) out = nosym_like(refstate.eri("o1v1o1v1")) self.base_test("ijkl,km->imjl", a, b, out)
def test_einsum_4_2_4_perm(self): # (1, 4, 2) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1o1v1v1")) b = empty_like(refstate.fock("v1v1")) self.base_test("ijkl,km->imjl", a, b)
def test_einsum_4_2_2(self): # (2, 4, 2) in C++ refstate = cache.refstate["cn_sto3g"] a = empty_like(refstate.eri("o1o1v1v1")) b = empty_like(refstate.fock("o1v1")) self.base_test("ijkl,jk->li", a, b)