def test_plane_wave_period_cutoff(self): # TODO: After figuring out the correct formula for period cutoff for # dual basis, change period_cutoff to default, and change # h_1 to also accept period_cutoff for real integration test. geometry = [('H', (0, )), ('H', (0.8, ))] grid = Grid(dimensions=1, scale=1.1, length=5) period_cutoff = 50.0 h_1 = plane_wave_hamiltonian(grid, geometry, True, True, False, None) jw_1 = jordan_wigner(h_1) spectrum_1 = eigenspectrum(jw_1) h_2 = plane_wave_hamiltonian(grid, geometry, True, True, False, None, True, period_cutoff) jw_2 = jordan_wigner(h_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.) # TODO: This is only for code coverage. Remove after having real # integration test. h_3 = plane_wave_hamiltonian(grid, geometry, True, True, False, None, True)
def test_plane_wave_hamiltonian_integration(self): length_set = [3, 4] spinless_set = [True, False] geometry = [('H', (0, )), ('H', (0.8, ))] length_scale = 1.1 for l in length_set: for spinless in spinless_set: grid = Grid(dimensions=1, scale=length_scale, length=l) h_plane_wave = plane_wave_hamiltonian(grid, geometry, spinless, True, include_constant=True) h_dual_basis = plane_wave_hamiltonian(grid, geometry, spinless, False) jw_h_plane_wave = jordan_wigner(h_plane_wave) jw_h_dual_basis = jordan_wigner(h_dual_basis) h_plane_wave_spectrum = eigenspectrum(jw_h_plane_wave) h_dual_basis_spectrum = eigenspectrum(jw_h_dual_basis) max_diff = numpy.amax(h_plane_wave_spectrum - h_dual_basis_spectrum) min_diff = numpy.amin(h_plane_wave_spectrum - h_dual_basis_spectrum) self.assertAlmostEqual(max_diff, 2.8372 / length_scale) self.assertAlmostEqual(min_diff, 2.8372 / length_scale)
def test_model_integration_with_constant(self): # Compute Hamiltonian in both momentum and position space. length_scale = 0.7 for length in [2, 3]: grid = Grid(dimensions=2, length=length, scale=length_scale) spinless = True # Include Madelung constant in the momentum but not the position # Hamiltonian. momentum_hamiltonian = jellium_model(grid, spinless, True, include_constant=True) position_hamiltonian = jellium_model(grid, spinless, False) # Confirm they are Hermitian momentum_hamiltonian_operator = ( get_sparse_operator(momentum_hamiltonian)) self.assertTrue(is_hermitian(momentum_hamiltonian_operator)) position_hamiltonian_operator = ( get_sparse_operator(position_hamiltonian)) self.assertTrue(is_hermitian(position_hamiltonian_operator)) # Diagonalize and confirm the same energy. jw_momentum = jordan_wigner(momentum_hamiltonian) jw_position = jordan_wigner(position_hamiltonian) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm momentum spectrum is shifted 2.8372/length_scale higher. max_difference = numpy.amax(momentum_spectrum - position_spectrum) min_difference = numpy.amax(momentum_spectrum - position_spectrum) self.assertAlmostEqual(max_difference, 2.8372 / length_scale) self.assertAlmostEqual(min_difference, 2.8372 / length_scale)
def test_plane_wave_hamiltonian_integration(self): length_set = [2, 3, 4] spinless_set = [True, False] length_scale = 1.1 for geometry in [[('H', (0, )), ('H', (0.8, ))], [('H', (0.1, ))], [('H', (0.1, ))]]: for l in length_set: for spinless in spinless_set: grid = Grid(dimensions=1, scale=length_scale, length=l) h_plane_wave = plane_wave_hamiltonian( grid, geometry, spinless, True, include_constant=False) h_dual_basis = plane_wave_hamiltonian( grid, geometry, spinless, False, include_constant=False) # Test for Hermiticity plane_wave_operator = get_sparse_operator(h_plane_wave) dual_operator = get_sparse_operator(h_dual_basis) self.assertTrue(is_hermitian((plane_wave_operator))) self.assertTrue(is_hermitian(dual_operator)) jw_h_plane_wave = jordan_wigner(h_plane_wave) jw_h_dual_basis = jordan_wigner(h_dual_basis) h_plane_wave_spectrum = eigenspectrum(jw_h_plane_wave) h_dual_basis_spectrum = eigenspectrum(jw_h_dual_basis) max_diff = numpy.amax(h_plane_wave_spectrum - h_dual_basis_spectrum) min_diff = numpy.amin(h_plane_wave_spectrum - h_dual_basis_spectrum) self.assertAlmostEqual(max_diff, 0) self.assertAlmostEqual(min_diff, 0)
def test_plane_wave_energy_cutoff(self): spinless = True # [[spatial dimension, fieldline dimension]] dims = [[2, 2], [2, 3], [3, 3]] e_cutoff = 20.0 for dim in dims: # If dim[0] == 2, get range(2, 4). # If dim[0] == 3, get range(2, 3). for length in range(2, 6 - dim[0]): grid = Grid(dimensions=dim[0], length=length, scale=1.0) hamiltonian_1 = jellium_model(grid, spinless, True, False, fieldlines=dim[1]) jw_1 = jordan_wigner(hamiltonian_1) spectrum_1 = eigenspectrum(jw_1) hamiltonian_2 = jellium_model(grid, spinless, True, False, e_cutoff, fieldlines=dim[1]) jw_2 = jordan_wigner(hamiltonian_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.)
def test_model_integration(self): # Compute Hamiltonian in both momentum and position space. for length in [2, 3]: grid = Grid(dimensions=2, length=length, scale=1.0) spinless = True momentum_hamiltonian = jellium_model(grid, spinless, True) position_hamiltonian = jellium_model(grid, spinless, False) # Confirm they are Hermitian momentum_hamiltonian_operator = ( get_sparse_operator(momentum_hamiltonian)) self.assertTrue(is_hermitian(momentum_hamiltonian_operator)) position_hamiltonian_operator = ( get_sparse_operator(position_hamiltonian)) self.assertTrue(is_hermitian(position_hamiltonian_operator)) # Diagonalize and confirm the same energy. jw_momentum = jordan_wigner(momentum_hamiltonian) jw_position = jordan_wigner(position_hamiltonian) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm spectra are the same. difference = numpy.amax( numpy.absolute(momentum_spectrum - position_spectrum)) self.assertAlmostEqual(difference, 0.)
def test_potential_integration(self): # Compute potential energy operator in momentum and position space. for length in [2, 3]: grid = Grid(dimensions=2, length=length, scale=2.) spinless = True momentum_potential = plane_wave_potential(grid, spinless) position_potential = dual_basis_potential(grid, spinless) # Confirm they are Hermitian momentum_potential_operator = ( get_sparse_operator(momentum_potential)) self.assertTrue(is_hermitian(momentum_potential_operator)) position_potential_operator = ( get_sparse_operator(position_potential)) self.assertTrue(is_hermitian(position_potential_operator)) # Diagonalize and confirm the same energy. jw_momentum = jordan_wigner(momentum_potential) jw_position = jordan_wigner(position_potential) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm spectra are the same. difference = numpy.amax( numpy.absolute(momentum_spectrum - position_spectrum)) self.assertAlmostEqual(difference, 0.)
def test_plane_wave_energy_cutoff(self): ''' Key: Spatial dimension. Value: List of geometries. ''' geometry_sets = { 2: [[('H', (0., 0.)), ('H', (0.8, 0.))], [('H', (0.1, 0.))]], 3: [[('H', (0., 0., 0.)), ('H', (0.8, 0., 0.))], [('H', (0.1, 0., 0.))]] } # [[spatial dimension, fieldline dimension]] dims = [[2, 2], [2, 3], [3, 3]] spinless_set = [True, False] e_cutoff = 20.0 for dim in dims: for geometry in geometry_sets[dim[0]]: for spinless in spinless_set: grid = Grid(dimensions=dim[0], scale=1.1, length=2) h_1 = plane_wave_hamiltonian(grid, geometry, True, True, False, fieldlines=dim[1]) jw_1 = jordan_wigner(h_1) spectrum_1 = eigenspectrum(jw_1) h_2 = plane_wave_hamiltonian(grid, geometry, True, True, False, e_cutoff, fieldlines=dim[1]) jw_2 = jordan_wigner(h_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.)
def test_bk_jw_majoranas(self): # Check if the Majorana operators have the same spectrum # irrespectively of the transform. n_qubits = 7 a = FermionOperator(((1, 0),)) a_dag = FermionOperator(((1, 1),)) c = a + a_dag d = 1j * (a_dag - a) c_spins = [jordan_wigner(c), bravyi_kitaev_tree(c)] d_spins = [jordan_wigner(d), bravyi_kitaev_tree(d)] c_sparse = [get_sparse_operator(c_spins[0]), get_sparse_operator(c_spins[1])] d_sparse = [get_sparse_operator(d_spins[0]), get_sparse_operator(d_spins[1])] c_spectrum = [eigenspectrum(c_spins[0]), eigenspectrum(c_spins[1])] d_spectrum = [eigenspectrum(d_spins[0]), eigenspectrum(d_spins[1])] self.assertAlmostEqual(0., numpy.amax(numpy.absolute(d_spectrum[0] - d_spectrum[1])))
def test_plane_wave_period_cutoff(self): # TODO: After figuring out the correct formula for period cutoff for # dual basis, change period_cutoff to default, and change # hamiltonian_1 to a real jellium_model for real integration test. grid = Grid(dimensions=2, length=2, scale=1.0) spinless = True period_cutoff = 0. hamiltonian_1 = FermionOperator() jw_1 = jordan_wigner(hamiltonian_1) spectrum_1 = eigenspectrum(jw_1) hamiltonian_2 = jellium_model(grid, spinless, True, False, None, True, period_cutoff) jw_2 = jordan_wigner(hamiltonian_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.) # TODO: This is only for code coverage. Remove after having real # integration test. jellium_model(grid, spinless, True, False, None, True) jellium_model(grid, spinless, False, False, None, True)
def test_tapering_qubits_manual_input(self): """ Test taper_off_qubits function using LiH Hamiltonian. Checks different qubits inputs to remove manually. Test the lowest eigenvalue against the full Hamiltonian, and the full spectrum between them. """ hamiltonian, spectrum = lih_hamiltonian() qubit_hamiltonian = jordan_wigner(hamiltonian) stab1 = QubitOperator('Z0 Z2', -1.0) stab2 = QubitOperator('Z1 Z3', -1.0) tapered_ham_0_3 = taper_off_qubits(qubit_hamiltonian, [stab1, stab2], manual_input=True, fixed_positions=[0, 3]) tapered_ham_2_1 = taper_off_qubits(qubit_hamiltonian, [stab1, stab2], manual_input=True, fixed_positions=[2, 1]) tapered_spectrum_0_3 = eigenspectrum(tapered_ham_0_3) tapered_spectrum_2_1 = eigenspectrum(tapered_ham_2_1) self.assertAlmostEqual(spectrum[0], tapered_spectrum_0_3[0]) self.assertAlmostEqual(spectrum[0], tapered_spectrum_2_1[0]) self.assertTrue( numpy.allclose(tapered_spectrum_0_3, tapered_spectrum_2_1))
def test_bravyi_kitaev(self): hamiltonian, gs_energy = lih_hamiltonian() code = bravyi_kitaev_code(4) qubit_hamiltonian = binary_code_transform(hamiltonian, code) self.assertAlmostEqual(gs_energy, eigenspectrum(qubit_hamiltonian)[0]) qubit_spectrum = eigenspectrum(qubit_hamiltonian) fenwick_spectrum = eigenspectrum(bravyi_kitaev(hamiltonian)) for eigen_idx, eigenvalue in enumerate(qubit_spectrum): self.assertAlmostEqual(eigenvalue, fenwick_spectrum[eigen_idx])
def test_one_body_square_decomposition(self): # Initialize H2 InteractionOperator. n_qubits = 4 n_orbitals = 2 filename = os.path.join(THIS_DIRECTORY, 'data', 'H2_sto-3g_singlet_0.7414') molecule = MolecularData(filename=filename) molecule_interaction = molecule.get_molecular_hamiltonian() fermion_operator = get_fermion_operator(molecule_interaction) two_body_coefficients = molecule_interaction.two_body_tensor # Decompose. eigenvalues, one_body_squares, one_body_correction, error = ( low_rank_two_body_decomposition(two_body_coefficients)) rank = eigenvalues.size for l in range(rank): one_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (q, 0)) coefficient = one_body_squares[l, p, q] one_body_operator += FermionOperator(term, coefficient) one_body_squared = one_body_operator**2 # Get the squared one-body operator via one-body decomposition. if abs(eigenvalues[l]) < 1e-6: with self.assertRaises(ValueError): prepare_one_body_squared_evolution(one_body_squares[l]) continue else: density_density_matrix, basis_transformation_matrix = ( prepare_one_body_squared_evolution(one_body_squares[l])) two_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (p, 0), (q, 1), (q, 0)) coefficient = density_density_matrix[p, q] two_body_operator += FermionOperator(term, coefficient) # Confirm that the rotations diagonalize the one-body squares. hopefully_diagonal = basis_transformation_matrix.dot( numpy.dot( one_body_squares[l], numpy.transpose( numpy.conjugate(basis_transformation_matrix)))) diagonal = numpy.diag(hopefully_diagonal) difference = hopefully_diagonal - numpy.diag(diagonal) self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) density_density_alternative = numpy.outer(diagonal, diagonal) difference = density_density_alternative - density_density_matrix self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) # Test spectra. one_body_squared_spectrum = eigenspectrum(one_body_squared) two_body_spectrum = eigenspectrum(two_body_operator) difference = two_body_spectrum - one_body_squared_spectrum self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
def test_eigenspectrum(self): fermion_eigenspectrum = eigenspectrum(self.fermion_operator) qubit_eigenspectrum = eigenspectrum(self.qubit_operator) interaction_eigenspectrum = eigenspectrum(self.interaction_operator) for i in range(2**self.n_qubits): self.assertAlmostEqual(fermion_eigenspectrum[i], qubit_eigenspectrum[i]) self.assertAlmostEqual(fermion_eigenspectrum[i], interaction_eigenspectrum[i])
def test_nonperiodic_external_potential_integration(self): # Compute potential energy operator in momentum and position space. # Non-periodic test. ''' Key: Spatial dimension. Value: List of geometries. ''' geometry_sets = { 2: [[('H', (0., 0.)), ('H', (0.8, 0.))], [('H', (0.1, 0.))]], 3: [[('H', (0., 0., 0.)), ('H', (0.8, 0., 0.))], [('H', (0.1, 0., 0.))]] } # [[spatial dimension, fieldline dimension]] dims = [[2, 2], [2, 3], [3, 3]] scale = 8 * 1. spinless = True for dim in dims: # If dim[0] == 2, get range(2, 4). # If dim[0] == 3, get range(2, 3). for length in range(2, 6 - dim[0]): for geometry in geometry_sets[dim[0]]: grid = Grid(dimensions=dim[0], scale=scale, length=length) period_cutoff = grid.volume_scale() ** (1. / grid.dimensions) momentum_external_potential = plane_wave_external_potential(grid, geometry, spinless, e_cutoff=None, non_periodic=True, period_cutoff=period_cutoff, fieldlines=dim[1]) position_external_potential = dual_basis_external_potential(grid, geometry, spinless, non_periodic=True, period_cutoff=period_cutoff, fieldlines=dim[1]) # Confirm they are Hermitian momentum_external_potential_operator = ( get_sparse_operator(momentum_external_potential)) self.assertTrue(is_hermitian(momentum_external_potential_operator)) position_external_potential_operator = ( get_sparse_operator(position_external_potential)) self.assertTrue(is_hermitian(position_external_potential_operator)) # Diagonalize. jw_momentum = jordan_wigner(momentum_external_potential) jw_position = jordan_wigner(position_external_potential) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm spectra are the same. difference = numpy.amax( numpy.absolute(momentum_spectrum - position_spectrum)) self.assertAlmostEqual(difference, 0.)
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))
def test_energy_reduce_symmetry_qubits(self): # Generate the fermionic Hamiltonians, # number of orbitals and number of electrons. lih_sto_hamil, lih_sto_numorb, lih_sto_numel = LiH_sto3g() # Use test function to reduce the qubits. lih_sto_qbt = (symmetry_conserving_bravyi_kitaev( lih_sto_hamil, lih_sto_numorb, lih_sto_numel)) self.assertAlmostEqual( eigenspectrum(lih_sto_qbt)[0], eigenspectrum(lih_sto_hamil)[0])
def test_one_body_square_decomposition(self): # Initialize a random two-body FermionOperator. n_qubits = 4 random_operator = get_fermion_operator( random_interaction_operator(n_qubits, seed=17004)) # Convert to chemist tensor. constant, one_body_coefficients, chemist_tensor = ( get_chemist_two_body_coefficients(random_operator)) # Perform decomposition. eigenvalues, one_body_squares, trunc_error = ( low_rank_two_body_decomposition(chemist_tensor)) # Build back two-body component. for l in range(n_qubits**2): # Get the squared one-body operator. one_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (q, 0)) coefficient = one_body_squares[l, p, q] one_body_operator += FermionOperator(term, coefficient) one_body_squared = one_body_operator**2 # Get the squared one-body operator via one-body decomposition. density_density_matrix, basis_transformation_matrix = ( prepare_one_body_squared_evolution(one_body_squares[l])) two_body_operator = FermionOperator() for p, q in itertools.product(range(n_qubits), repeat=2): term = ((p, 1), (p, 0), (q, 1), (q, 0)) coefficient = density_density_matrix[p, q] two_body_operator += FermionOperator(term, coefficient) # Confirm that the rotations diagonalize the one-body squares. hopefully_diagonal = basis_transformation_matrix.dot( numpy.dot( one_body_squares[l], numpy.transpose( numpy.conjugate(basis_transformation_matrix)))) diagonal = numpy.diag(hopefully_diagonal) difference = hopefully_diagonal - numpy.diag(diagonal) self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) density_density_alternative = numpy.outer(diagonal, diagonal) difference = density_density_alternative - density_density_matrix self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference))) # Test spectra. one_body_squared_spectrum = eigenspectrum(one_body_squared) two_body_spectrum = eigenspectrum(two_body_operator) difference = two_body_spectrum - one_body_squared_spectrum self.assertAlmostEqual(0., numpy.amax(numpy.absolute(difference)))
def test_bk_jw_number_operator(self): # Check if number operator has the same spectrum in both # BK and JW representations n = number_operator(1, 0) jw_n = jordan_wigner(n) bk_n = bravyi_kitaev(n) # Diagonalize and make sure the spectra are the same. jw_spectrum = eigenspectrum(jw_n) bk_spectrum = eigenspectrum(bk_n) self.assertAlmostEqual(0., numpy.amax( numpy.absolute(jw_spectrum - bk_spectrum)))
def test_bk_jw_hopping_operator(self): # Check if the spectrum fits for a single hoppping operator ho = FermionOperator(((1, 1), (4, 0))) + FermionOperator( ((4, 1), (1, 0))) jw_ho = jordan_wigner(ho) bk_ho = bravyi_kitaev(ho) # Diagonalize and make sure the spectra are the same. jw_spectrum = eigenspectrum(jw_ho) bk_spectrum = eigenspectrum(bk_ho) self.assertAlmostEqual(0., numpy.amax( numpy.absolute(jw_spectrum - bk_spectrum)))
def test_model_integration_with_constant(self): # Compute Hamiltonian in both momentum and position space. length_scale = 0.7 spinless = True # [[spatial dimension, fieldline dimension]] dims = [[2, 2], [2, 3], [3, 3]] for dim in dims: # If dim[0] == 2, get range(2, 4). # If dim[0] == 3, get range(2, 3). for length in range(2, 6 - dim[0]): grid = Grid(dimensions=dim[0], length=length, scale=length_scale) # Include Madelung constant in the momentum but not the position # Hamiltonian. momentum_hamiltonian = jellium_model(grid, spinless, True, include_constant=True, fieldlines=dim[1]) position_hamiltonian = jellium_model(grid, spinless, False, fieldlines=dim[1]) # Confirm they are Hermitian. momentum_hamiltonian_operator = ( get_sparse_operator(momentum_hamiltonian)) self.assertTrue(is_hermitian(momentum_hamiltonian_operator)) position_hamiltonian_operator = ( get_sparse_operator(position_hamiltonian)) self.assertTrue(is_hermitian(position_hamiltonian_operator)) # Diagonalize and confirm the same energy. jw_momentum = jordan_wigner(momentum_hamiltonian) jw_position = jordan_wigner(position_hamiltonian) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm momentum spectrum is shifted 2.8372/length_scale higher. max_difference = numpy.amax(momentum_spectrum - position_spectrum) min_difference = numpy.amax(momentum_spectrum - position_spectrum) self.assertAlmostEqual(max_difference, 2.8372 / length_scale) self.assertAlmostEqual(min_difference, 2.8372 / length_scale)
def test_nonperiodic_potential_integration(self): # Compute potential energy operator in momentum and position space. # Non-periodic test. spinless = True # [[spatial dimension, fieldline dimension]] dims = [[2, 2], [2, 3], [3, 3]] for dim in dims: # If dim[0] == 2, get range(2, 4). # If dim[0] == 3, get range(2, 3). for length in range(2, 6 - dim[0]): grid = Grid(dimensions=dim[0], length=length, scale=1.) period_cutoff = grid.volume_scale()**(1. / grid.dimensions) / 2. momentum_potential = plane_wave_potential( grid, spinless=spinless, e_cutoff=None, non_periodic=True, period_cutoff=period_cutoff, fieldlines=dim[1]) position_potential = dual_basis_potential( grid, spinless=spinless, non_periodic=True, period_cutoff=period_cutoff, fieldlines=dim[1]) # Confirm they are Hermitian momentum_potential_operator = ( get_sparse_operator(momentum_potential)) self.assertTrue(is_hermitian(momentum_potential_operator)) position_potential_operator = ( get_sparse_operator(position_potential)) self.assertTrue(is_hermitian(position_potential_operator)) # Diagonalize and confirm the same energy. jw_momentum = jordan_wigner(momentum_potential) jw_position = jordan_wigner(position_potential) momentum_spectrum = eigenspectrum(jw_momentum) position_spectrum = eigenspectrum(jw_position) # Confirm spectra are the same. difference = numpy.amax( numpy.absolute(momentum_spectrum - position_spectrum)) self.assertAlmostEqual(difference, 0.)
def test_bk_jw_number_operator_scaled(self): # Check if number operator has the same spectrum in both # JW and BK representations n_qubits = 1 n = number_operator(n_qubits, 0, coefficient=2) # eigenspectrum (0,2) jw_n = jordan_wigner(n) bk_n = bravyi_kitaev(n) # Diagonalize and make sure the spectra are the same. jw_spectrum = eigenspectrum(jw_n) bk_spectrum = eigenspectrum(bk_n) self.assertAlmostEqual(0., numpy.amax( numpy.absolute(jw_spectrum - bk_spectrum)))
def test_bk_jw_integration(self): # This is a legacy test, which was a minimal failing example when # optimization for hermitian operators was used. # Minimal failing example: fo = FermionOperator(((3, 1),)) jw = jordan_wigner(fo) bk = bravyi_kitaev(fo) jw_spectrum = eigenspectrum(jw) bk_spectrum = eigenspectrum(bk) self.assertAlmostEqual(0., numpy.amax(numpy.absolute(jw_spectrum - bk_spectrum)))
def test_plane_wave_energy_cutoff(self): grid = Grid(dimensions=1, length=5, scale=1.0) spinless = True e_cutoff = 20.0 hamiltonian_1 = jellium_model(grid, spinless, True, False) jw_1 = jordan_wigner(hamiltonian_1) spectrum_1 = eigenspectrum(jw_1) hamiltonian_2 = jellium_model(grid, spinless, True, False, e_cutoff) jw_2 = jordan_wigner(hamiltonian_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.)
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
def test_weight_one_binary_addressing_code(self): hamiltonian, gs_energy = lih_hamiltonian() code = interleaved_code(8) * ( 2 * weight_one_binary_addressing_code(2)) qubit_hamiltonian = binary_code_transform(hamiltonian, code) self.assertAlmostEqual(gs_energy, eigenspectrum(qubit_hamiltonian)[0])
def test_jordan_wigner(self): hamiltonian, gs_energy = lih_hamiltonian() code = jordan_wigner_code(4) qubit_hamiltonian = binary_code_transform(hamiltonian, code) self.assertAlmostEqual(gs_energy, eigenspectrum(qubit_hamiltonian)[0]) self.assertDictEqual(qubit_hamiltonian.terms, jordan_wigner(hamiltonian).terms)
def test_plane_wave_energy_cutoff(self): geometry = [('H', (0, )), ('H', (0.8, ))] grid = Grid(dimensions=1, scale=1.1, length=5) e_cutoff = 50.0 h_1 = plane_wave_hamiltonian(grid, geometry, True, True, False) jw_1 = jordan_wigner(h_1) spectrum_1 = eigenspectrum(jw_1) h_2 = plane_wave_hamiltonian(grid, geometry, True, True, False, e_cutoff) jw_2 = jordan_wigner(h_2) spectrum_2 = eigenspectrum(jw_2) max_diff = numpy.amax(numpy.absolute(spectrum_1 - spectrum_2)) self.assertGreater(max_diff, 0.)
def test_bk_jw_number_operators(self): # Check if a number operator has the same spectrum in both # JW and BK representations n_qubits = 2 n1 = number_operator(n_qubits, 0) n2 = number_operator(n_qubits, 1) n = n1 + n2 jw_n = jordan_wigner(n) bk_n = bravyi_kitaev(n) # Diagonalize and make sure the spectra are the same. jw_spectrum = eigenspectrum(jw_n) bk_spectrum = eigenspectrum(bk_n) self.assertAlmostEqual(0., numpy.amax( numpy.absolute(jw_spectrum - bk_spectrum)))