def setUp(self): self.x_dimension = 2 self.y_dimension = 3 # Create a Hamiltonian with nearest-neighbor hopping terms self.ferm_op = fermi_hubbard(self.x_dimension, self.y_dimension, 1., 0., 0., 0., False, True) # Get the ground energy and ground state self.ferm_op_sparse = get_sparse_operator(self.ferm_op) self.ferm_op_ground_energy, self.ferm_op_ground_state = ( get_ground_state(self.ferm_op_sparse)) # Transform the FermionOperator to a QubitOperator self.transformed_op = verstraete_cirac_2d_square( self.ferm_op, self.x_dimension, self.y_dimension, add_auxiliary_hamiltonian=True, snake=False) # Get the ground energy and state of the transformed operator self.transformed_sparse = get_sparse_operator(self.transformed_op) self.transformed_ground_energy, self.transformed_ground_state = ( get_ground_state(self.transformed_sparse))
def test_hf_state_energy_close_to_ground_energy_at_high_density(self): grid_length = 8 dimension = 1 spinless = True n_particles = grid_length**dimension // 2 # High density -> small length_scale. length_scale = 0.25 grid = Grid(dimension, grid_length, length_scale) hamiltonian = jellium_model(grid, spinless) hamiltonian_sparse = get_sparse_operator(hamiltonian) hf_state = hartree_fock_state_jellium(grid, n_particles, spinless, plane_wave=True) restricted_hamiltonian = jw_number_restrict_operator( hamiltonian_sparse, n_particles) E_g = get_ground_state(restricted_hamiltonian)[0] E_HF_plane_wave = expectation(hamiltonian_sparse, hf_state) self.assertAlmostEqual(E_g, E_HF_plane_wave, places=5)
def test_apply_constraints(self): # Get norm of original operator. original_norm = 0. for term, coefficient in self.fermion_hamiltonian.terms.items(): if term != (): original_norm += abs(coefficient) # Get modified operator. modified_operator = apply_constraints(self.fermion_hamiltonian, self.n_fermions) modified_operator.compress() # Get norm of modified operator. modified_norm = 0. for term, coefficient in modified_operator.terms.items(): if term != (): modified_norm += abs(coefficient) self.assertTrue(modified_norm < original_norm) # Map both to sparse matrix under Jordan-Wigner. sparse_original = get_sparse_operator(self.fermion_hamiltonian) sparse_modified = get_sparse_operator(modified_operator) # Check spectra. sparse_original = jw_number_restrict_operator(sparse_original, self.n_fermions) sparse_modified = jw_number_restrict_operator(sparse_modified, self.n_fermions) original_spectrum = sparse_eigenspectrum(sparse_original) modified_spectrum = sparse_eigenspectrum(sparse_modified) spectral_deviation = numpy.amax( numpy.absolute(original_spectrum - modified_spectrum)) self.assertAlmostEqual(spectral_deviation, 0.) # Check expectation value. energy, wavefunction = get_ground_state(sparse_original) modified_energy = expectation(sparse_modified, wavefunction) self.assertAlmostEqual(modified_energy, energy)
def test_constraint_matrix(self): # Randomly project operator with constraints. numpy.random.seed(8) constraints = constraint_matrix(self.n_orbitals, self.n_fermions) n_constraints, n_terms = constraints.shape self.assertEqual(1 + self.n_orbitals**2 + self.n_orbitals**4, n_terms) random_weights = numpy.random.randn(n_constraints) vectorized_operator = operator_to_vector(self.fermion_hamiltonian) modification_vector = constraints.transpose() * random_weights new_operator_vector = vectorized_operator + modification_vector modified_operator = vector_to_operator(new_operator_vector, self.n_orbitals) # Map both to sparse matrix under Jordan-Wigner. sparse_original = get_sparse_operator(self.fermion_hamiltonian) sparse_modified = get_sparse_operator(modified_operator) # Check expectation value. energy, wavefunction = get_ground_state(sparse_original) modified_energy = expectation(sparse_modified, wavefunction) self.assertAlmostEqual(modified_energy, energy)
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))