def test_apply_spinful_fermionop(self): """ Make sure the spin-orbital reordering is working by comparing apply operation """ wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') wfn.normalize() cirq_wf = to_cirq(wfn).reshape((-1, 1)) op_to_apply = FermionOperator() test_state = copy.deepcopy(wfn) test_state.set_wfn('zero') for p, q, r, s in product(range(2), repeat=4): op = FermionOperator( ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)), coefficient=numpy.random.randn()) op_to_apply += op + hermitian_conjugated(op) test_state += wfn.apply(op + hermitian_conjugated(op)) opmat = get_sparse_operator(op_to_apply, n_qubits=4).toarray() new_state_cirq = opmat @ cirq_wf # this part is because we need to pass a normalized wavefunction norm_constant = new_state_cirq.conj().T @ new_state_cirq new_state_cirq /= numpy.sqrt(norm_constant) new_state_wfn = from_cirq(new_state_cirq.flatten(), thresh=1.0E-12) new_state_wfn.scale(numpy.sqrt(norm_constant)) self.assertTrue( numpy.allclose(test_state.get_coeff((2, 0)), new_state_wfn.get_coeff((2, 0))))
def test_lih_dipole(self): """Calculate the LiH dipole """ norb = 6 nalpha = 2 nbeta = 2 nele = nalpha + nbeta au2debye = 2.5417464157449032 dip_ref, dip_mat, lih_ground = build_lih_data.build_lih_data('dipole') wfn = Wavefunction([[nele, nalpha - nbeta, norb]]) wfn.set_wfn(strategy='from_data', raw_data={(nele, nalpha - nbeta): lih_ground}) hwfn_x = wfn._apply_array(tuple([dip_mat[0]]), e_0=0. + 0.j) hwfn_y = wfn._apply_array(tuple([dip_mat[1]]), e_0=0. + 0.j) hwfn_z = wfn._apply_array(tuple([dip_mat[2]]), e_0=0. + 0.j) calc_dip = numpy.array([fqe.vdot(wfn, hwfn_x).real, \ fqe.vdot(wfn, hwfn_y).real, \ fqe.vdot(wfn, hwfn_z).real])*au2debye for card in range(3): with self.subTest(dip=card): err = abs(calc_dip[card] - dip_ref[card]) self.assertTrue(err < 1.e-5)
def test_evolve_spinful_fermionop(self): """ Make sure the spin-orbital reordering is working by comparing time evolution """ wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') wfn.normalize() cirq_wf = to_cirq(wfn).reshape((-1, 1)) op_to_apply = FermionOperator() for p, q, r, s in product(range(2), repeat=4): op = FermionOperator( ((2 * p, 1), (2 * q + 1, 1), (2 * r + 1, 0), (2 * s, 0)), coefficient=numpy.random.randn()) op_to_apply += op + hermitian_conjugated(op) opmat = get_sparse_operator(op_to_apply, n_qubits=4).toarray() dt = 0.765 new_state_cirq = scipy.linalg.expm(-1j * dt * opmat) @ cirq_wf new_state_wfn = from_cirq(new_state_cirq.flatten(), thresh=1.0E-12) test_state = wfn.time_evolve(dt, op_to_apply) self.assertTrue( numpy.allclose(test_state.get_coeff((2, 0)), new_state_wfn.get_coeff((2, 0))))
def test_general_exceptions(self): """Test general method exceptions """ test1 = Wavefunction(param=[[2, 0, 4]]) test2 = Wavefunction(param=[[4, -4, 8]]) test1.set_wfn(strategy='ones') test2.set_wfn(strategy='ones') self.assertRaises(ValueError, test1.ax_plus_y, 1.0, test2) self.assertRaises(ValueError, test1.__add__, test2) self.assertRaises(ValueError, test1.__sub__, test2) self.assertRaises(ValueError, test1.set_wfn, strategy='from_data')
def test_apply_diagonal(self): wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') data = numpy.random.rand(2) hamil = diagonal_hamiltonian.Diagonal(data) out1 = wfn._apply_diagonal(hamil) fac = 0.5 hamil = diagonal_hamiltonian.Diagonal(data, e_0=fac) out2 = wfn._apply_diagonal(hamil) out2.ax_plus_y(-fac, wfn) self.assertTrue((out1 - out2).norm() < 1.0e-8)
def test_apply_nbody(self): wfn = Wavefunction([[2, 0, 2]]) wfn.set_wfn(strategy='random') fac = 3.14 fop = FermionOperator('1^ 1', fac) hamil = sparse_hamiltonian.SparseHamiltonian(fop) out1 = wfn._apply_few_nbody(hamil) fop = FermionOperator('1 1^', fac) hamil = sparse_hamiltonian.SparseHamiltonian(fop) out2 = wfn._apply_few_nbody(hamil) out2.scale(-1.0) out2.ax_plus_y(fac, wfn) self.assertTrue((out1 - out2).norm() < 1.0e-8)
def test_lih_energy(self): """Checking total energy with LiH """ eref = -8.877719570384043 norb = 6 nalpha = 2 nbeta = 2 nele = nalpha + nbeta h1e, h2e, lih_ground = build_lih_data.build_lih_data('energy') elec_hamil = general_hamiltonian.General((h1e, h2e)) wfn = Wavefunction([[nele, nalpha - nbeta, norb]]) wfn.set_wfn(strategy='from_data', raw_data={(nele, nalpha - nbeta): lih_ground}) ecalc = wfn.expectationValue(elec_hamil) self.assertAlmostEqual(eref, ecalc, places=8)
def test_hartree_fock_init(self): h1e, h2e, _ = build_lih_data('energy') elec_hamil = get_restricted_hamiltonian((h1e, h2e)) norb = 6 nalpha = 2 nbeta = 2 wfn = Wavefunction([[nalpha + nbeta, nalpha - nbeta, norb]]) wfn.print_wfn() wfn.set_wfn(strategy='hartree-fock') wfn.print_wfn() self.assertEqual(wfn.expectationValue(elec_hamil), -8.857341498221992) hf_wf = numpy.zeros((int(binom(norb, 2)), int(binom(norb, 2)))) hf_wf[0, 0] = 1. self.assertTrue(numpy.allclose(wfn.get_coeff((4, 0)), hf_wf)) wfn = Wavefunction([[nalpha + nbeta, nalpha - nbeta, norb], [nalpha + nbeta, 2, norb]]) self.assertRaises(ValueError, wfn.set_wfn, strategy='hartree-fock')
def test_rdm(self): """Check that the rdms will properly return the energy """ wfn = Wavefunction(param=[[4, 0, 3]]) work, energy = build_wfn.restricted_wfn_energy() wfn.set_wfn(strategy='from_data', raw_data={(4, 0): work}) rdm1 = wfn.rdm('i^ j') rdm2 = wfn.rdm('i^ j^ k l') rdm3 = wfn.rdm('i^ j^ k^ l m n') rdm4 = wfn.rdm('i^ j^ k^ l^ m n o p') h1e, h2e, h3e, h4e = build_hamiltonian.build_restricted(3, full=False) expval = 0. + 0.j axes = [0, 1] expval += numpy.tensordot(h1e, rdm1, axes=(axes, axes)) axes = [0, 1, 2, 3] expval += numpy.tensordot(h2e, rdm2, axes=(axes, axes)) axes = [0, 1, 2, 3, 4, 5] expval += numpy.tensordot(h3e, rdm3, axes=(axes, axes)) axes = [0, 1, 2, 3, 4, 5, 6, 7] expval += numpy.tensordot(h4e, rdm4, axes=(axes, axes)) self.assertAlmostEqual(expval, energy)
def test_wick(self): """Check that wick performs the proper restructuring of the density matrix given a string of indexes. """ norb = 4 nele = 4 s_z = 0 wfn = Wavefunction([[nele, s_z, norb]]) numpy.random.seed(seed=1) wfn.set_wfn(strategy='random') wfn.normalize() rdms = wfn._compute_rdm(4) out1 = wick.wick('k j^', list(rdms), True) two = numpy.eye(norb, dtype=out1.dtype) * 2.0 self.assertRaises(ValueError, wick.wick, 'k0 j', list(rdms)) self.assertTrue(numpy.allclose(two - out1.T, rdms[0])) self.assertRaises(ValueError, wick.wick, 'k^ l i^ j', list(rdms), True) out2 = wick.wick('k l i^ j^', list(rdms), True) h_1 = numpy.zeros_like(out1) for i in range(norb): h_1[:, :] += out2[:, i, :, i] / (norb * 2 - nele - 1) self.assertAlmostEqual(numpy.std(out1 + h_1), 0.) out2a = wick.wick('k l^ i^ j', list(rdms), True) self.assertAlmostEqual(out2a[2, 3, 0, 1], -rdms[1][0, 3, 2, 1]) out3 = wick.wick('k l m i^ j^ n^', list(rdms), True) h_2 = numpy.zeros_like(out2) for i in range(norb): h_2[:, :, :, :] += out3[:, i, :, :, i, :] / (norb * 2 - nele - 2) self.assertAlmostEqual(numpy.std(out2 - h_2), 0.) out4 = wick.wick('k l m x i^ j^ n^ y^', list(rdms), True) h_3 = numpy.zeros_like(out3) for i in range(norb): h_3[:, :, :, :, :, :] += out4[:, i, :, :, :, i, :, :] / (norb * 2 - nele - 3) self.assertAlmostEqual(numpy.std(out3 + h_3), 0.)
def test_lih_ops(self): """Check the value of the operators on LiH """ norb = 6 nalpha = 2 nbeta = 2 nele = nalpha + nbeta _, _, lih_ground = build_lih_data.build_lih_data('energy') wfn = Wavefunction([[nele, nalpha - nbeta, norb]]) wfn.set_wfn(strategy='from_data', raw_data={(nele, nalpha - nbeta): lih_ground}) operator = S2Operator() self.assertAlmostEqual(wfn.expectationValue(operator), 0. + 0.j) operator = SzOperator() self.assertAlmostEqual(wfn.expectationValue(operator), 0. + 0.j) operator = TimeReversalOp() self.assertAlmostEqual(wfn.expectationValue(operator), 1. + 0.j) operator = NumberOperator() self.assertAlmostEqual(wfn.expectationValue(operator), 4. + 0.j) self.assertAlmostEqual(wfn.expectationValue(operator, wfn), 4. + 0.j)
def test_apply_number(self): norb = 4 test = numpy.random.rand(norb, norb) diag = numpy.random.rand(norb * 2) diag2 = copy.deepcopy(diag) e_0 = 0 for i in range(norb): e_0 += diag[i + norb] diag2[i + norb] = -diag[i + norb] hamil = diagonal_hamiltonian.Diagonal(diag2, e_0=e_0) hamil._conserve_number = False wfn = Wavefunction([[4, 2, norb]], broken=['number']) wfn.set_wfn(strategy='from_data', raw_data={(4, 2): test}) out1 = wfn.apply(hamil) hamil = diagonal_hamiltonian.Diagonal(diag) wfn = Wavefunction([[4, 2, norb]]) wfn.set_wfn(strategy='from_data', raw_data={(4, 2): test}) out2 = wfn.apply(hamil) self.assertTrue( numpy.allclose(out1._civec[(4, 2)].coeff, out2._civec[(4, 2)].coeff))
def test_general_functions(self): """Test general wavefunction members """ test = Wavefunction(param=[[2, 0, 4]]) test.set_wfn(strategy='ones') self.assertEqual(1. + 0.j, test[(4, 8)]) test[(4, 8)] = 3.14 + 0.00159j self.assertEqual(3.14 + 0.00159j, test[(4, 8)]) self.assertEqual(3.14 + 0.00159j, test.max_element()) self.assertTrue(test.conserve_spin()) test1 = Wavefunction(param=[[2, 0, 4]]) test2 = Wavefunction(param=[[2, 0, 4]]) test1.set_wfn(strategy='ones') test2.set_wfn(strategy='ones') work = test1 + test2 ref = 2.0 * numpy.ones((4, 4), dtype=numpy.complex128) self.assertTrue(numpy.allclose(ref, work._civec[(2, 0)].coeff)) work = test1 - test2 ref = numpy.zeros((4, 4), dtype=numpy.complex128) self.assertTrue(numpy.allclose(ref, work._civec[(2, 0)].coeff))
def test_set_wfn_random_with_multiple_sectors_is_normalized(self): wfn = Wavefunction([[2, 0, 4], [2, -2, 4]], broken=None) wfn.set_wfn(strategy="random") self.assertAlmostEqual(wfn.norm(), 1.0)