/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2013 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see .
*
******************************************************************************/
#pragma once
#include "./product.hpp"
namespace triqs { namespace gfs {
template struct lambda_valued {};
template gf_view> make_gf_view_lambda_valued(M m, L l) {
return {std::move(m), l, nothing(), nothing(), {}};
}
namespace gfs_implementation {
/// --------------------------- data access ---------------------------------
template struct data_proxy,Opt> : data_proxy_lambda {};
/// --------------------------- Factories ---------------------------------
template
struct data_factory, lambda_valued, nothing, Opt> {};
/// --------------------------- partial_eval ---------------------------------
// partial_eval<0> (g, 1) returns : x -> g(1,x)
// partial_eval<1> (g, 3) returns : x -> g(x,3)
// a technical trait: from a tuple of mesh, return the mesh (either M if it is a tuple of size 1, or the corresponding cartesian_product).
template struct cart_prod_impl;
template struct cart_prod_impl> { using type = cartesian_product;};
template struct cart_prod_impl> { using type = M;};
template using cart_prod = typename cart_prod_impl::type;
// The implementation (can be overloaded for some types), so put in a struct to have partial specialization
template struct partial_eval_impl;
// The user function
template
auto partial_eval(gf_view g, T&&... x) {
return partial_eval_impl::template invoke(g(), std::forward(x)...);
}
template
auto partial_eval(gf& g, T&&... x) {
return partial_eval_impl::template invoke(g(), std::forward(x)...);
}
template
auto partial_eval(gf const& g, T&&... x) {
return partial_eval_impl::template invoke(g(), std::forward(x)...);
}
/// --------------------------- curry ---------------------------------
// curry<0>(g) returns : x-> y... -> g(x,y...)
// curry<1>(g) returns : y-> x,z... -> g(x,y,z...)
// The implementation (can be overloaded for some types)
template
auto curry_impl(gf_view, Target, Singularity, Opt, IsConst> g) {
// pick up the meshed corresponding to the curryed variables
auto meshes_tuple = triqs::tuple::filter(g.mesh().components());
using var_t = cart_prod, pos...>>;
auto m = triqs::tuple::apply_construct>(meshes_tuple);
auto l = [g](auto&&... x) { return partial_eval(g, x...); };
return make_gf_view_lambda_valued(m, l);
};
// The user function
template
auto curry(gf_view g) {
return curry_impl(g());
}
template
auto curry(gf& g) {
return curry_impl(g());
}
template
auto curry(gf const& g) {
return curry_impl(g());
}
//---------------------------------------------
// A generic impl. for cartesian product
template
struct partial_eval_impl, Target, Singularity, Opt, IsConst> {
template
static auto invoke(gf_view, Target, Singularity, Opt, IsConst> g, T const&... x) {
using var_t = cart_prod, pos...>>;
// meshes of the returned gf_view : just drop the mesh of the evaluated variables
auto meshes_tuple_partial = triqs::tuple::filter_out(g.mesh().components());
auto m = triqs::tuple::apply_construct>(meshes_tuple_partial);
// now rebuild a tuple of the size sizeof...(Ms), containing the indices and range at the position of evaluated variables.
auto arr_args = triqs::tuple::inverse_filter(std::make_tuple(x...), arrays::range());
// from it, we make a slice of the array of g, corresponding to the data of the returned gf_view
auto arr2 = triqs::tuple::apply(g.data(), std::tuple_cat(arr_args, std::make_tuple(arrays::ellipsis{})));
auto singv = partial_eval(g.singularity(), x...);
using r_sing_t = typename decltype(singv)::regular_type;
// finally, we build the view on this data.
using r_t = gf_view;
return r_t{m, arr2, singv, {}, {}};
}
};
} // gf_implementation
using gfs_implementation::partial_eval;
using gfs_implementation::curry;
}}