Exemple #1
0
    def setUp(self):
        self.n_qubits = 5
        self.constant = 1.7
        self.chemical_potential = 2.

        # Obtain random Hermitian and antisymmetric matrices
        self.hermitian_mat = random_hermitian_matrix(self.n_qubits)
        self.antisymmetric_mat = random_antisymmetric_matrix(self.n_qubits)

        self.combined_hermitian = (
            self.hermitian_mat -
            self.chemical_potential * numpy.eye(self.n_qubits))

        # Initialize a particle-number-conserving Hamiltonian
        self.quad_ham_pc = QuadraticHamiltonian(
            self.constant, self.hermitian_mat)

        # Initialize a non-particle-number-conserving Hamiltonian
        self.quad_ham_npc = QuadraticHamiltonian(
            self.constant, self.hermitian_mat, self.antisymmetric_mat,
            self.chemical_potential)

        # Initialize the sparse operators and get their ground energies
        self.quad_ham_pc_sparse = get_sparse_operator(self.quad_ham_pc)
        self.quad_ham_npc_sparse = get_sparse_operator(self.quad_ham_npc)

        self.pc_ground_energy, self.pc_ground_state = get_ground_state(
            self.quad_ham_pc_sparse)
        self.npc_ground_energy, self.npc_ground_state = get_ground_state(
            self.quad_ham_npc_sparse)
Exemple #2
0
    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_ground_state_particle_nonconserving(self):
        """Test getting the ground state preparation circuit for a Hamiltonian
        that does not conserve particle number."""
        for n_qubits in self.n_qubits_range:
            # Initialize a particle-number-conserving Hamiltonian
            quadratic_hamiltonian = random_quadratic_hamiltonian(
                n_qubits, False, True)

            # Compute the true ground state
            sparse_operator = get_sparse_operator(quadratic_hamiltonian)
            ground_energy, _ = get_ground_state(sparse_operator)

            # Obtain the circuit
            circuit_description, start_orbitals = (
                gaussian_state_preparation_circuit(quadratic_hamiltonian))

            # Initialize the starting state
            state = jw_configuration_state(start_orbitals, n_qubits)

            # Apply the circuit
            particle_hole_transformation = (
                jw_sparse_particle_hole_transformation_last_mode(n_qubits))
            for parallel_ops in circuit_description:
                for op in parallel_ops:
                    if op == 'pht':
                        state = particle_hole_transformation.dot(state)
                    else:
                        i, j, theta, phi = op
                        state = jw_sparse_givens_rotation(
                            i, j, theta, phi, n_qubits).dot(state)

            # Check that the state obtained using the circuit is a ground state
            difference = sparse_operator * state - ground_energy * state
            discrepancy = numpy.amax(numpy.abs(difference))
            self.assertAlmostEqual(discrepancy, 0)
    def test_orbital_energies(self):
        """Test getting the orbital energies."""
        # Test the particle-number-conserving case
        orbital_energies, constant = self.quad_ham_pc.orbital_energies()
        # Test the ground energy
        energy = numpy.sum(
                orbital_energies[orbital_energies < -EQ_TOLERANCE]) + constant
        quad_ham_pc_sparse = get_sparse_operator(self.quad_ham_pc)
        ground_energy, ground_state = get_ground_state(quad_ham_pc_sparse)
        self.assertAlmostEqual(energy, ground_energy)

        # Test the non-particle-number-conserving case
        orbital_energies, constant = self.quad_ham_npc.orbital_energies()
        # Test the ground energy
        energy = constant
        quad_ham_npc_sparse = get_sparse_operator(self.quad_ham_npc)
        ground_energy, ground_state = get_ground_state(quad_ham_npc_sparse)
        self.assertAlmostEqual(energy, ground_energy)
    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)

        # Test consistency with cvxopt.
        scipy_operator = apply_constraints(self.fermion_hamiltonian,
                                           self.n_fermions,
                                           use_scipy=False)

        # Get norm.
        scipy_norm = 0.
        for term, coefficient in scipy_operator.terms.items():
            if term != ():
                scipy_norm += abs(coefficient)
        self.assertAlmostEqual(scipy_norm, modified_norm)
    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)
Exemple #7
0
def energy_levels(separation):
    g = [('H', (0., 0., 0.)), ('H', (0., 0., separation))]
    d = str(separation)
    m = MolecularData(g,
                      basis,
                      multiplicity,
                      description=d,
                      data_directory=data_directory)
    run_psi4(m, run_fci=True, delete_output=True)
    _, s = get_ground_state(
        get_sparse_operator(
            normal_ordered(
                get_fermion_operator(
                    m.get_molecular_hamiltonian(
                        active_indices=range(active_spatial_orbitals))))))
    h = normal_ordered(
        get_fermion_operator(
            m.get_molecular_hamiltonian(
                active_indices=range(active_spatial_orbitals +
                                     virtual_spatial_orbitals))))
    o = vqse_operators(s)
    return generalized_eigenvalues(h_matrix(h, o, s), s_matrix(o, s))
Exemple #8
0
# Get the Hamiltonian in an active space.
molecular_hamiltonian = molecule.get_molecular_hamiltonian(
    occupied_indices=range(active_space_start),
    active_indices=range(active_space_start, active_space_stop))

# Map operator to fermions and qubits.
fermion_hamiltonian = get_fermion_operator(molecular_hamiltonian)
qubit_hamiltonian = jordan_wigner(fermion_hamiltonian)
qubit_hamiltonian.compress()
print('The Jordan-Wigner Hamiltonian in canonical basis follows:\n{}'.format(
    qubit_hamiltonian))

# Get sparse operator and ground state energy.
sparse_hamiltonian = get_sparse_operator(qubit_hamiltonian)
energy, state = get_ground_state(sparse_hamiltonian)
print('Ground state energy before rotation is {} Hartree.\n'.format(energy))

# Randomly rotate.
n_orbitals = molecular_hamiltonian.n_qubits // 2
n_variables = int(n_orbitals * (n_orbitals - 1) / 2)
random_angles = numpy.pi * (1. - 2. * numpy.random.rand(n_variables))
kappa = numpy.zeros((n_orbitals, n_orbitals))
index = 0
for p in range(n_orbitals):
    for q in range(p + 1, n_orbitals):
        kappa[p, q] = random_angles[index]
        kappa[q, p] = -numpy.conjugate(random_angles[index])
        index += 1

    # Build the unitary rotation matrix.
from openfermion.hamiltonians import fermi_hubbard
from openfermion.transforms import get_sparse_operator, jordan_wigner
from openfermion.utils import get_ground_state

# Set model.
x_dimension = 2
y_dimension = 2
tunneling = 2.
coulomb = 1.
magnetic_field = 0.5
chemical_potential = 0.25
periodic = 1
spinless = 1

# Get fermion operator.
hubbard_model = fermi_hubbard(
  x_dimension, y_dimension, tunneling, coulomb, chemical_potential,
  magnetic_field, periodic, spinless)
print (hubbard_model)

# Get qubit operator under Jordan-Wigner.
jw_hamiltonian = jordan_wigner(hubbard_model)
jw_hamiltonian.compress()
print (jw_hamiltonian)

# Get scipy.sparse.csc representation.
sparse_operator = get_sparse_operator(hubbard_model)
print (sparse_operator)
print ('\nEnergy of the model is {} in units of T and J.'.format(
  get_ground_state(sparse_operator)[0]))