Fourier transforms


Here is a synopsis (V = imfreq, imtime, refreq, retime):

auto fourier(gf_const_view<V, T> g);
auto fourier(gf_const_view<V, T> g, array_const_view<dcomplex, 1 + T::rank> known_moments);

gf<adj(V), T> make_gf_from_fourier(gf_const_view<V, T> g);
gf<adj(V), T> make_gf_from_fourier(gf_const_view<V, T> g, V m);
gf<adj(V), T> make_gf_from_fourier(gf_const_view<V, T> g, V m, array_const_view<dcomplex, 1 + T::rank> known_moments);


The fourier function does not perform the Fourier transformation, but returns a small lazy object (basically saying “Fourier Transform of XXX”), which is then used in an assignment of a view of a gf.

The reason is the following: when putting e.g. a Fourier transform of a function in time, say gt, into a Green function in frequencies, say gw, we want to say something like:

gw = fourier(gt); // ??? (1)

However, if the fourier function performs the transformation, how could it know the details of the mesh of gw ? That information is not available when calling fourier.

Since fourier returns a small lazy object, the library can then rewrite (1) internally into something like

call_the_fourier_implementation(gt, gw);

where all the information about the mesh of gw is now available to the implementation.

Moreover, since fourier(gt) does not possess a domain (for the same reason), (1) makes no sense: RHS of gf assignment requires a domain (cf concepts). We therefore use a view as LHS:

gw() = fourier(gt); // correct usage.


In the case where we want to create a new container from the fourier transform of gt, we can use the function make_gf_from_fourier.


#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs::gfs;
using namespace triqs;

int main() {

  // Set the parameters
  double beta = 1, a = 1;
  int n_iw  = 1000;
  int n_tau = 6 * n_iw + 1;

  // Construct the meshes
  auto iw_mesh  = mesh::imfreq{beta, Fermion, n_iw};
  auto tau_mesh = make_adjoint_mesh(iw_mesh);

  // Construct the Green functions
  auto gw = gf<imfreq, scalar_valued>{iw_mesh};
  auto gt = gf<imtime, scalar_valued>{tau_mesh};

  // Initialization
  nda::clef::placeholder<0> om_;
  gw(om_) << 1 / (om_ - a);

  // Fill gt with the fourier transform of gw and provide the first two
  // orders of the high-frequency expansion of gw
  auto known_moments = array<dcomplex, 1>{0.0, 1.0};
  gt()               = fourier(gw, known_moments);

  // Construct a new Green function gw2 from the Fourier transform of gt
  auto gw2 = make_gf_from_fourier(gt, iw_mesh);