diff --git a/pytriqs/gf/local/imfreq.pxd b/pytriqs/gf/local/imfreq.pxd index e61f3266..ec676a9e 100644 --- a/pytriqs/gf/local/imfreq.pxd +++ b/pytriqs/gf/local/imfreq.pxd @@ -48,7 +48,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_imfreq & operator [](int) discrete_mesh & mesh() - cdef gf_block_imfreq make_gf_block_imfreq "triqs::gfs::make_block_gf_view_from_vector>" (vector[gf_imfreq] &) + cdef gf_block_imfreq make_gf_block_imfreq "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" (vector[gf_imfreq] &) #cdef gf_block_imfreq make_gf_block_imfreq "triqs::gfs::make_gf_view>" ( vector[gf_imfreq] &) cdef gf_block_imfreq as_gf_block_imfreq (G) except + diff --git a/pytriqs/gf/local/imtime.pxd b/pytriqs/gf/local/imtime.pxd index f651ec54..c8490ca0 100644 --- a/pytriqs/gf/local/imtime.pxd +++ b/pytriqs/gf/local/imtime.pxd @@ -49,7 +49,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_imtime & operator [](int) discrete_mesh & mesh() - cdef gf_block_imtime make_gf_block_imtime "triqs::gfs::make_block_gf_view_from_vector>" (vector[gf_imtime] &) + cdef gf_block_imtime make_gf_block_imtime "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" (vector[gf_imtime] &) #cdef gf_block_imtime make_gf_block_imtime "triqs::gfs::make_gf_view>" ( vector[gf_imtime] &) cdef gf_block_imtime as_gf_block_imtime (G) except + diff --git a/pytriqs/gf/local/legendre.pxd b/pytriqs/gf/local/legendre.pxd index 23ba9172..28643c54 100644 --- a/pytriqs/gf/local/legendre.pxd +++ b/pytriqs/gf/local/legendre.pxd @@ -46,7 +46,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_legendre & operator [](int) discrete_mesh & mesh() - cdef gf_block_legendre make_gf_block_legendre "triqs::gfs::make_block_gf_view_from_vector>" (vector[gf_legendre] &) + cdef gf_block_legendre make_gf_block_legendre "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" (vector[gf_legendre] &) #cdef gf_block_legendre make_gf_block_legendre "triqs::gfs::make_gf_view>" ( vector[gf_legendre] &) cdef gf_block_legendre as_gf_block_legendre (G) except + diff --git a/pytriqs/gf/local/refreq.pxd b/pytriqs/gf/local/refreq.pxd index 05c6ae5c..016bf22c 100644 --- a/pytriqs/gf/local/refreq.pxd +++ b/pytriqs/gf/local/refreq.pxd @@ -48,7 +48,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_refreq & operator [](int) discrete_mesh & mesh() - cdef gf_block_refreq make_gf_block_refreq "triqs::gfs::make_block_gf_view_from_vector>" (vector[gf_refreq] &) + cdef gf_block_refreq make_gf_block_refreq "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" (vector[gf_refreq] &) #cdef gf_block_refreq make_gf_block_refreq "triqs::gfs::make_gf_view>" ( vector[gf_refreq] &) cdef gf_block_refreq as_gf_block_refreq (G) except + diff --git a/pytriqs/gf/local/retime.pxd b/pytriqs/gf/local/retime.pxd index 8d3288a5..2b696964 100644 --- a/pytriqs/gf/local/retime.pxd +++ b/pytriqs/gf/local/retime.pxd @@ -48,7 +48,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_retime & operator [](int) discrete_mesh & mesh() - cdef gf_block_retime make_gf_block_retime "triqs::gfs::make_block_gf_view_from_vector>" (vector[gf_retime] &) + cdef gf_block_retime make_gf_block_retime "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" (vector[gf_retime] &) #cdef gf_block_retime make_gf_block_retime "triqs::gfs::make_gf_view>" ( vector[gf_retime] &) cdef gf_block_retime as_gf_block_retime (G) except + diff --git a/pytriqs/gf/local/two_real_times.pxd b/pytriqs/gf/local/two_real_times.pxd index 1be1ec7d..27fbd795 100644 --- a/pytriqs/gf/local/two_real_times.pxd +++ b/pytriqs/gf/local/two_real_times.pxd @@ -51,7 +51,7 @@ cdef extern from "triqs/gfs/block.hpp" namespace "triqs::gfs" : gf_two_real_times & operator [](int) discrete_mesh & mesh() - cdef gf_block_two_real_times make_gf_block_two_real_times "triqs::gfs::make_block_gf_view_from_vector>" ( vector[gf_two_real_times] &) + cdef gf_block_two_real_times make_gf_block_two_real_times "triqs::gfs::make_block_gf_view_from_vector_of_cython_proxy>" ( vector[gf_two_real_times] &) #cdef gf_block_two_real_times make_gf_block_two_real_times "triqs::gfs::make_gf_view>" ( vector[gf_two_real_times] &) cdef gf_block_two_real_times as_gf_block_two_real_times (G) except + diff --git a/test/triqs/gfs/block.cpp b/test/triqs/gfs/block.cpp index 58ac7bac..e56074d4 100644 --- a/test/triqs/gfs/block.cpp +++ b/test/triqs/gfs/block.cpp @@ -1,75 +1,88 @@ #define TRIQS_ARRAYS_ENFORCE_BOUNDCHECK -#include +#include using namespace triqs::gfs; using namespace triqs; -#define TEST(X) std::cout << BOOST_PP_STRINGIZE((X)) << " ---> "<< (X) < " << (X) << std::endl << std::endl; int main() { try { - double beta =1; - auto G1 = gf ({beta, Fermion}, {2,2}); + double beta = 1; + auto G1 = gf({beta, Fermion}, {2, 2}); auto G2 = G1; auto G3 = G2; // construct some block functions - auto B0 = block_gf (3); + auto B0 = block_gf(3); - auto B1 = make_block_gf (3, G1); - auto B2 = make_block_gf ({G1,G1,G1}); - auto B3 = make_block_gf ({"a","b","c"}, {G1,G1,G1}); - auto B4 = block_gf (1); + auto B1 = make_block_gf(3, G1); + auto B2 = make_block_gf({G1, G1, G1}); + auto B3 = make_block_gf({"a", "b", "c"}, {G1, G1, G1}); + auto B4 = block_gf(1); - // test hdf5 + // test hdf5 { - H5::H5File file("ess_gf.h5", H5F_ACC_TRUNC ); - h5_write(file, "B3", B3); + H5::H5File file("ess_gf.h5", H5F_ACC_TRUNC); + h5_write(file, "B3", B3); } { - H5::H5File file("ess_gf.h5", H5F_ACC_RDONLY); - std::cout << "B4 mesh" << B4.mesh().size()< b_; clef::placeholder<1> om_; - B1[b_][om_] << b_ / ( om_ + 2); + B1[b_][om_] << b_ / (om_ + 2); - // does not work - //std::vector> green_v; - //green_v.emplace_back({beta, Fermion}, {2,2} ); + auto B11 = B1; + B1[b_](om_) << B11[b_](om_) * B1[b_](om_) * B11[b_](om_); + + // does not work + // std::vector> green_v; + // green_v.emplace_back({beta, Fermion}, {2,2} ); + + // test reinterpretation + // compile only, add more test here + auto gs1 = gf({beta, Fermion}); + auto bgs = make_block_gf(3, gs1); + auto bg = reinterpret_scalar_valued_gf_as_matrix_valued(bgs); } -TRIQS_CATCH_AND_ABORT; + TRIQS_CATCH_AND_ABORT; } diff --git a/test/triqs/gfs/block.output b/test/triqs/gfs/block.output index 4cabd634..541ecaec 100644 --- a/test/triqs/gfs/block.output +++ b/test/triqs/gfs/block.output @@ -1,11 +1,11 @@ B4 mesh1 B4 mesh3 Number of blocks 3 -(G1( 0)) ---> +(G1(0)) ---> [[(20,0),(0,0)] [(0,0),(20,0)]] -(G1( 0)) ---> +(G1(0)) ---> [[(3.2,0),(0,0)] [(0,0),(3.2,0)]] diff --git a/triqs/clef/clef.hpp b/triqs/clef/clef.hpp index 217552f2..69bc9f3a 100644 --- a/triqs/clef/clef.hpp +++ b/triqs/clef/clef.hpp @@ -139,19 +139,21 @@ namespace triqs { namespace clef { // a little function to clean the reference_wrapper template U _cl(U && x) { return std::forward(x);} - template U & _cl(std::reference_wrapper x) { return x.get();} + template auto _cl(std::reference_wrapper x) DECL_AND_RETURN(x.get()); /// Terminal template<> struct operation { template L operator()(L&& l) const { return std::forward(l);} }; /// Function call - template<> struct operation { - template auto operator()(F const & f, Args const & ... args) const DECL_AND_RETURN(_cl(f)(_cl(args)...)); + template<> struct operation { + template + auto operator()(F&& f, Args&&... args) const DECL_AND_RETURN(_cl(std::forward(f))(_cl(std::forward(args))...)); }; /// [ ] Call template<> struct operation { - template auto operator()(F const & f, Args const & args) const DECL_AND_RETURN(_cl(f)[_cl(args)]); + template + auto operator()(F&& f, Args&& args) const DECL_AND_RETURN(_cl(std::forward(f))[_cl(std::forward(args))]); }; // all binary operators.... @@ -228,7 +230,7 @@ namespace triqs { namespace clef { template struct operation2; template struct operation2 { template - expr::type ...> operator()(Args && ... args) const { + expr::type ...> operator()(Args && ... args) const { return {Tag(), std::forward(args)...}; } }; diff --git a/triqs/gfs/block.hpp b/triqs/gfs/block.hpp index 97838c49..ce0d6598 100644 --- a/triqs/gfs/block.hpp +++ b/triqs/gfs/block.hpp @@ -153,10 +153,37 @@ namespace gfs { // return { gf_mesh {int(V.size())}, std::move(V), nothing{}, nothing{} } ; } - template gf_view make_block_gf_view_from_vector(std::vector V) { + template gf_view make_block_gf_view_from_vector(std::vector V) { return {{int(V.size())}, std::move(V), nothing{}, nothing{}}; } + // for cython proxy only. do not document. + template gf_view make_block_gf_view_from_vector_of_cython_proxy(std::vector V) { + return {{int(V.size())}, std::move(V), nothing{}, nothing{}}; + } + + // ------------------------------- Extend reinterpret_scalar_valued_gf_as_matrix_valued for block gf ------ + + template + gf_view, Opt2, IsConst> + reinterpret_scalar_valued_gf_as_matrix_valued(gf_view, Opt2, IsConst> bg) { + std::vector> V; + for (auto &g : bg) V.push_back(reinterpret_scalar_valued_gf_as_matrix_valued(g)); + return make_block_gf_view_from_vector(std::move(V)); + } + + template + gf_const_view, Opt2> + reinterpret_scalar_valued_gf_as_matrix_valued(gf, Opt2> const &bg) { + return reinterpret_scalar_valued_gf_as_matrix_valued(bg()); + } + + template + gf_view, Opt2> + reinterpret_scalar_valued_gf_as_matrix_valued(gf, Opt2> &bg) { + return reinterpret_scalar_valued_gf_as_matrix_valued(bg()); + } + // ------------------------------- Free functions -------------------------------------------------- // a simple function to get the number of blocks @@ -165,17 +192,19 @@ namespace gfs { // ------------------------------- an iterator over the blocks -------------------------------------------------- + template using __get_target = typename std::remove_reference()[0])>::type; + // iterator - template + template class block_gf_iterator - : public boost::iterator_facade, Target, boost::forward_traversal_tag, Target &> { + : public boost::iterator_facade, __get_target, boost::forward_traversal_tag, __get_target &> { friend class boost::iterator_core_access; - typedef gf_impl big_gf_t; + typedef typename std::remove_reference::type big_gf_t; big_gf_t &big_gf; typedef typename big_gf_t::mesh_t::const_iterator mesh_iterator_t; mesh_iterator_t mesh_it; - Target &dereference() const { return big_gf[*mesh_it]; } + __get_target &dereference() const { return big_gf[*mesh_it]; } bool equal(block_gf_iterator const &other) const { return ((mesh_it == other.mesh_it)); } public: @@ -186,27 +215,27 @@ namespace gfs { //------------ template - block_gf_iterator begin(gf_impl &bgf) { + block_gf_iterator> begin(gf_impl &bgf) { return {bgf, false}; } //------------ template - block_gf_iterator end(gf_impl &bgf) { + block_gf_iterator> end(gf_impl &bgf) { return {bgf, true}; } //----- const iterator - template - class block_gf_const_iterator : public boost::iterator_facade, Target, - boost::forward_traversal_tag, Target const &> { + template + class block_gf_const_iterator + : public boost::iterator_facade, __get_target, boost::forward_traversal_tag, __get_target const &> { friend class boost::iterator_core_access; - typedef gf_impl big_gf_t; + typedef typename std::remove_reference::type big_gf_t; big_gf_t const &big_gf; typedef typename big_gf_t::mesh_t::const_iterator mesh_iterator_t; mesh_iterator_t mesh_it; - Target const &dereference() const { return big_gf[*mesh_it]; } + __get_target const &dereference() const { return big_gf[*mesh_it]; } bool equal(block_gf_const_iterator const &other) const { return ((mesh_it == other.mesh_it)); } public: @@ -216,22 +245,22 @@ namespace gfs { }; template - block_gf_const_iterator begin(gf_impl const &bgf) { + block_gf_const_iterator> begin(gf_impl const &bgf) { return {bgf, false}; } template - block_gf_const_iterator end(gf_impl const &bgf) { + block_gf_const_iterator> end(gf_impl const &bgf) { return {bgf, true}; } template - block_gf_const_iterator cbegin(gf_impl const &bgf) { + block_gf_const_iterator> cbegin(gf_impl const &bgf) { return {bgf, false}; } template - block_gf_const_iterator cend(gf_impl const &bgf) { + block_gf_const_iterator> cend(gf_impl const &bgf) { return {bgf, true}; } } diff --git a/triqs/gfs/gf.hpp b/triqs/gfs/gf.hpp index f2ef8953..53b32262 100644 --- a/triqs/gfs/gf.hpp +++ b/triqs/gfs/gf.hpp @@ -546,7 +546,7 @@ namespace triqs { namespace gfs { } // a scalar_valued gf can be viewed as a 1x1 matrix - template + template gf_view reinterpret_scalar_valued_gf_as_matrix_valued(gf_view g) { typedef typename gf_view::data_view_t a_t; @@ -554,12 +554,12 @@ namespace triqs { namespace gfs { return {g.mesh(), a, g.singularity(), g.symmetry()}; } - template + template gf_view reinterpret_scalar_valued_gf_as_matrix_valued(gf &g) { return reinterpret_scalar_valued_gf_as_matrix_valued(g()); } - template + template gf_const_view reinterpret_scalar_valued_gf_as_matrix_valued(gf const &g) { return reinterpret_scalar_valued_gf_as_matrix_valued(g()); @@ -574,6 +574,8 @@ namespace triqs { namespace gfs { namespace gfs_implementation { // implement some default traits // ------------------------- default factories --------------------- + + // ----- tensor_valued template struct factories, Opt> { typedef gf, Opt> gf_t; typedef tqa::mini_vector target_shape_t; @@ -590,6 +592,7 @@ namespace triqs { namespace gfs { } }; + // ----- matrix_valued template struct factories { typedef gf gf_t; typedef tqa::mini_vector target_shape_t; @@ -606,6 +609,7 @@ namespace triqs { namespace gfs { } }; + // ----- scalar_valued template struct factories { typedef gf gf_t; struct target_shape_t {