Exemplo n.º 1
0
    def test_consistency(self):
        """Test consistency with JW for FermionOperators."""
        # Random interaction operator
        n_qubits = 5
        iop = random_interaction_operator(n_qubits, real=False)
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)

        # Interaction operator from molecule
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1

        filename = os.path.join(DATA_DIRECTORY, 'H1-Li1_sto-3g_singlet_1.45')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()

        iop = molecule.get_molecular_hamiltonian()
        op1 = jordan_wigner(iop)
        op2 = jordan_wigner(get_fermion_operator(iop))

        self.assertEqual(op1, op2)
def lih_hamiltonian():
    """
    Generate test Hamiltonian from LiH.

    Args:
        None

    Return:

        hamiltonian: FermionicOperator

        spectrum: List of energies.
    """
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    active_space_start = 1
    active_space_stop = 3
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()

    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(active_space_start),
        active_indices=range(active_space_start, active_space_stop))

    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    spectrum = eigenspectrum(hamiltonian)

    return hamiltonian, spectrum
Exemplo n.º 3
0
def lih_hamiltonian():
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    active_space_start = 1
    active_space_stop = 3
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()
    molecular_hamiltonian = molecule.get_molecular_hamiltonian(
        occupied_indices=range(active_space_start),
        active_indices=range(active_space_start, active_space_stop))
    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    ground_state_energy = eigenspectrum(hamiltonian)[0]
    return hamiltonian, ground_state_energy
Exemplo n.º 4
0
def LiH_sto3g():
    """ Generates the Hamiltonian for LiH in
        the STO-3G basis, at a distance of
        1.45 A.
    """
    geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
    molecule = MolecularData(geometry, 'sto-3g', 1, description="1.45")
    molecule.load()
    molecular_hamiltonian = molecule.get_molecular_hamiltonian()
    hamiltonian = get_fermion_operator(molecular_hamiltonian)
    num_electrons = molecule.n_electrons
    num_orbitals = 2 * molecule.n_orbitals

    return hamiltonian, num_orbitals, num_electrons
def test_d2_to_g2():
    # this should test for correctness
    filename = os.path.join(DATA_DIRECTORY, "H1-Li1_sto-3g_singlet_1.45.hdf5")
    molecule = MolecularData(filename=filename)
    molecule.load()
    opdm = molecule.fci_one_rdm
    tpdm = molecule.fci_two_rdm
    phdm = map_two_pdm_to_particle_hole_dm(tpdm, opdm)

    db = tpdm_to_phdm_mapping(molecule.n_qubits)
    topdm = Tensor(tensor=opdm, name='ck')
    ttpdm = Tensor(tensor=np.einsum('ijlk', tpdm), name='cckk')
    tphdm = Tensor(tensor=np.einsum('ijlk', phdm), name='ckck')
    mt = MultiTensor(tensors=[topdm, ttpdm, tphdm], dual_basis=db)
    A, _, b = mt.synthesize_dual_basis()
    vec_rdms = mt.vectorize_tensors()
    assert np.isclose(np.linalg.norm(A.dot(vec_rdms) - b), 0)
    def setUp(self):

        # Set up molecule.
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()
        self.n_fermions = molecule.n_electrons
        self.n_orbitals = molecule.n_qubits

        # Get molecular Hamiltonian.
        molecular_hamiltonian = molecule.get_molecular_hamiltonian()
        self.fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
Exemplo n.º 7
0
    def setUp(self):

        # Setup.
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        molecule = MolecularData(geometry,
                                 basis,
                                 multiplicity,
                                 filename=filename)
        molecule.load()
        self.n_fermions = molecule.n_electrons
        self.n_orbitals = molecule.n_qubits

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = molecule.get_molecular_hamiltonian()
        self.fci_rdm = molecule.get_molecular_rdm(use_fci=1)
Exemplo n.º 8
0
class LiHIntegrationTest(unittest.TestCase):
    def setUp(self):
        # Set up molecule.
        geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., 1.45))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H1-Li1_sto-3g_singlet_1.45')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()
        self.molecular_hamiltonian_no_core = (
            self.molecule.get_molecular_hamiltonian(
                occupied_indices=[0],
                active_indices=range(1, self.molecule.n_orbitals)))

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get matrix form.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
        self.hamiltonian_matrix_no_core = get_sparse_operator(
            self.molecular_hamiltonian_no_core)

    def test_all(self):

        # Test reverse Jordan-Wigner.
        fermion_hamiltonian = reverse_jordan_wigner(self.qubit_hamiltonian)
        fermion_hamiltonian = normal_ordered(fermion_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

        # Test mapping to interaction operator.
        fermion_hamiltonian = get_fermion_operator(self.molecular_hamiltonian)
        fermion_hamiltonian = normal_ordered(fermion_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

        # Test RDM energy.
        fci_rdm_energy = self.nuclear_repulsion
        fci_rdm_energy += numpy.sum(self.fci_rdm.one_body_tensor *
                                    self.one_body)
        fci_rdm_energy += numpy.sum(self.fci_rdm.two_body_tensor *
                                    self.two_body)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

        # Confirm expectation on qubit Hamiltonian using reverse JW matches.
        qubit_rdm = self.fci_rdm.get_qubit_expectations(self.qubit_hamiltonian)
        qubit_energy = 0.0
        for term, coefficient in qubit_rdm.terms.items():
            qubit_energy += coefficient * self.qubit_hamiltonian.terms[term]
        self.assertAlmostEqual(qubit_energy, self.molecule.fci_energy)

        # Confirm fermionic RDMs can be built from measured qubit RDMs.
        new_fermi_rdm = get_interaction_rdm(qubit_rdm)
        new_fermi_rdm.expectation(self.molecular_hamiltonian)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

        # Test sparse matrices.
        energy, wavefunction = get_ground_state(self.hamiltonian_matrix)
        self.assertAlmostEqual(energy, self.molecule.fci_energy)
        expected_energy = expectation(self.hamiltonian_matrix, wavefunction)
        self.assertAlmostEqual(expected_energy, energy)

        # Make sure you can reproduce Hartree-Fock energy.
        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        hf_density = get_density_matrix([hf_state], [1.])
        expected_hf_density_energy = expectation(self.hamiltonian_matrix,
                                                 hf_density)
        expected_hf_energy = expectation(self.hamiltonian_matrix, hf_state)
        self.assertAlmostEqual(expected_hf_energy, self.molecule.hf_energy)
        self.assertAlmostEqual(expected_hf_density_energy,
                               self.molecule.hf_energy)

        # Check that frozen core result matches frozen core FCI from psi4.
        # Recore frozen core result from external calculation.
        self.frozen_core_fci_energy = -7.8807607374168
        no_core_fci_energy = numpy.linalg.eigh(
            self.hamiltonian_matrix_no_core.toarray())[0][0]
        self.assertAlmostEqual(no_core_fci_energy, self.frozen_core_fci_energy)

        # Check that the freeze_orbitals function has the same effect as the
        # as the occupied_indices option of get_molecular_hamiltonian.
        frozen_hamiltonian = freeze_orbitals(
            get_fermion_operator(self.molecular_hamiltonian), [0, 1])
        self.assertTrue(frozen_hamiltonian == get_fermion_operator(
            self.molecular_hamiltonian_no_core))
Exemplo n.º 9
0
class bravyi_kitaev_fastTransformTest(unittest.TestCase):
    def setUp(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)
        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get the sparse matrix.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)

    def test_bad_input(self):
        with self.assertRaises(TypeError):
            bksf.bravyi_kitaev_fast(FermionOperator())

    def test_bravyi_kitaev_fast_edgeoperator_Bi(self):
        # checking the edge operators
        edge_matrix = numpy.triu(numpy.ones((4, 4)))
        edge_matrix_indices = numpy.array(
            numpy.nonzero(
                numpy.triu(edge_matrix) - numpy.diag(numpy.diag(edge_matrix))))

        correct_operators_b0 = ((0, 'Z'), (1, 'Z'), (2, 'Z'))
        correct_operators_b1 = ((0, 'Z'), (3, 'Z'), (4, 'Z'))
        correct_operators_b2 = ((1, 'Z'), (3, 'Z'), (5, 'Z'))
        correct_operators_b3 = ((2, 'Z'), (4, 'Z'), (5, 'Z'))

        qterm_b0 = QubitOperator(correct_operators_b0, 1)
        qterm_b1 = QubitOperator(correct_operators_b1, 1)
        qterm_b2 = QubitOperator(correct_operators_b2, 1)
        qterm_b3 = QubitOperator(correct_operators_b3, 1)
        self.assertTrue(
            qterm_b0 == bksf.edge_operator_b(edge_matrix_indices, 0))
        self.assertTrue(
            qterm_b1 == bksf.edge_operator_b(edge_matrix_indices, 1))
        self.assertTrue(
            qterm_b2 == bksf.edge_operator_b(edge_matrix_indices, 2))
        self.assertTrue(
            qterm_b3 == bksf.edge_operator_b(edge_matrix_indices, 3))

    def test_bravyi_kitaev_fast_edgeoperator_Aij(self):
        # checking the edge operators
        edge_matrix = numpy.triu(numpy.ones((4, 4)))
        edge_matrix_indices = numpy.array(
            numpy.nonzero(
                numpy.triu(edge_matrix) - numpy.diag(numpy.diag(edge_matrix))))
        correct_operators_a01 = ((0, 'X'), )
        correct_operators_a02 = ((0, 'Z'), (1, 'X'))
        correct_operators_a03 = ((0, 'Z'), (1, 'Z'), (2, 'X'))
        correct_operators_a12 = ((0, 'Z'), (1, 'Z'), (3, 'X'))
        correct_operators_a13 = ((0, 'Z'), (2, 'Z'), (3, 'Z'), (4, 'X'))
        correct_operators_a23 = ((1, 'Z'), (2, 'Z'), (3, 'Z'), (4, 'Z'), (5,
                                                                          'X'))

        qterm_a01 = QubitOperator(correct_operators_a01, 1)
        qterm_a02 = QubitOperator(correct_operators_a02, 1)
        qterm_a03 = QubitOperator(correct_operators_a03, 1)
        qterm_a12 = QubitOperator(correct_operators_a12, 1)
        qterm_a13 = QubitOperator(correct_operators_a13, 1)
        qterm_a23 = QubitOperator(correct_operators_a23, 1)

        self.assertTrue(
            qterm_a01 == bksf.edge_operator_aij(edge_matrix_indices, 0, 1))
        self.assertTrue(
            qterm_a02 == bksf.edge_operator_aij(edge_matrix_indices, 0, 2))
        self.assertTrue(
            qterm_a03 == bksf.edge_operator_aij(edge_matrix_indices, 0, 3))
        self.assertTrue(
            qterm_a12 == bksf.edge_operator_aij(edge_matrix_indices, 1, 2))
        self.assertTrue(
            qterm_a13 == bksf.edge_operator_aij(edge_matrix_indices, 1, 3))
        self.assertTrue(
            qterm_a23 == bksf.edge_operator_aij(edge_matrix_indices, 2, 3))

    def test_bravyi_kitaev_fast_jw_number_operator(self):
        # bksf algorithm allows for even number of particles. So, compare the
        # spectrum of number operator from jordan-wigner and bksf algorithm
        # to make sure half of the jordan-wigner number operator spectrum
        # can be found in bksf number operator spectrum.
        bravyi_kitaev_fast_n = bksf.number_operator(self.molecular_hamiltonian)
        jw_n = QubitOperator()
        n_qubits = count_qubits(self.molecular_hamiltonian)
        for i in range(n_qubits):
            jw_n += jordan_wigner_one_body(i, i)
        jw_eig_spec = eigenspectrum(jw_n)
        bravyi_kitaev_fast_eig_spec = eigenspectrum(bravyi_kitaev_fast_n)
        evensector = 0
        for i in range(numpy.size(jw_eig_spec)):
            if bool(
                    numpy.size(
                        numpy.where(
                            jw_eig_spec[i] == bravyi_kitaev_fast_eig_spec))):
                evensector += 1
        self.assertEqual(evensector, 2**(n_qubits - 1))

    def test_bravyi_kitaev_fast_jw_hamiltonian(self):
        # make sure half of the jordan-wigner Hamiltonian eigenspectrum can
        # be found in bksf Hamiltonian eigenspectrum.
        n_qubits = count_qubits(self.molecular_hamiltonian)
        bravyi_kitaev_fast_H = bksf.bravyi_kitaev_fast(
            self.molecular_hamiltonian)
        jw_H = jordan_wigner(self.molecular_hamiltonian)
        bravyi_kitaev_fast_H_eig = eigenspectrum(bravyi_kitaev_fast_H)
        jw_H_eig = eigenspectrum(jw_H)
        bravyi_kitaev_fast_H_eig = bravyi_kitaev_fast_H_eig.round(5)
        jw_H_eig = jw_H_eig.round(5)
        evensector = 0
        for i in range(numpy.size(jw_H_eig)):
            if bool(
                    numpy.size(
                        numpy.where(jw_H_eig[i] == bravyi_kitaev_fast_H_eig))):
                evensector += 1
        self.assertEqual(evensector, 2**(n_qubits - 1))

    def test_bravyi_kitaev_fast_generate_fermions(self):
        n_qubits = count_qubits(self.molecular_hamiltonian)
        # test for generating two fermions
        edge_matrix = bksf.bravyi_kitaev_fast_edge_matrix(
            self.molecular_hamiltonian)
        edge_matrix_indices = numpy.array(
            numpy.nonzero(
                numpy.triu(edge_matrix) - numpy.diag(numpy.diag(edge_matrix))))
        fermion_generation_operator = bksf.generate_fermions(
            edge_matrix_indices, 2, 3)
        fermion_generation_sp_matrix = get_sparse_operator(
            fermion_generation_operator)
        fermion_generation_matrix = fermion_generation_sp_matrix.toarray()
        bksf_vacuum_state_operator = bksf.vacuum_operator(edge_matrix_indices)
        bksf_vacuum_state_sp_matrix = get_sparse_operator(
            bksf_vacuum_state_operator)
        bksf_vacuum_state_matrix = bksf_vacuum_state_sp_matrix.toarray()
        vacuum_state = numpy.zeros((2**(n_qubits), 1))
        vacuum_state[0] = 1.
        bksf_vacuum_state = numpy.dot(bksf_vacuum_state_matrix, vacuum_state)
        two_fermion_state = numpy.dot(fermion_generation_matrix,
                                      bksf_vacuum_state)
        # using total number operator to check the number of fermions generated
        tot_number_operator = bksf.number_operator(self.molecular_hamiltonian)
        number_operator_sp_matrix = get_sparse_operator(tot_number_operator)
        number_operator_matrix = number_operator_sp_matrix.toarray()
        tot_fermions = numpy.dot(
            two_fermion_state.conjugate().T,
            numpy.dot(number_operator_matrix, two_fermion_state))
        # checking the occupation number of site 2 and 3
        number_operator_2 = bksf.number_operator(self.molecular_hamiltonian, 2)
        number_operator_3 = bksf.number_operator(self.molecular_hamiltonian, 3)
        number_operator_23 = number_operator_2 + number_operator_3
        number_operator_23_sp_matrix = get_sparse_operator(number_operator_23)
        number_operator_23_matrix = number_operator_23_sp_matrix.toarray()
        tot_23_fermions = numpy.dot(
            two_fermion_state.conjugate().T,
            numpy.dot(number_operator_23_matrix, two_fermion_state))
        self.assertTrue(2.0 - float(tot_fermions.real) < 1e-13)
        self.assertTrue(2.0 - float(tot_23_fermions.real) < 1e-13)

    def test_bravyi_kitaev_fast_excitation_terms(self):
        # Testing on-site and excitation terms in Hamiltonian
        constant = 0
        one_body = numpy.array([[1, 2, 0, 3], [2, 1, 2, 0], [0, 2, 1, 2.5],
                                [3, 0, 2.5, 1]])
        # No Coloumb interaction
        two_body = numpy.zeros((4, 4, 4, 4))
        molecular_hamiltonian = InteractionOperator(constant, one_body,
                                                    two_body)
        n_qubits = count_qubits(molecular_hamiltonian)
        # comparing the eigenspectrum of Hamiltonian
        bravyi_kitaev_fast_H = bksf.bravyi_kitaev_fast(molecular_hamiltonian)
        jw_H = jordan_wigner(molecular_hamiltonian)
        bravyi_kitaev_fast_H_eig = eigenspectrum(bravyi_kitaev_fast_H)
        jw_H_eig = eigenspectrum(jw_H)
        bravyi_kitaev_fast_H_eig = bravyi_kitaev_fast_H_eig.round(5)
        jw_H_eig = jw_H_eig.round(5)
        evensector_H = 0
        for i in range(numpy.size(jw_H_eig)):
            if bool(
                    numpy.size(
                        numpy.where(jw_H_eig[i] == bravyi_kitaev_fast_H_eig))):
                evensector_H += 1

        # comparing eigenspectrum of number operator
        bravyi_kitaev_fast_n = bksf.number_operator(molecular_hamiltonian)
        jw_n = QubitOperator()
        n_qubits = count_qubits(molecular_hamiltonian)
        for i in range(n_qubits):
            jw_n += jordan_wigner_one_body(i, i)
        jw_eig_spec = eigenspectrum(jw_n)
        bravyi_kitaev_fast_eig_spec = eigenspectrum(bravyi_kitaev_fast_n)
        evensector_n = 0
        for i in range(numpy.size(jw_eig_spec)):
            if bool(
                    numpy.size(
                        numpy.where(
                            jw_eig_spec[i] == bravyi_kitaev_fast_eig_spec))):
                evensector_n += 1
        self.assertEqual(evensector_H, 2**(n_qubits - 1))
        self.assertEqual(evensector_n, 2**(n_qubits - 1))

    def test_bravyi_kitaev_fast_number_excitation_operator(self):
        # using hydrogen Hamiltonian and introducing some number operator terms
        constant = 0
        one_body = numpy.zeros((4, 4))
        one_body[(0, 0)] = .4
        one_body[(1, 1)] = .5
        one_body[(2, 2)] = .6
        one_body[(3, 3)] = .7
        two_body = self.molecular_hamiltonian.two_body_tensor
        # initiating number operator terms for all the possible cases
        two_body[(1, 2, 3, 1)] = 0.1
        two_body[(1, 3, 2, 1)] = 0.1
        two_body[(1, 2, 1, 3)] = 0.15
        two_body[(3, 1, 2, 1)] = 0.15
        two_body[(0, 2, 2, 1)] = 0.09
        two_body[(1, 2, 2, 0)] = 0.09
        two_body[(1, 2, 3, 2)] = 0.11
        two_body[(2, 3, 2, 1)] = 0.11
        two_body[(2, 2, 2, 2)] = 0.1
        molecular_hamiltonian = InteractionOperator(constant, one_body,
                                                    two_body)
        # comparing the eigenspectrum of Hamiltonian
        n_qubits = count_qubits(molecular_hamiltonian)
        bravyi_kitaev_fast_H = bksf.bravyi_kitaev_fast(molecular_hamiltonian)
        jw_H = jordan_wigner(molecular_hamiltonian)
        bravyi_kitaev_fast_H_eig = eigenspectrum(bravyi_kitaev_fast_H)
        jw_H_eig = eigenspectrum(jw_H)
        bravyi_kitaev_fast_H_eig = bravyi_kitaev_fast_H_eig.round(5)
        jw_H_eig = jw_H_eig.round(5)
        evensector_H = 0
        for i in range(numpy.size(jw_H_eig)):
            if bool(
                    numpy.size(
                        numpy.where(jw_H_eig[i] == bravyi_kitaev_fast_H_eig))):
                evensector_H += 1

        # comparing eigenspectrum of number operator
        bravyi_kitaev_fast_n = bksf.number_operator(molecular_hamiltonian)
        jw_n = QubitOperator()
        n_qubits = count_qubits(molecular_hamiltonian)
        for i in range(n_qubits):
            jw_n += jordan_wigner_one_body(i, i)
        jw_eig_spec = eigenspectrum(jw_n)
        bravyi_kitaev_fast_eig_spec = eigenspectrum(bravyi_kitaev_fast_n)
        evensector_n = 0
        for i in range(numpy.size(jw_eig_spec)):
            if bool(
                    numpy.size(
                        numpy.where(
                            jw_eig_spec[i] == bravyi_kitaev_fast_eig_spec))):
                evensector_n += 1
        self.assertEqual(evensector_H, 2**(n_qubits - 1))
        self.assertEqual(evensector_n, 2**(n_qubits - 1))
class HydrogenIntegrationTest(unittest.TestCase):
    def setUp(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get the sparse matrix.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)

    def test_integral_data(self):

        # Initialize coefficients given in arXiv 1208.5986:
        g0 = 0.71375
        g1 = -1.2525
        g2 = -0.47593
        g3 = 0.67449 / 2.
        g4 = 0.69740 / 2.
        g5 = 0.66347 / 2.
        g6 = 0.18129 / 2.

        # Check the integrals in the test data.
        self.assertAlmostEqual(self.nuclear_repulsion, g0, places=4)

        self.assertAlmostEqual(self.one_body[0, 0], g1, places=4)
        self.assertAlmostEqual(self.one_body[1, 1], g1, places=4)

        self.assertAlmostEqual(self.one_body[2, 2], g2, places=4)
        self.assertAlmostEqual(self.one_body[3, 3], g2, places=4)

        self.assertAlmostEqual(self.two_body[0, 1, 1, 0], g3, places=4)
        self.assertAlmostEqual(self.two_body[1, 0, 0, 1], g3, places=4)

        self.assertAlmostEqual(self.two_body[2, 3, 3, 2], g4, places=4)
        self.assertAlmostEqual(self.two_body[3, 2, 2, 3], g4, places=4)

        self.assertAlmostEqual(self.two_body[0, 2, 2, 0], g5, places=4)
        self.assertAlmostEqual(self.two_body[0, 3, 3, 0], g5, places=4)
        self.assertAlmostEqual(self.two_body[1, 2, 2, 1], g5, places=4)
        self.assertAlmostEqual(self.two_body[1, 3, 3, 1], g5, places=4)
        self.assertAlmostEqual(self.two_body[2, 0, 0, 2], g5, places=4)
        self.assertAlmostEqual(self.two_body[3, 0, 0, 3], g5, places=4)
        self.assertAlmostEqual(self.two_body[2, 1, 1, 2], g5, places=4)
        self.assertAlmostEqual(self.two_body[3, 1, 1, 3], g5, places=4)

        self.assertAlmostEqual(self.two_body[0, 2, 0, 2], g6, places=4)
        self.assertAlmostEqual(self.two_body[1, 3, 1, 3], g6, places=4)
        self.assertAlmostEqual(self.two_body[2, 1, 3, 0], g6, places=4)
        self.assertAlmostEqual(self.two_body[2, 3, 1, 0], g6, places=4)
        self.assertAlmostEqual(self.two_body[0, 3, 1, 2], g6, places=4)
        self.assertAlmostEqual(self.two_body[0, 1, 3, 2], g6, places=4)

    def test_qubit_operator(self):

        # Below are qubit term coefficients, also from arXiv 1208.5986:
        f1 = 0.1712
        f2 = -0.2228
        f3 = 0.1686
        f4 = 0.1205
        f5 = 0.1659
        f6 = 0.1743
        f7 = 0.04532

        # Test the local Hamiltonian terms.
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Z'), )],
                               f1,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((1, 'Z'), )],
                               f1,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((2, 'Z'), )],
                               f2,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((3, 'Z'), )],
                               f2,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Z'), (1,
                                                                        'Z'))],
                               f3,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Z'), (2,
                                                                        'Z'))],
                               f4,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((1, 'Z'), (3,
                                                                        'Z'))],
                               f4,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((1, 'Z'), (2,
                                                                        'Z'))],
                               f5,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Z'), (3,
                                                                        'Z'))],
                               f5,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((2, 'Z'), (3,
                                                                        'Z'))],
                               f6,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Y'), (1,
                                                                        'Y'),
                                                             (2, 'X'), (3,
                                                                        'X'))],
                               -f7,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'X'), (1,
                                                                        'X'),
                                                             (2, 'Y'), (3,
                                                                        'Y'))],
                               -f7,
                               places=4)

        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'X'), (1,
                                                                        'Y'),
                                                             (2, 'Y'), (3,
                                                                        'X'))],
                               f7,
                               places=4)
        self.assertAlmostEqual(self.qubit_hamiltonian.terms[((0, 'Y'), (1,
                                                                        'X'),
                                                             (2, 'X'), (3,
                                                                        'Y'))],
                               f7,
                               places=4)

    def test_reverse_jordan_wigner(self):
        fermion_hamiltonian = reverse_jordan_wigner(self.qubit_hamiltonian)
        fermion_hamiltonian = normal_ordered(fermion_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

    def test_interaction_operator_mapping(self):

        # Make sure mapping of FermionOperator to InteractionOperator works.
        molecular_hamiltonian = get_interaction_operator(
            self.fermion_hamiltonian)
        fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
        self.assertTrue(self.fermion_hamiltonian == fermion_hamiltonian)

        # Make sure mapping of InteractionOperator to QubitOperator works.
        qubit_hamiltonian = jordan_wigner(self.molecular_hamiltonian)
        self.assertTrue(self.qubit_hamiltonian == qubit_hamiltonian)

    def test_rdm_numerically(self):

        # Test energy of RDM.
        fci_rdm_energy = self.nuclear_repulsion
        fci_rdm_energy += numpy.sum(self.fci_rdm.one_body_tensor *
                                    self.molecular_hamiltonian.one_body_tensor)
        fci_rdm_energy += numpy.sum(self.fci_rdm.two_body_tensor *
                                    self.molecular_hamiltonian.two_body_tensor)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

        # Confirm expectation on qubit Hamiltonian using reverse JW matches.
        qubit_rdm = self.fci_rdm.get_qubit_expectations(self.qubit_hamiltonian)
        qubit_energy = 0.0
        for term, expectation in qubit_rdm.terms.items():
            qubit_energy += expectation * self.qubit_hamiltonian.terms[term]
        self.assertAlmostEqual(qubit_energy, self.molecule.fci_energy)

        # Confirm fermionic RDMs can be built from measured qubit RDMs
        new_fermi_rdm = get_interaction_rdm(qubit_rdm)
        new_fermi_rdm.expectation(self.molecular_hamiltonian)
        self.assertAlmostEqual(fci_rdm_energy, self.molecule.fci_energy)

    def test_sparse_numerically(self):

        # Check FCI energy.
        energy, wavefunction = get_ground_state(self.hamiltonian_matrix)
        self.assertAlmostEqual(energy, self.molecule.fci_energy)
        expected_energy = expectation(self.hamiltonian_matrix, wavefunction)
        self.assertAlmostEqual(expected_energy, energy)

        # Make sure you can reproduce Hartree energy.
        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        hf_density = get_density_matrix([hf_state], [1.])

        # Make sure you can reproduce Hartree-Fock energy.
        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        hf_density = get_density_matrix([hf_state], [1.])
        expected_hf_density_energy = expectation(self.hamiltonian_matrix,
                                                 hf_density)
        expected_hf_energy = expectation(self.hamiltonian_matrix, hf_state)
        self.assertAlmostEqual(expected_hf_energy, self.molecule.hf_energy)
        self.assertAlmostEqual(expected_hf_density_energy,
                               self.molecule.hf_energy)
Exemplo n.º 11
0
class UnitaryCC(unittest.TestCase):
    def test_uccsd_anti_hermitian(self):
        """Test operators are anti-Hermitian independent of inputs"""
        test_orbitals = 4

        single_amplitudes = randn(*(test_orbitals, ) * 2)
        double_amplitudes = randn(*(test_orbitals, ) * 4)

        generator = uccsd_generator(single_amplitudes, double_amplitudes)
        conj_generator = hermitian_conjugated(generator)

        self.assertEqual(generator, -1. * conj_generator)

    def test_uccsd_singlet_anti_hermitian(self):
        """Test that the singlet version is anti-Hermitian"""
        test_orbitals = 8
        test_electrons = 4

        packed_amplitude_size = uccsd_singlet_paramsize(
            test_orbitals, test_electrons)

        packed_amplitudes = randn(int(packed_amplitude_size))

        generator = uccsd_singlet_generator(packed_amplitudes, test_orbitals,
                                            test_electrons)

        conj_generator = hermitian_conjugated(generator)

        self.assertEqual(generator, -1. * conj_generator)

    def test_uccsd_singlet_symmetries(self):
        """Test that the singlet generator has the correct symmetries."""
        test_orbitals = 8
        test_electrons = 4

        packed_amplitude_size = uccsd_singlet_paramsize(
            test_orbitals, test_electrons)
        packed_amplitudes = randn(int(packed_amplitude_size))
        generator = uccsd_singlet_generator(packed_amplitudes, test_orbitals,
                                            test_electrons)

        # Construct symmetry operators
        sz = sz_operator(test_orbitals)
        s_squared = s_squared_operator(test_orbitals)

        # Check the symmetries
        comm_sz = normal_ordered(commutator(generator, sz))
        comm_s_squared = normal_ordered(commutator(generator, s_squared))
        zero = FermionOperator()

        self.assertEqual(comm_sz, zero)
        self.assertEqual(comm_s_squared, zero)

    def test_uccsd_singlet_builds(self):
        """Test specific builds of the UCCSD singlet operator"""
        # Build 1
        n_orbitals = 4
        n_electrons = 2
        n_params = uccsd_singlet_paramsize(n_orbitals, n_electrons)
        self.assertEqual(n_params, 2)

        initial_amplitudes = [1., 2.]

        generator = uccsd_singlet_generator(initial_amplitudes, n_orbitals,
                                            n_electrons)

        test_generator = (FermionOperator("2^ 0", 1.) +
                          FermionOperator("0^ 2", -1.) +
                          FermionOperator("3^ 1", 1.) +
                          FermionOperator("1^ 3", -1.) +
                          FermionOperator("2^ 0 3^ 1", 4.) +
                          FermionOperator("1^ 3 0^ 2", -4.))

        self.assertEqual(normal_ordered(test_generator),
                         normal_ordered(generator))

        # Build 2
        n_orbitals = 6
        n_electrons = 2

        n_params = uccsd_singlet_paramsize(n_orbitals, n_electrons)
        self.assertEqual(n_params, 5)

        initial_amplitudes = numpy.arange(1, n_params + 1, dtype=float)
        generator = uccsd_singlet_generator(initial_amplitudes, n_orbitals,
                                            n_electrons)

        test_generator = (
            FermionOperator("2^ 0", 1.) + FermionOperator("0^ 2", -1) +
            FermionOperator("3^ 1", 1.) + FermionOperator("1^ 3", -1.) +
            FermionOperator("4^ 0", 2.) + FermionOperator("0^ 4", -2) +
            FermionOperator("5^ 1", 2.) + FermionOperator("1^ 5", -2.) +
            FermionOperator("2^ 0 3^ 1", 6.) +
            FermionOperator("1^ 3 0^ 2", -6.) +
            FermionOperator("4^ 0 5^ 1", 8.) +
            FermionOperator("1^ 5 0^ 4", -8.) +
            FermionOperator("2^ 0 5^ 1", 5.) +
            FermionOperator("1^ 5 0^ 2", -5.) +
            FermionOperator("4^ 0 3^ 1", 5.) +
            FermionOperator("1^ 3 0^ 4", -5.) +
            FermionOperator("2^ 0 4^ 0", 5.) +
            FermionOperator("0^ 4 0^ 2", -5.) +
            FermionOperator("3^ 1 5^ 1", 5.) +
            FermionOperator("1^ 5 1^ 3", -5.))

        self.assertEqual(normal_ordered(test_generator),
                         normal_ordered(generator))

    def test_sparse_uccsd_generator_numpy_inputs(self):
        """Test numpy ndarray inputs to uccsd_generator that are sparse"""
        test_orbitals = 30
        sparse_single_amplitudes = numpy.zeros((test_orbitals, test_orbitals))
        sparse_double_amplitudes = numpy.zeros(
            (test_orbitals, test_orbitals, test_orbitals, test_orbitals))

        sparse_single_amplitudes[3, 5] = 0.12345
        sparse_single_amplitudes[12, 4] = 0.44313

        sparse_double_amplitudes[0, 12, 6, 2] = 0.3434
        sparse_double_amplitudes[1, 4, 6, 13] = -0.23423

        generator = uccsd_generator(sparse_single_amplitudes,
                                    sparse_double_amplitudes)

        test_generator = (0.12345 * FermionOperator("3^ 5") +
                          (-0.12345) * FermionOperator("5^ 3") +
                          0.44313 * FermionOperator("12^ 4") +
                          (-0.44313) * FermionOperator("4^ 12") +
                          0.3434 * FermionOperator("0^ 12 6^ 2") +
                          (-0.3434) * FermionOperator("2^ 6 12^ 0") +
                          (-0.23423) * FermionOperator("1^ 4 6^ 13") +
                          0.23423 * FermionOperator("13^ 6 4^ 1"))
        self.assertEqual(test_generator, generator)

    def test_sparse_uccsd_generator_list_inputs(self):
        """Test list inputs to uccsd_generator that are sparse"""
        sparse_single_amplitudes = [[[3, 5], 0.12345], [[12, 4], 0.44313]]
        sparse_double_amplitudes = [[[0, 12, 6, 2], 0.3434],
                                    [[1, 4, 6, 13], -0.23423]]

        generator = uccsd_generator(sparse_single_amplitudes,
                                    sparse_double_amplitudes)

        test_generator = (0.12345 * FermionOperator("3^ 5") +
                          (-0.12345) * FermionOperator("5^ 3") +
                          0.44313 * FermionOperator("12^ 4") +
                          (-0.44313) * FermionOperator("4^ 12") +
                          0.3434 * FermionOperator("0^ 12 6^ 2") +
                          (-0.3434) * FermionOperator("2^ 6 12^ 0") +
                          (-0.23423) * FermionOperator("1^ 4 6^ 13") +
                          0.23423 * FermionOperator("13^ 6 4^ 1"))
        self.assertEqual(test_generator, generator)

    def test_uccsd_singlet_get_packed_amplitudes(self):
        test_orbitals = 6
        test_electrons = 2
        sparse_single_amplitudes = numpy.zeros((test_orbitals, test_orbitals))
        sparse_double_amplitudes = numpy.zeros(
            (test_orbitals, test_orbitals, test_orbitals, test_orbitals))

        sparse_single_amplitudes[2, 0] = 0.12345
        sparse_single_amplitudes[3, 1] = 0.12345

        sparse_double_amplitudes[2, 0, 3, 1] = 0.9

        sparse_double_amplitudes[2, 0, 4, 0] = 0.3434
        sparse_double_amplitudes[5, 1, 3, 1] = 0.3434

        packed_amplitudes = uccsd_singlet_get_packed_amplitudes(
            sparse_single_amplitudes, sparse_double_amplitudes, test_orbitals,
            test_electrons)

        self.assertEqual(len(packed_amplitudes), 5)

        self.assertTrue(
            numpy.allclose(packed_amplitudes,
                           numpy.array([0.12345, 0., 0.9, 0., 0.3434])))

    def test_ucc_h2(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get the sparse matrix.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
        # Test UCCSD for accuracy against FCI using loaded t amplitudes.
        ucc_operator = uccsd_generator(self.molecule.ccsd_single_amps,
                                       self.molecule.ccsd_double_amps)

        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        uccsd_sparse = jordan_wigner_sparse(ucc_operator)
        uccsd_state = scipy.sparse.linalg.expm_multiply(uccsd_sparse, hf_state)
        expected_uccsd_energy = expectation(self.hamiltonian_matrix,
                                            uccsd_state)
        self.assertAlmostEqual(expected_uccsd_energy,
                               self.molecule.fci_energy,
                               places=4)
        print("UCCSD ENERGY: {}".format(expected_uccsd_energy))

        # Test CCSD for precise match against FCI using loaded t amplitudes.
        ccsd_operator = uccsd_generator(self.molecule.ccsd_single_amps,
                                        self.molecule.ccsd_double_amps,
                                        anti_hermitian=False)

        ccsd_sparse_r = jordan_wigner_sparse(ccsd_operator)
        ccsd_sparse_l = jordan_wigner_sparse(
            -hermitian_conjugated(ccsd_operator))

        ccsd_state_r = scipy.sparse.linalg.expm_multiply(
            ccsd_sparse_r, hf_state)
        ccsd_state_l = scipy.sparse.linalg.expm_multiply(
            ccsd_sparse_l, hf_state)
        expected_ccsd_energy = ccsd_state_l.conjugate().dot(
            self.hamiltonian_matrix.dot(ccsd_state_r))
        self.assertAlmostEqual(expected_ccsd_energy, self.molecule.fci_energy)

    def test_ucc_h2_singlet(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(THIS_DIRECTORY, 'data',
                                'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()

        # Get molecular Hamiltonian.
        self.molecular_hamiltonian = self.molecule.get_molecular_hamiltonian()

        # Get FCI RDM.
        self.fci_rdm = self.molecule.get_molecular_rdm(use_fci=1)

        # Get explicit coefficients.
        self.nuclear_repulsion = self.molecular_hamiltonian.constant
        self.one_body = self.molecular_hamiltonian.one_body_tensor
        self.two_body = self.molecular_hamiltonian.two_body_tensor

        # Get fermion Hamiltonian.
        self.fermion_hamiltonian = normal_ordered(
            get_fermion_operator(self.molecular_hamiltonian))

        # Get qubit Hamiltonian.
        self.qubit_hamiltonian = jordan_wigner(self.fermion_hamiltonian)

        # Get the sparse matrix.
        self.hamiltonian_matrix = get_sparse_operator(
            self.molecular_hamiltonian)
        # Test UCCSD for accuracy against FCI using loaded t amplitudes.
        ucc_operator = uccsd_generator(self.molecule.ccsd_single_amps,
                                       self.molecule.ccsd_double_amps)

        hf_state = jw_hartree_fock_state(self.molecule.n_electrons,
                                         count_qubits(self.qubit_hamiltonian))
        uccsd_sparse = jordan_wigner_sparse(ucc_operator)
        uccsd_state = scipy.sparse.linalg.expm_multiply(uccsd_sparse, hf_state)
        expected_uccsd_energy = expectation(self.hamiltonian_matrix,
                                            uccsd_state)
        self.assertAlmostEqual(expected_uccsd_energy,
                               self.molecule.fci_energy,
                               places=4)
        print("UCCSD ENERGY: {}".format(expected_uccsd_energy))

        # Test CCSD singlet for precise match against FCI using loaded t
        # amplitudes
        packed_amplitudes = uccsd_singlet_get_packed_amplitudes(
            self.molecule.ccsd_single_amps, self.molecule.ccsd_double_amps,
            self.molecule.n_qubits, self.molecule.n_electrons)
        ccsd_operator = uccsd_singlet_generator(packed_amplitudes,
                                                self.molecule.n_qubits,
                                                self.molecule.n_electrons,
                                                anti_hermitian=False)

        ccsd_sparse_r = jordan_wigner_sparse(ccsd_operator)
        ccsd_sparse_l = jordan_wigner_sparse(
            -hermitian_conjugated(ccsd_operator))

        ccsd_state_r = scipy.sparse.linalg.expm_multiply(
            ccsd_sparse_r, hf_state)
        ccsd_state_l = scipy.sparse.linalg.expm_multiply(
            ccsd_sparse_l, hf_state)
        expected_ccsd_energy = ccsd_state_l.conjugate().dot(
            self.hamiltonian_matrix.dot(ccsd_state_r))
        self.assertAlmostEqual(expected_ccsd_energy, self.molecule.fci_energy)

    def test_value_error_for_odd_n_qubits(self):
        # Pass odd n_qubits to singlet generators
        with self.assertRaises(ValueError):
            _ = uccsd_singlet_paramsize(3, 4)

    def test_value_error_bad_amplitudes(self):
        with self.assertRaises(ValueError):
            _ = uccsd_singlet_generator([1.], 3, 4)
Exemplo n.º 12
0
class InteractionRDMTest(unittest.TestCase):

    def setUp(self):
        geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 0.7414))]
        basis = 'sto-3g'
        multiplicity = 1
        filename = os.path.join(DATA_DIRECTORY, 'H2_sto-3g_singlet_0.7414')
        self.molecule = MolecularData(geometry,
                                      basis,
                                      multiplicity,
                                      filename=filename)
        self.molecule.load()
        self.cisd_energy = self.molecule.cisd_energy
        self.rdm = self.molecule.get_molecular_rdm()
        self.hamiltonian = self.molecule.get_molecular_hamiltonian()

    def test_get_qubit_expectations(self):
        qubit_operator = jordan_wigner(self.hamiltonian)
        qubit_expectations = self.rdm.get_qubit_expectations(qubit_operator)

        test_energy = 0.0
        for qubit_term in qubit_expectations.terms:
            term_coefficient = qubit_operator.terms[qubit_term]
            test_energy += (term_coefficient *
                            qubit_expectations.terms[qubit_term])
        self.assertLess(abs(test_energy - self.cisd_energy), EQ_TOLERANCE)

    def test_get_qubit_expectations_nonmolecular_term(self):
        with self.assertRaises(InteractionRDMError):
            self.rdm.get_qubit_expectations(QubitOperator('X1 X2 X3 X4 Y6'))

    def test_get_qubit_expectations_through_expectation_method(self):
        qubit_operator = jordan_wigner(self.hamiltonian)
        test_energy = self.rdm.expectation(qubit_operator)

        self.assertLess(abs(test_energy - self.cisd_energy), EQ_TOLERANCE)

    def test_get_molecular_operator_expectation(self):
        expectation = self.rdm.expectation(self.hamiltonian)
        self.assertAlmostEqual(expectation, self.cisd_energy, places=7)

    def test_expectation_bad_type(self):
        with self.assertRaises(InteractionRDMError):
            self.rdm.expectation(12)

    def test_addition(self):
        rdm2 = self.rdm + self.rdm
        self.assertTrue(
            numpy.array_equal(rdm2.one_body_tensor,
                              rdm2.n_body_tensors[(1, 0)]))
        self.assertTrue(
            numpy.array_equal(rdm2.two_body_tensor,
                              rdm2.n_body_tensors[(1, 1, 0, 0)]))

    def test_rdm_setters(self):
        temp_rdm = self.molecule.get_molecular_rdm()
        one_body_tensor_test = numpy.eye(4)
        temp_rdm.one_body_tensor = one_body_tensor_test
        self.assertTrue(
            numpy.array_equal(temp_rdm.n_body_tensors[(1, 0)],
                              one_body_tensor_test))
        two_body_tensor_test = numpy.zeros([4, 4, 4, 4])
        temp_rdm.two_body_tensor = two_body_tensor_test
        self.assertTrue(
            numpy.array_equal(temp_rdm.n_body_tensors[(1, 1, 0, 0)],
                              two_body_tensor_test))