Skip to content

Commit d049440

Browse files
Strilancbabbush
authored andcommitted
Cleanup plane wave fourier transform (#34)
* Add multiplicative/additive identity methods to FermionOperator * Add FermionOperator.sum/product * Rename * Cleanup plane wave fourier transform - Use Grid parameter instead of grid field parameters - Extract common helper to handle both the forward and inverse cases * merge typo * Cut sum/product * typo
1 parent d43dcb8 commit d049440

File tree

1 file changed

+37
-44
lines changed

1 file changed

+37
-44
lines changed

src/fermilib/utils/_plane_wave_hamiltonian.py

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -165,89 +165,82 @@ def fourier_transform(hamiltonian, grid, spinless):
165165
c_v = \sqrt{1/N} \sum_m {a_m \exp(i k_v r_m)}
166166
167167
Args:
168-
hamiltonian: The hamiltonian in plane wave basis.
169-
grid: The discretization to use.
170-
spinless: Bool, whether to use the spinless model or not.
168+
hamiltonian (FermionOperator): The hamiltonian in plane wave basis.
169+
grid (Grid): The discretization to use.
170+
spinless (bool): Whether to use the spinless model or not.
171171
172172
Returns:
173-
hamiltonian_t: An instance of the FermionOperator class.
173+
FermionOperator: The fourier-transformed hamiltonian.
174174
"""
175175
return _fourier_transform_helper(hamiltonian=hamiltonian,
176176
grid=grid,
177177
spinless=spinless,
178-
factor=+1,
178+
phase_factor=+1,
179179
vec_func_1=momentum_vector,
180180
vec_func_2=position_vector)
181181

182182

183183
def inverse_fourier_transform(hamiltonian, grid, spinless):
184-
"""Apply Fourier transform to change hamiltonian in plane wave dual basis.
184+
"""Apply inverse Fourier transform to change hamiltonian in plane wave dual
185+
basis.
185186
186187
.. math::
187188
188189
a^\dagger_v = \sqrt{1/N} \sum_m {c^\dagger_m \exp(i k_v r_m)}
189190
a_v = \sqrt{1/N} \sum_m {c_m \exp(-i k_v r_m)}
190191
191192
Args:
192-
hamiltonian: The hamiltonian in plane wave dual basis.
193-
grid: The discretization to use.
194-
spinless: Bool, whether to use the spinless model or not.
193+
hamiltonian (FermionOperator):
194+
The hamiltonian in plane wave dual basis.
195+
grid (Grid): The discretization to use.
196+
spinless (bool): Whether to use the spinless model or not.
195197
196198
Returns:
197-
hamiltonian_t: An instance of the FermionOperator class.
199+
FermionOperator: The inverse-fourier-transformed hamiltonian.
198200
"""
201+
199202
return _fourier_transform_helper(hamiltonian=hamiltonian,
200203
grid=grid,
201204
spinless=spinless,
202-
factor=-1,
205+
phase_factor=-1,
203206
vec_func_1=position_vector,
204207
vec_func_2=momentum_vector)
205208

206209

207-
def _fourier_transform_helper(hamiltonian, grid, spinless,
208-
factor, vec_func_1, vec_func_2):
209-
hamiltonian_t = None
210+
def _fourier_transform_helper(hamiltonian,
211+
grid,
212+
spinless,
213+
phase_factor,
214+
vec_func_1,
215+
vec_func_2):
216+
hamiltonian_t = FermionOperator.zero()
217+
normalize_factor = numpy.sqrt(1.0 / float(grid.num_points()))
210218

211219
for term in hamiltonian.terms:
212-
transformed_term = None
213-
for ladder_operator in term:
214-
indices_1 = grid_indices(ladder_operator[0], grid, spinless)
215-
vec_1 = vec_func_1(indices_1, grid)
216-
new_basis = None
220+
transformed_term = FermionOperator.identity()
221+
for ladder_op_mode, ladder_op_type in term:
222+
indices_1 = grid_indices(ladder_op_mode, grid, spinless)
223+
vec1 = vec_func_1(indices_1, grid)
224+
new_basis = FermionOperator.zero()
217225
for indices_2 in grid.all_points_indices():
218-
vec_2 = vec_func_2(indices_2, grid)
219-
if spinless:
220-
spin = None
221-
else:
222-
spin = ladder_operator[0] % 2
226+
vec2 = vec_func_2(indices_2, grid)
227+
spin = None if spinless else ladder_op_mode % 2
223228
orbital = orbital_id(grid, indices_2, spin)
224-
exp_index = factor * 1.0j * numpy.dot(vec_1, vec_2)
225-
if ladder_operator[1] == 1:
229+
exp_index = phase_factor * 1.0j * numpy.dot(vec1, vec2)
230+
if ladder_op_type == 1:
226231
exp_index *= -1.0
227232

228-
element = FermionOperator(((orbital, ladder_operator[1]),),
233+
element = FermionOperator(((orbital, ladder_op_type),),
229234
numpy.exp(exp_index))
230-
if new_basis is None:
231-
new_basis = element
232-
else:
233-
new_basis += element
234-
235-
new_basis *= numpy.sqrt(1.0/float(grid.num_points()))
236-
237-
if transformed_term is None:
238-
transformed_term = new_basis
239-
else:
240-
transformed_term *= new_basis
241-
if transformed_term is None:
242-
continue
235+
new_basis += element
236+
237+
new_basis *= normalize_factor
238+
transformed_term *= new_basis
243239

244240
# Coefficient.
245241
transformed_term *= hamiltonian.terms[term]
246242

247-
if hamiltonian_t is None:
248-
hamiltonian_t = transformed_term
249-
else:
250-
hamiltonian_t += transformed_term
243+
hamiltonian_t += transformed_term
251244

252245
return hamiltonian_t
253246

0 commit comments

Comments
 (0)