void som_core::set_input_data(gf_const_view<GfOpts...> g, gf_const_view<GfOpts...> S) { using mesh_t = typename gf_const_view<GfOpts...>::mesh_t; auto & rhs_ = (input_data_t<mesh_t>&)rhs; auto & error_bars_ = (input_data_t<mesh_t>&)error_bars; auto gf_dim = get_target_shape(g)[0]; results.reserve(gf_dim); for(int i = 0; i < gf_dim; ++i) { rhs_.emplace_back(g.data()(range(),i,i)); error_bars_.emplace_back(S.data()(range(),i,i)); results.emplace_back(ci); } histograms.resize(gf_dim); }
// compute a tail from the Legendre GF // this is Eq. 8 of our paper tail_view get_tail(gf_const_view<legendre> gl, int size = 10, int omin = -1) { auto sh = gl.data().shape().front_pop(); tail t(sh, size, omin); t.data()() = 0.0; for (int p=1; p<=t.order_max(); p++) for (auto l : gl.mesh()) t(p) += (triqs::utility::legendre_t(l.index(),p)/pow(gl.domain().beta,p)) * gl[l]; return t; }
// compute a tail from the Legendre GF // this is Eq. 8 of our paper array<dcomplex, 3> get_tail(gf_const_view<legendre> gl, int order) { auto _ = ellipsis{}; auto sh = gl.data().shape(); sh[0] = order; array<dcomplex, 3> t{sh}; t() = 0.0; for (int p = 0; p < order; p++) for (auto l : gl.mesh()) t(p, _) += (triqs::utility::legendre_t(l.index(), p) / std::pow(gl.domain().beta, p)) * gl[l]; return t; }
void legendre_matsubara_inverse(gf_view<legendre> gl, gf_const_view<imfreq> gw) { gl() = 0.0; // Construct a temporary imaginary-time Green's function gt // I set Nt time bins. This is ugly, one day we must code the direct // transformation without going through imaginary time int Nt = 50000; auto gt = gf<imtime>{{gw.domain(), Nt}, gw.data().shape().front_pop()}; // We first transform to imaginary time because it's been coded with the knowledge of the tails gt() = inverse_fourier(gw); legendre_matsubara_inverse(gl, gt()); }
// This function takes a g(i omega_n) on half mesh (positive omega_n) and returns a gf on the whole mesh // using G(-i omega_n) = G(i omega_n)^* for real G(tau) functions. template <typename T, typename S, typename E> gf<imfreq, T, S, E> make_gf_from_real_gf(gf_const_view<imfreq, T, S, E> g) { if (!g.mesh().positive_only()) TRIQS_RUNTIME_ERROR << "gf imfreq is not for omega_n >0, real_to_complex does not apply"; auto const &dat = g.data(); auto sh = dat.shape(); int is_boson = (g.mesh().domain().statistic == Boson); long L = sh[0]; sh[0] = 2 * sh[0] - is_boson; array<dcomplex, std14::decay_t<decltype(dat)>::rank> new_data(sh); auto _ = arrays::ellipsis{}; if (is_boson) new_data(L - 1, _) = dat(0, _); int L1 = (is_boson ? L - 1 : L); for (int u = is_boson; u < L; ++u) { new_data(L1 + u, _) = dat(u, _); new_data(L - 1 - u, _) = conj(dat(u, _)); } return {gf_mesh<imfreq>{g.mesh().domain(), L}, std::move(new_data), g.singularity(), g.symmetry(), g.indices(), g.name}; }
/// Takes the real part of g without check, and returns a new gf with a real target template <typename M, typename T, typename S, typename E> gf<M, real_target_t<T>, S> real(gf_const_view<M, T, S, E> g) { return {g.mesh(), real(g.data()), g.singularity(), g.symmetry(), {}, {}}; // no indices for real_valued, internal C++ use only }
template <typename F, typename G> gf<block_index, std14::result_of_t<F(G)>> map(F &&f, gf_const_view<block_index, G> g) { return make_block_gf(get_block_names(g), _map(f, g.data())); }