From f4444f3b496e3ffde6f02bf1f588b61b0420b535 Mon Sep 17 00:00:00 2001 From: Michel Ferrero Date: Wed, 16 Oct 2013 23:48:14 +0200 Subject: [PATCH] Revert a wrong fix in expression template for gf This reverts the part of the commit 1906dc30a5363351a1a5d8fd429a2f91caf944bd which introduced modifications in the expr templates of the Green's functions. The commit had introduced some bugs and this revert removes them (the expr templates will be taken care of fully in later commits). This is a temporary fix for issues #18 and #25. reverted: triqs/gfs/data_proxies.hpp reverted: triqs/gfs/gf.hpp reverted: triqs/gfs/gf_expr.hpp --- triqs/gfs/data_proxies.hpp | 12 ++++ triqs/gfs/gf.hpp | 70 ++++++++++++++++------ triqs/gfs/gf_expr.hpp | 116 ++++++++++++++++++------------------- 3 files changed, 120 insertions(+), 78 deletions(-) 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