/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2012 by M. Ferrero, 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 . * ******************************************************************************/ #ifndef TRIQS_GF_EXPR_H #define TRIQS_GF_EXPR_H #include namespace triqs { namespace gf { using utility::is_in_ZRC; namespace gf_expr_tools { template struct scalar_wrap { typedef S value_type; S s; scalar_wrap(S const &s_):s(s_){} S singularity() 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 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" < 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 keeper_type : std::conditional::value, scalar_wrap, typename view_type_if_exists_else_type::type> {}; }// gf_expr_tools template struct gf_expr : TRIQS_MODEL_CONCEPT(ImmutableGreenFunction),gf_tag { typedef typename gf_expr_tools::keeper_type::type L_t; typedef typename gf_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 gf_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())); //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_MODEL_CONCEPT(ImmutableGreenFunction),gf_tag{ typedef typename gf_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_)) {} 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, 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); DEFINE_OPERATOR(multiplies, *, ImmutableGreenFunction,ImmutableGreenFunction); DEFINE_OPERATOR(multiplies, *, is_in_ZRC,ImmutableGreenFunction); DEFINE_OPERATOR(multiplies, *, ImmutableGreenFunction,is_in_ZRC); DEFINE_OPERATOR(divides, /, ImmutableGreenFunction,ImmutableGreenFunction); DEFINE_OPERATOR(divides, /, is_in_ZRC,ImmutableGreenFunction); DEFINE_OPERATOR(divides, /, ImmutableGreenFunction,is_in_ZRC); #undef DEFINE_OPERATOR // the unary is special 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