예제 #1
0
def _fourier_transform_helper(hamiltonian, grid, spinless, phase_factor,
                              vec_func_1, vec_func_2):
    hamiltonian_t = FermionOperator.zero()
    normalize_factor = numpy.sqrt(1.0 / float(grid.num_points()))

    for term in hamiltonian.terms:
        transformed_term = FermionOperator.identity()
        for ladder_op_mode, ladder_op_type in term:
            indices_1 = grid_indices(ladder_op_mode, grid, spinless)
            vec1 = vec_func_1(indices_1, grid)
            new_basis = FermionOperator.zero()
            for indices_2 in grid.all_points_indices():
                vec2 = vec_func_2(indices_2, grid)
                spin = None if spinless else ladder_op_mode % 2
                orbital = orbital_id(grid, indices_2, spin)
                exp_index = phase_factor * 1.0j * numpy.dot(vec1, vec2)
                if ladder_op_type == 1:
                    exp_index *= -1.0

                element = FermionOperator(((orbital, ladder_op_type), ),
                                          numpy.exp(exp_index))
                new_basis += element

            new_basis *= normalize_factor
            transformed_term *= new_basis

        # Coefficient.
        transformed_term *= hamiltonian.terms[term]

        hamiltonian_t += transformed_term

    return hamiltonian_t
예제 #2
0
    def __init__(self, a=7.72, n=3, n_active_el=2, n_active_orb=4):
        self.a = a
        self.n = n
        self.n_active_el = n_active_el
        self.n_active_orb = n_active_orb
        self.N_units = 4
        self.opt_energy = None
        self.opt_amplitudes = None

        species_a = 'H'
        species_b = 'Li'

        # Construct a fermion Hamiltonian
        grid = Grid(3, self.n, self.a)
        geometry = [(species_a, (0, 0, 0)), (species_a, (0, 0.5, 0.5)),
                    (species_a, (0.5, 0, 0.5)), (species_a, (0.5, 0.5, 0)),
                    (species_b, (0.5, 0.5, 0.5)), (species_b, (0.5, 0, 0)),
                    (species_b, (0, 0.5, 0)), (species_b, (0, 0, 0.5))]
        self.fermion_hamiltonian = plane_wave_hamiltonian(
            grid,
            geometry=geometry,
            spinless=False,
            plane_wave=False,
            include_constant=False,
            e_cutoff=None)

        # Freeze specified orbitals
        n_qubits = 2 * n * n * n
        n_electrons = 4 * 3 + 4 * 1

        # Determine the indices of occupied orbitals to be frozen
        if self.n == 3:
            to_fill = ((1, 1, 1), (0, 1, 1), (2, 1, 1), (1, 0, 1), (1, 2, 1),
                       (1, 1, 0), (1, 1, 2), (0, 0, 1))
        else:
            to_fill = range(n_electrons - self.n_active_el)
        to_fill_ids = []
        for s in to_fill:
            to_fill_ids.append(orbital_id(grid, s, 0))
            to_fill_ids.append(orbital_id(grid, s, 1))
        to_fill_ids = to_fill_ids[0:(n_electrons - self.n_active_el)]
        #print(to_fill_ids)
        #print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))
        self.fermion_hamiltonian = freeze_orbitals(self.fermion_hamiltonian,
                                                   to_fill_ids)
        #print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))

        # Freeze unoccupied orbitals
        to_freeze_ids = range(self.n_active_orb,
                              n_qubits - (n_electrons - self.n_active_el))
        #print(to_freeze_ids)
        self.fermion_hamiltonian = freeze_orbitals(self.fermion_hamiltonian,
                                                   [], to_freeze_ids)

        print('# of terms: {}'.format(len(self.fermion_hamiltonian.terms)))

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

        # Initialize com;iler engine
        self.compiler_engine = uccsd_trotter_engine()