Fourier transforms

Synopsis

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, 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);


fourier

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.


make_gf_from_fourier

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.

Example

#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};

// 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);
}

language:

cpp