Skip to content

Commit a706534

Browse files
author
Kari Rummukainen
committed
Update FFT documentation
1 parent 42a49dd commit a706534

1 file changed

Lines changed: 55 additions & 22 deletions

File tree

libraries/plumbing/fft.h

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -366,15 +366,24 @@ void FFT_delete_plans();
366366
/////////////////////////////////////////////////////////////////////////////////////////
367367
/// Complex-to-complex FFT transform of a field input, result in result.
368368
/// input and result can be same, "in-place".
369-
/// Both input and output are of type Field<T>, where T must contain complex type,
370-
/// Complex<float> or Complex<double>.
369+
///
370+
/// Both input and output are of type Field<T>, where T must contain complex type,
371+
/// either Complex<float> or Complex<double>.
372+
/// As an example, if T is Vector<Complex<double>,3> the result has the same type
373+
/// and the 3 components of the vector will contain FFTs of the input components.
374+
///
371375
/// directions: if directions[dir] == false (or 0), transform is not done to
372-
/// direction dir. fftdir: direction of the transform itself:
376+
/// coordinate direction dir.
377+
///
378+
/// fftdir: direction of the transform itself:
373379
/// fft_direction::forward (default) x -> k
374380
/// fft_direction::inverse k-> x
381+
///
375382
/// FFT is unnormalized: transform + inverse transform yields source multiplied
376383
/// by the product of the size of the lattice to active directions
377-
/// If all directions are active, result = source * lattice.volume():
384+
/// If all directions are active, result = source * lattice.volume()
385+
///
386+
/// See also Field<T>::FFT()
378387
/////////////////////////////////////////////////////////////////////////////////////////
379388

380389
template <typename T>
@@ -404,6 +413,7 @@ inline void FFT_field(const Field<T> &input, Field<T> &result, const CoordinateV
404413
/// Same as FFT_field(input,result,directions,fftdir)
405414
/// with all directions active.
406415
///
416+
/// See also Field<T>::FFT()
407417
//////////////////////////////////////////////////////////////////////////////////
408418

409419
template <typename T>
@@ -420,13 +430,30 @@ inline void FFT_field(const Field<T> &input, Field<T> &result,
420430
/**
421431
* @brief Field method for performing FFT
422432
* @details
423-
* By default calling without arguments will execute FFT in all directions.
433+
* Used as
434+
* res = f.FFT(<args>);
435+
* where f and res are of type Field<T>, where T must contain complex type, either
436+
* Complex<float> or Complex<double>.
437+
*
438+
* As an example, if T is Vector<Complex<double>,3> the result has the same type
439+
* and the 3 components of the vector will contain FFTs of the input components.
440+
*
441+
* parameter dirs: if dirs[dir] == false (or 0), transform is not done to coordinate
442+
* direction dir. By default calling without arguments will execute FFT in all directions.
443+
*
444+
* parameter fftdir: direction of the transform itself:
445+
* fft_direction::forward (default) x -> k
446+
* fft_direction::inverse k-> x
447+
*
448+
* NOTE: the transform is unnormalized, i.e. forward + inverse transform yields
449+
* the original Field multiplied by the product of the size of the lattice to active directions.
450+
*
424451
* @code{.cpp}
425452
* .
426453
* . // Field f is defined
427454
* .
428455
* auto res = f.FFT() //Forward transform
429-
* auto res_2 = res.FFT(fft_direction::back) // res_2 is same as f
456+
* auto res_2 = res.FFT(fft_direction::back) // res_2 == f * lattice.volume()
430457
* @endcode
431458
*
432459
* One can also specify the direction of the FFT with a coordinate vector:
@@ -435,7 +462,7 @@ inline void FFT_field(const Field<T> &input, Field<T> &result,
435462
* . // Field f is defined
436463
* .
437464
* auto res = f.FFT(e_x) //Forward transform in x-direction
438-
* auto res_2 = res.FFT(e_X,fft_direction::back) // res_2 is same as f
465+
* auto res_2 = res.FFT(e_X,fft_direction::back) // res_2 == f * lattice.size(e_x)
439466
* @endcode
440467
*
441468
* With this in mind `f.FFT(e_x+e_y+e_z) = f.FFT()`
@@ -481,6 +508,27 @@ Field<Complex<hila::arithmetic_type<T>>> Field<T>::FFT_real_to_complex(fft_direc
481508
return cf.FFT(fftdir);
482509
}
483510

511+
//////////////////////////////////////////////////////////////////////////////////
512+
/// @internal Helper function for complex to real FFT, used by FFT_complex_to_real()
513+
//////////////////////////////////////////////////////////////////////////////////
514+
namespace hila {
515+
inline int FFT_complex_to_real_site(const CoordinateVector &cv) {
516+
517+
// foralldir continues only if cv[d] == 0 or cv[d] == size(d)/2
518+
foralldir(d) {
519+
if (cv[d] > 0 && cv[d] < lattice.size(d) / 2)
520+
return 1;
521+
if (cv[d] > lattice.size(d) / 2)
522+
return -1;
523+
}
524+
// we get here only if all coords are 0 or size(d)/2
525+
return 0;
526+
}
527+
528+
} // namespace hila
529+
530+
531+
484532
//////////////////////////////////////////////////////////////////////////////////
485533
/// FFT_complex_to_real;
486534
/// Field must be a complex-valued field, result is a real field of the same number type
@@ -508,21 +556,6 @@ Field<Complex<hila::arithmetic_type<T>>> Field<T>::FFT_real_to_complex(fft_direc
508556
///
509557
//////////////////////////////////////////////////////////////////////////////////
510558

511-
namespace hila {
512-
inline int FFT_complex_to_real_site(const CoordinateVector &cv) {
513-
514-
// foralldir continues only if cv[d] == 0 or cv[d] == size(d)/2
515-
foralldir(d) {
516-
if (cv[d] > 0 && cv[d] < lattice.size(d) / 2)
517-
return 1;
518-
if (cv[d] > lattice.size(d) / 2)
519-
return -1;
520-
}
521-
// we get here only if all coords are 0 or size(d)/2
522-
return 0;
523-
}
524-
525-
} // namespace hila
526559

527560
template <typename T>
528561
Field<hila::arithmetic_type<T>> Field<T>::FFT_complex_to_real(fft_direction fftdir) const {

0 commit comments

Comments
 (0)