37 constexpr dcomplex I{0, 1};
38 inline dcomplex th_expo(
double t,
double a) {
return (t > 0 ? -I * exp(-a * t) : (t < 0 ? 0 : -0.5 * I * exp(-a * t))); }
39 inline dcomplex th_expo_neg(
double t,
double a) {
return (t < 0 ? I * exp(a * t) : (t > 0 ? 0 : 0.5 * I * exp(a * t))); }
40 inline dcomplex th_expo_inv(
double w,
double a) {
return 1. / (
w + I * a); }
41 inline dcomplex th_expo_neg_inv(
double w,
double a) {
return 1. / (
w - I * a); }
46 gf_vec_t<mesh::refreq> _fourier_impl(mesh::refreq
const &w_mesh, gf_vec_cvt<mesh::retime> gt, nda::array_const_view<dcomplex, 2> known_moments) {
48 nda::array_const_view<dcomplex, 2> mom_12;
49 if (known_moments.is_empty())
53 TRIQS_ASSERT2(known_moments.shape()[0] >= 3,
" Direct RealTime Fourier transform requires known moments up to order 2.")
54 double _abs_tail0 = max_element(abs(known_moments(0, range::all)));
56 "ERROR: Direct Fourier implementation requires vanishing 0th moment\n error is :" + std::to_string(_abs_tail0));
57 mom_12.rebind(known_moments(range(1, 3), range::all));
60 long L = gt.mesh().
size();
62 double test = std::abs(gt.mesh().delta() * w_mesh.delta() * static_cast<
double>(L) / (2 * M_PI) - 1);
65 long n_others = second_dim(gt.
data());
66 array<dcomplex, 2> _gout(L, n_others);
67 array<dcomplex, 2> _gin(L, n_others);
69 const
double tmin = gt.mesh().t_min();
70 const
double wmin = w_mesh.w_min();
72 const
double a = w_mesh.delta() * std::sqrt(static_cast<
double>(L));
75 auto m1 = mom_12(0, _);
76 auto m2 = mom_12(1, _);
78 array<dcomplex, 1> a1 = (m1 + I * m2 / a) / 2., a2 = (m1 - I * m2 / a) / 2.;
80 for (auto t : gt.mesh()) _gin(t.index(), _) = (gt[t] - (a1 * th_expo(t, a) + a2 * th_expo_neg(t, a))) * std::exp(I * t * wmin);
82 std::array<
int, 1> dims{
static_cast<int>(L)};
83 _fourier_base(_gin, _gout, 1, dims.data(),
static_cast<int>(n_others), FFTW_BACKWARD);
85 auto gw = gf_vec_t<mesh::refreq>{w_mesh, {n_others}};
87 gw[
w] = gt.mesh().delta() * std::exp(I * (w - wmin) * tmin) * _gout(
w.index(), _) + a1 * th_expo_inv(w, a) + a2 * th_expo_neg_inv(w, a);
94 gf_vec_t<mesh::retime> _fourier_impl(mesh::retime
const &t_mesh, gf_vec_cvt<mesh::refreq> gw, nda::array_const_view<dcomplex, 2> known_moments) {
96 nda::array_const_view<dcomplex, 2> mom_12;
98 if (known_moments.is_empty())
102 TRIQS_ASSERT2(known_moments.shape()[0] >= 3,
" Direct Real-Frequency Fourier transform requires known moments up to order 2.")
104 double _abs_tail0 = max_element(abs(known_moments(0, range::all)));
106 "ERROR: Inverse Fourier implementation requires vanishing 0th moment\n error is :" + std::to_string(_abs_tail0));
108 mom_12.rebind(known_moments(range(1, 3), range::all));
111 long L = gw.mesh().
size();
113 double test = std::abs(t_mesh.delta() * gw.mesh().delta() * static_cast<
double>(L) / (2 * M_PI) - 1);
116 const
double tmin = t_mesh.t_min();
117 const
double wmin = gw.mesh().w_min();
119 const
double a = gw.mesh().delta() * std::sqrt(static_cast<
double>(L));
121 long n_others = second_dim(gw.
data());
123 array<dcomplex, 2> _gin(L, n_others);
124 array<dcomplex, 2> _gout(L, n_others);
127 auto m1 = mom_12(0, _);
128 auto m2 = mom_12(1, _);
130 array<dcomplex, 1> a1 = (m1 + I * m2 / a) / 2., a2 = (m1 - I * m2 / a) / 2.;
132 for (auto w : gw.mesh()) _gin(w.index(), _) = (gw[w] - a1 * th_expo_inv(w, a) - a2 * th_expo_neg_inv(w, a)) * std::exp(-I * w * tmin);
134 std::array<
int, 1> dims{
static_cast<int>(L)};
135 _fourier_base(_gin, _gout, 1, dims.data(),
static_cast<int>(n_others), FFTW_FORWARD);
137 auto gt = gf_vec_t<mesh::retime>{t_mesh, {n_others}};
138 const double corr = 1.0 / (t_mesh.delta() *
static_cast<double>(L));
139 for (
auto t : t_mesh) gt[t] = corr * std::exp(I * wmin * (tmin - t)) * _gout(t.index(), _) + a1 * th_expo(t, a) + a2 * th_expo_neg(t, a);
data_t & data()
Direct access to the blocks.
int size() const
Get the total number of blocks.
Provides the Fourier transform factories and the lazy fourier(...) assignment for Green's functions.
Declares the low-level FFTW wrapper shared by the Fourier transform implementations.
Provides tail fitting, slicing, inversion, reality and matrix-multiplication functions for Green's fu...
auto make_zero_tail(G const &g, int n_moments=10)
Create a zero-initialized tail object for a given Green function object.
#define TRIQS_RUNTIME_ERROR
Throw a triqs::runtime_error with the current source location.
#define TRIQS_ASSERT2(X,...)
Like TRIQS_ASSERT but lets the caller add a custom message.
constexpr nda::clef::placeholder< 3 > w
Placeholder for the frequency .