@@ -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
380389template <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
409419template <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
527560template <typename T>
528561Field<hila::arithmetic_type<T>> Field<T>::FFT_complex_to_real(fft_direction fftdir) const {
0 commit comments