diff --git a/triqs/gfs/data_proxies.hpp b/triqs/gfs/data_proxies.hpp index 24d3b3c0..3e8605d2 100644 --- a/triqs/gfs/data_proxies.hpp +++ b/triqs/gfs/data_proxies.hpp @@ -42,7 +42,9 @@ namespace triqs { namespace gfs { arrays::matrix_view_proxy operator()(storage_view_t & data, size_t i) const { return arrays::matrix_view_proxy(data,i); } arrays::const_matrix_view_proxy operator()(storage_view_t const & data, size_t i) const { return arrays::const_matrix_view_proxy(data,i); } + template static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward(rhs);} template static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward(rhs);} + template static void assign_with_resize (storage_t & data, RHS && rhs) { data = std::forward(rhs);} template static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); } }; @@ -59,7 +61,9 @@ namespace triqs { namespace gfs { auto operator()(storage_view_t & data,size_t i) const -> decltype(data(i)) { return data(i);} auto operator()(storage_view_t const & data,size_t i) const -> decltype(data(i)) { return data(i);} + template static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward(rhs);} template static void assign_to_scalar (S & data, RHS && rhs) { data() = std::forward(rhs);} + template static void assign_with_resize (storage_t & data, RHS && rhs) { data = std::forward(rhs);} template static void rebind (storage_view_t & data, RHS && rhs) { data.rebind(rhs.data()); } }; @@ -78,6 +82,12 @@ namespace triqs { namespace gfs { Tv & operator()(storage_view_t & data, size_t i) { return data[i];} Tv const & operator()(storage_view_t const & data, size_t i) const { return data[i];} + template static void assign_no_resize (S & data, RHS && rhs) { + //auto r = make_vector(rhs); + if (data.size() !=rhs.size()) TRIQS_RUNTIME_ERROR << "Size mismatch in gf assignment"; + for (size_t i =0; i static void assign_with_resize (S & data, RHS && rhs) {data = utility::factory(rhs);} template static void assign_to_scalar (S & data, RHS && rhs) {for (size_t i =0; i static void rebind (storage_view_t & data, RHS && rhs) { data.clear(); for (auto & x : rhs.data()) data.push_back(x);} }; @@ -94,6 +104,8 @@ namespace triqs { namespace gfs { auto operator()(storage_t & data, size_t i) DECL_AND_RETURN( data(i)); auto operator()(storage_t const & data, size_t i) const DECL_AND_RETURN( data(i)); + template static void assign_no_resize (S & data, RHS && rhs) { data() = std::forward(rhs);} + template static void assign_with_resize (S & data, RHS && rhs) = delete; template static void assign_to_scalar (S & data, RHS && rhs) = delete; template static void rebind (storage_view_t & data, RHS && rhs) = delete;// { data = std::forward(rhs);} }; diff --git a/triqs/gfs/gf.hpp b/triqs/gfs/gf.hpp index adc70a64..f2422468 100644 --- a/triqs/gfs/gf.hpp +++ b/triqs/gfs/gf.hpp @@ -33,6 +33,7 @@ namespace triqs { namespace gfs { using utility::factory; using arrays::make_shape; + // GENERALISE matrxi TO DEFAULT template struct gf_mesh; template class gf; // the regular type template class gf_view; // the view type @@ -40,7 +41,7 @@ namespace triqs { namespace gfs { // various implementation traits namespace gfs_implementation { // never use using of this... - // evaluator regroup functions to evaluate the function. + // evaluator regroup functions to evaluate the function. Cf descriptors template struct evaluator{ static constexpr int arity = 0;}; // closest_point mechanism @@ -59,7 +60,7 @@ namespace triqs { namespace gfs { // this is used to specialize this part of the code to array of dim 3 (matrix gf), dim 1 (scalar gf) and vector (e.g. block gf, ...) template struct data_proxy; - // This trait contains functions to read/write in hdf5 files. Can be specialized for some case (Cf block) + // This trait contains functions to read/write in hdf5 files. Can be specialized for some descriptor (Cf block) template struct h5_name; // value is a const char * template struct h5_name { static std::string invoke(){ return h5_name::invoke() + "_s";}}; @@ -82,6 +83,9 @@ namespace triqs { namespace gfs { template gf_view make_gf_view(U && ... x) { return gfs_implementation::factories::make_gf_view(std::forward(x)...);} + template struct gf_desc{}; + template struct gf_tag{}; + // The trait that "marks" the Green function TRIQS_DEFINE_CONCEPT_AND_ASSOCIATED_TRAIT(ImmutableGreenFunction); @@ -89,28 +93,31 @@ namespace triqs { namespace gfs { /// A common implementation class for gf and gf_view. They will only redefine contructor and = ... template class gf_impl : - TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ + TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction), gf_tag> { public : + + // Pattern : ValueView typedef gf_view view_type; typedef gf regular_type; + typedef gf_desc descriptor_t; + typedef Variable variable_t; - typedef Target target_t; typedef Opt option_t; typedef gf_mesh mesh_t; typedef typename mesh_t::domain_t domain_t; typedef typename mesh_t::mesh_point_t mesh_point_t; typedef typename mesh_t::index_t mesh_index_t; - typedef typename gfs_implementation::symmetry::type symmetry_t; - typedef gfs_implementation::evaluator evaluator_t; + typedef typename gfs_implementation::symmetry::type symmetry_t; + typedef gfs_implementation::evaluator evaluator_t; - typedef gfs_implementation::data_proxy data_proxy_t; + typedef gfs_implementation::data_proxy data_proxy_t; typedef typename data_proxy_t::storage_t data_regular_t; typedef typename data_proxy_t::storage_view_t data_view_t; - typedef typename std::conditional::type data_t; + typedef typename std::conditional::type data_t; - typedef typename gfs_implementation::singularity::type singularity_non_view_t; + typedef typename gfs_implementation::singularity::type singularity_non_view_t; typedef typename view_type_if_exists_else_type::type singularity_view_t; typedef typename std::conditional::type singularity_t; @@ -178,6 +185,13 @@ namespace triqs { namespace gfs { >::type // end of add_Const operator() (Arg0&& arg0, Args&&... args) const { return _evaluator(this,std::forward( arg0), std::forward(args)...); } + // Interaction with the CLEF library : calling the gf with any clef expression as argument build a new clef expression + //template + // auto operator()(Arg0 arg0, Args... args) const DECL_AND_RETURN( clef::make_expr_call(view_type(*this),arg0, args...)); + + //template + // auto operator()(Arg0 arg0, Args... args) DECL_AND_RETURN( clef::make_expr_call(view_type(*this),arg0, args...)); + template typename clef::_result_of::make_expr_call::type operator()(Arg0 arg0, Args... args) const { @@ -213,14 +227,34 @@ namespace triqs { namespace gfs { template cr_type operator[] (closest_pt_wrap const & p) const { return _data_proxy(_data, _mesh.index_to_linear( gfs_implementation::get_closest_point::invoke(this,p)));} + // Interaction with the CLEF library : calling the gf with any clef expression as argument build a new clef expression + /* template + typename boost::lazy_enable_if< // enable the template if + clef::is_any_lazy, // One of Args is a lazy expression + clef::_result_of::make_expr_subscript + >::type // end of lazy_enable_if + operator[](Arg && arg) const { return clef::make_expr_subscript(view_type(*this),std::forward(arg));} + */ + + /*template + //auto operator[](Arg && arg) const DECL_AND_RETURN(clef::make_expr_subscript((*this)(),std::forward(arg))); + auto operator[](Arg && arg) const DECL_AND_RETURN(clef::make_expr_subscript(view_type(*this),std::forward(arg))); + + template + //auto operator[](Arg && arg) DECL_AND_RETURN(clef::make_expr_subscript((*this)(),std::forward(arg))); + auto operator[](Arg && arg) DECL_AND_RETURN(clef::make_expr_subscript(view_type(*this),std::forward(arg))); + */ + template typename clef::_result_of::make_expr_subscript::type operator[](Arg && arg) const { return clef::make_expr_subscript(view_type(*this),std::forward(arg));} /// A direct access to the grid point + template r_type on_mesh (Args&&... args) { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward(args)...)));} + /// A direct access to the grid point (const version) template cr_type on_mesh (Args&&... args) const { return _data_proxy(_data,_mesh.index_to_linear(mesh_index_t(std::forward(args)...)));} @@ -245,7 +279,7 @@ namespace triqs { namespace gfs { friend void h5_write (h5::group fg, std::string subgroup_name, gf_impl const & g) { auto gr = fg.create_group(subgroup_name); gr.write_triqs_hdf5_data_scheme(g); - gfs_implementation::h5_ops::write(gr, "data", g._data, g); + gfs_implementation::h5_ops::write(gr, "data", g._data, g);//can be specialized for some descriptors (E.g. blocks) h5_write(gr,"singularity",g._singularity); h5_write(gr,"mesh",g._mesh); h5_write(gr,"symmetry",g._symmetry); @@ -259,7 +293,7 @@ namespace triqs { namespace gfs { auto tag_expected= get_triqs_hdf5_data_scheme(g); if (tag_file != tag_expected) TRIQS_RUNTIME_ERROR<< "h5_read : mismatch of the tag TRIQS_HDF5_data_scheme tag in the h5 group : found "<::read(gr, "data", g._data, g); + gfs_implementation::h5_ops::read(gr, "data", g._data, g);//can be specialized for some descriptors (E.g. blocks) h5_read(gr,"singularity",g._singularity); h5_read(gr,"mesh",g._mesh); h5_read(gr,"symmetry",g._symmetry); @@ -303,13 +337,13 @@ namespace triqs { namespace gfs { friend void swap (gf & a, gf & b) noexcept { a.swap_impl (b);} - gf & operator = (gf const & rhs) { *this = gf(rhs); return *this;} // use move = - gf & operator = (gf & rhs) { *this = gf(rhs); return *this;} // use move = - gf & operator = (gf && rhs) noexcept { swap(*this,rhs); return *this;} + gf & operator = (gf const & rhs) { *this = gf(rhs); return *this;} // use move = + gf & operator = (gf & rhs) { *this = gf(rhs); return *this;} // use move = + gf & operator = (gf && rhs) noexcept { swap(*this, rhs); return *this;} template void operator = (RHS && rhs) { - this->_mesh = std::forward(rhs).mesh(); - for (auto const & w: this->mesh()) (*this)[w] = rhs[w]; + this->_mesh = rhs.mesh(); + B::data_proxy_t::assign_with_resize(this->data(), std::forward(rhs).data()); // looks strange for && this->_singularity = rhs.singularity(); // to be implemented : there is none in the gf_expr in particular.... //this->_symmetry = rhs.symmetry(); @@ -371,8 +405,8 @@ namespace triqs { namespace gfs { // delegate = so that I can overload it for specific RHS... template DISABLE_IF(arrays::is_scalar) triqs_gf_view_assign_delegation( gf_view g, RHS const & rhs) { - if (!(g.mesh() == rhs.mesh())) TRIQS_RUNTIME_ERROR<<"Gf Assignment in View : incompatible mesh"; - for (auto const & w: g.mesh()) g[w] = rhs[w]; + if (!(g.mesh() == rhs.mesh())) TRIQS_RUNTIME_ERROR<<"Gf Assignment in View : incompatible mesh"; + gf_view::data_proxy_t::assign_no_resize(g.data(),rhs.data()); g.singularity() = rhs.singularity(); } diff --git a/triqs/gfs/gf_expr.hpp b/triqs/gfs/gf_expr.hpp index 21804105..88bfada4 100644 --- a/triqs/gfs/gf_expr.hpp +++ b/triqs/gfs/gf_expr.hpp @@ -21,93 +21,93 @@ #ifndef TRIQS_GF_EXPR_H #define TRIQS_GF_EXPR_H #include -namespace triqs { namespace gfs { - +namespace triqs { namespace gfs { using utility::is_in_ZRC; - using utility::remove_rvalue_ref; - - namespace gfs_expr_tools { - - // a wrapper for scalars + namespace gfs_expr_tools { template struct scalar_wrap { - typedef void variable_t; - typedef void target_t; - typedef void option_t; - S s; - template scalar_wrap(T && x):s(std::forward(x)){} + typedef S value_type; + S s; scalar_wrap(S const &s_):s(s_){} S singularity() const { return s;} - template S operator[](KeyType && key) const { return s;} - template inline S operator()(Args && ... args) const { return s;} + S data() const { return s;} + template value_type operator[](KeyType && key) const { return s;} + template inline value_type operator()(Args && ... args) const { return s;} friend std::ostream &operator <<(std::ostream &sout, scalar_wrap const &expr){return sout << expr.s; } }; // Combine the two meshes of LHS and RHS : need to specialize where there is a scalar struct combine_mesh { template - auto operator() (L && l, R && r) const -> decltype(std::forward(l).mesh()) { + inline auto operator() (L const & l, R const & r) const -> decltype(l.mesh()) { if (!(l.mesh() == r.mesh())) TRIQS_RUNTIME_ERROR << "Mesh mismatch : ";//<< l.mesh()<<" vs" <(l).mesh(); + return l.mesh(); } - template auto operator() (scalar_wrap const &, R && r) const DECL_AND_RETURN(std::forward(r).mesh()); - template auto operator() (L && l, scalar_wrap const &) const DECL_AND_RETURN(std::forward(l).mesh()); + template auto operator() (scalar_wrap const & w, R const & r) const -> decltype(r.mesh()) { return r.mesh();} + template auto operator() (L const & l, scalar_wrap const & w) const -> decltype(l.mesh()) { return l.mesh();} }; - template struct node_t : std::conditional::value, scalar_wrap, typename remove_rvalue_ref::type> {}; - - template struct _or_ {typedef void type;}; - template struct _or_ {typedef A type;}; - template struct _or_ {typedef A type;}; - template struct _or_ {typedef A type;}; - template <> struct _or_ {typedef void type;}; - + template struct keeper_type : std::conditional::value, scalar_wrap, typename view_type_if_exists_else_type::type> {}; }// gfs_expr_tools - template struct gf_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ - typedef typename std::remove_reference::type L_t; - typedef typename std::remove_reference::type R_t; - typedef typename gfs_expr_tools::_or_::type variable_t; - typedef typename gfs_expr_tools::_or_::type target_t; - typedef typename gfs_expr_tools::_or_::type option_t; - static_assert(!std::is_same::value, "Can not combine two gf expressions with different variables"); - static_assert(!std::is_same::value, "Can not combine two gf expressions with different target"); - - L l; R r; - template gf_expr(LL && l_, RR && r_):l(std::forward(l_)), r(std::forward(r_)) {} - - auto mesh() const DECL_AND_RETURN(gfs_expr_tools::combine_mesh()(l,r)); + template struct gf_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction),gf_tag { + typedef typename gfs_expr_tools::keeper_type::type L_t; + typedef typename gfs_expr_tools::keeper_type::type R_t; + typedef Descriptor descriptor_t; + //typedef typename std::result_of(typename L_t::value_type,typename R_t::value_type)>::type value_t; + typedef typename std::remove_reference::type>::type mesh_t; + //typedef typename Descriptor::singularity_t::view_type singularity_view_t; + //typedef value_t value_type; + L_t l; R_t r; + template gf_expr(LL && l_, RR && r_) : l(std::forward(l_)), r(std::forward(r_)) {} + mesh_t mesh() const { return gfs_expr_tools::combine_mesh()(l,r); } + auto data() const ->decltype( utility::operation()(l.data(), r.data())) { return utility::operation()(l.data(), r.data());} auto singularity() const DECL_AND_RETURN (utility::operation()(l.singularity() , r.singularity())); - - template auto operator[](KeyType && key) const DECL_AND_RETURN(utility::operation()(l[std::forward(key)] , r[std::forward(key)])); + //const singularity_view_t singularity() const { return utility::operation()(l.singularity() , r.singularity());} + //symmetry_t const & symmetry() const { return _symmetry;} + template auto operator[](KeyType && key) const DECL_AND_RETURN(utility::operation()(l[std::forward(key)] , r[std::forward(key)])); template auto operator()(Args && ... args) const DECL_AND_RETURN(utility::operation()(l(std::forward(args)...) , r(std::forward(args)...))); friend std::ostream &operator <<(std::ostream &sout, gf_expr const &expr){return sout << "("<::name << " "< struct gf_unary_m_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction){ - typedef typename std::remove_reference::type L_t; - typedef typename L_t::variable_t variable_t; - typedef typename L_t::target_t target_t; - typedef typename L_t::option_t option_t; - - L l; + template struct gf_unary_m_expr : TRIQS_CONCEPT_TAG_NAME(ImmutableGreenFunction),gf_tag{ + typedef typename gfs_expr_tools::keeper_type::type L_t; + typedef Descriptor descriptor_t; + //typedef typename L_t::value_type value_type; + typedef typename L_t::mesh_t mesh_t; + //typedef typename Descriptor::singularity_t::view_type singularity_view_t; + L_t l; template gf_unary_m_expr(LL && l_) : l(std::forward(l_)) {} - - auto mesh() const DECL_AND_RETURN(l.mesh()); + mesh_t mesh() const { return l.mesh(); } + auto data() const ->decltype( - l.data()) { return - l.data();} auto singularity() const DECL_AND_RETURN(l.singularity()); - + //const singularity_view_t singularity() const { return l.singularity();} + //symmetry_t const & symmetry() const { return _symmetry;} template auto operator[](KeyType&& key) const DECL_AND_RETURN( -l[key]); template auto operator()(Args && ... args) const DECL_AND_RETURN( -l(std::forward(args)...)); friend std::ostream &operator <<(std::ostream &sout, gf_unary_m_expr const &expr){return sout << '-'< struct get_desc; + template + struct get_desc ::value) && (ImmutableGreenFunction::value))>::type > { + typedef typename A2::descriptor_t type; + }; + template + struct get_desc ::value) && (ImmutableGreenFunction::value)>::type > { + typedef typename A1::descriptor_t type; + }; + template + struct get_desc ::value) && (ImmutableGreenFunction::value) && std::is_same::value >::type > { typedef typename A2::descriptor_t type; }; + // ------------------------------------------------------------------- // Now we can define all the C++ operators ... #define DEFINE_OPERATOR(TAG, OP, TRAIT1, TRAIT2) \ template\ - typename std::enable_if::value && TRAIT2 ::value, \ - gf_expr::type, typename gfs_expr_tools::node_t::type>>::type\ - operator OP (A1 && a1, A2 && a2) { return {std::forward(a1),std::forward(a2)};} + typename std::enable_if::value && TRAIT2 ::value, gf_expr::type, utility::tags::TAG, A1,A2>>::type\ + operator OP (A1 const & a1, A2 const & a2) { return gf_expr::type,utility::tags::TAG, A1,A2>(a1,a2);} DEFINE_OPERATOR(plus, +, ImmutableGreenFunction,ImmutableGreenFunction); DEFINE_OPERATOR(minus, -, ImmutableGreenFunction,ImmutableGreenFunction); @@ -120,12 +120,8 @@ namespace triqs { namespace gfs { #undef DEFINE_OPERATOR // the unary is special - template - typename std::enable_if< - ImmutableGreenFunction::value, - gf_unary_m_expr::type > - >::type - operator - (A1 && a1) { return {std::forward(a1)};} + template typename std::enable_if::value, gf_unary_m_expr>::type + operator - (A1 const & a1) { return gf_unary_m_expr(a1);} }}//namespace triqs::gf #endif