/******************************************************************************* * * TRIQS: a Toolbox for Research in Interacting Quantum Systems * * Copyright (C) 2011-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 . * ******************************************************************************/ #ifndef TRIQS_ARRAYS_INDEXMAP_CUBOID_DOMAIN_H #define TRIQS_ARRAYS_INDEXMAP_CUBOID_DOMAIN_H #include "../common.hpp" #include "../range.hpp" #include "./mem_layout.hpp" #include #include "../../impl/exceptions.hpp" #include #include #include #include #include #include namespace triqs { namespace arrays { namespace indexmaps { namespace cuboid { using namespace triqs::arrays::permutations; /// Standard hyper_rectangular domain for arrays template class domain_t { typedef mini_vector n_uple; n_uple lengths_; friend class boost::serialization::access; template void serialize(Archive & ar, const unsigned int version) { ar & boost::serialization::make_nvp("dimensions",lengths_);} public : static constexpr unsigned int rank = Rank; typedef n_uple index_value_type; domain_t () =default; domain_t (const domain_t & C) = default; domain_t (domain_t && C) { *this = std::move(C);} friend void swap( domain_t & a, domain_t & b) { swap(a.lengths_,b.lengths_);} domain_t & operator =( domain_t const &) = default; domain_t & operator =( domain_t && x) { swap(*this,x); return *this;} domain_t (n_uple lengths):lengths_(std::move(lengths)) {} domain_t (mini_vector const & lengths):lengths_(lengths) {} domain_t (std::vector const & l):lengths_() { if (!(l.size()==Rank)) TRIQS_RUNTIME_ERROR << "cuboid domain_t construction : vector size incorrect : got "< domain_t(size_t i0, T... t): lengths_(i0, t...){} size_t number_of_elements() const { return lengths_.product_of_elements();} bool operator==(domain_t const & X) const { return this->lengths_ == X.lengths_;} bool operator!=(domain_t const & X) const { return !(*this==X);} n_uple const & lengths() const & { return lengths_;} n_uple lengths() && { return lengths_;} /** Generates the value of the indices of a cuboid_domain. */ static constexpr ull_t iteration_order_default = permutations::identity(Rank); template class gal_generator { typedef index_value_type indices_type; const domain_t * dom; indices_type indices_tuple; bool atend; public: gal_generator (const domain_t & P, bool atEnd=false): dom(&P), atend(atEnd) {} bool operator==(const gal_generator & IT2) const { assert((IT2.dom == dom)); return ((IT2.atend==atend) );} bool operator!=(const gal_generator & IT2) const { return (!operator==(IT2));} indices_type const & operator *() const { return indices_tuple;} explicit operator bool () const { return !atend;} gal_generator & operator++(){ assert(!atend); atend = advance_impl(std::integral_constant()); return *this;} private: template bool advance_impl(std::integral_constant) { constexpr int p = permutations::apply(IterationOrder, r); if (indices_tuple[p] < dom->lengths()[p]-1) { ++(indices_tuple[p]); return false;} indices_tuple[p] = 0; return advance_impl(std::integral_constant()); } bool advance_impl(std::integral_constant) { return true;} }; typedef gal_generator<> generator; generator begin() const { return generator(*this,false);} generator end() const { return generator(*this,true);} /* End of generator */ // Check that key in in the domain template void assert_key_in_domain(KeyType const & key) const { std::stringstream fs; bool res = key_check_impl(std::integral_constant(), key,this->lengths_,fs); if (!res) TRIQS_ARRAYS_KEY_ERROR << " key out of domain \n" < bool key_check_impl (std::integral_constant, KeyType const & key, n_uple const & L, std::stringstream & fs ) const { //bool cond = ( ( size_t(key[r]) < L[r])); bool cond = ( ( size_t(std::get(key)) < L[r])); //if (!cond) fs << "key ["<(), key,L,fs) && cond; } template bool key_check_impl (std::integral_constant, KeyType const &, n_uple const &, std::stringstream &) const { return true;} // Check that key in in the domain : variadic form. No need for speed optimisation here, it is just for debug template void assert_key_in_domain_v (Args const & ... args) const { assert_key_in_domain( std::make_tuple(args...));} friend std::ostream & operator<<(std::ostream & out, domain_t const & x){return out<<"Cuboid of rank "< void foreach(domain_t const & dom, FntType F) {\ BOOST_PP_REPEAT(RR,AUX0,BOOST_PP_DEC(RR))\ mini_vector t;\ const mini_vector l(dom.lengths());\ BOOST_PP_REPEAT(RR,AUX1,nil){ F(BOOST_PP_REPEAT(RR,AUX3,nil)); }} BOOST_PP_REPEAT_FROM_TO(1,ARRAY_NRANK_MAX , IMPL, nil); #undef IMPL #undef AUX0 #undef AUX1 #undef AUX3 } /// ------------ Pretty Printing : specializing the default behaviour for d=1,2 ------------------------- namespace PrettyPrint_details { template struct print_impl { std::ostream & out; A const & a; print_impl( std::ostream & out_, A const & a_) : out(out_), a(a_){} template void operator()(A0 const & a0, Args const & ... args) const { out << a(a0,args...)<< " ";} void print() const { out<<"["; indexmaps::cuboid::foreach (a.domain(), std::cref(*this)); //foreach(a, std::cref(*this)); out<<"]"; } }; template struct print_impl <1,A> { std::ostream & out; A const & a; print_impl( std::ostream & out_, A const & a_) : out(out_), a(a_){} void print() const { auto d = a.indexmap().domain(); out<<"["; for (size_t i=0; i< d.lengths()[0]; ++i) out<<(i>0 ? ",": "")< struct print_impl <2,A> { std::ostream & out; A const & a; print_impl( std::ostream & out_, A const & a_) : out(out_), a(a_){} void print() const { auto d = a.indexmap().domain(); out<<"\n["; for (size_t i=0; i< d.lengths()[0]; ++i) { out<<(i==0 ? "[" : " ["); for (size_t j=0; j< d.lengths()[1]; ++j) out<<(j>0 ? ",": "")< void pretty_print (std::ostream & out, A const & a ) { PrettyPrint_details::print_impl(out,a).print();} } template indexmaps::cuboid::domain_t make_cuboid_domain(U ... u) { return {size_t(u)...};} //cuboid_array_domain make_cuboid_domain(U ... u) { return {u...};} typedef indexmaps::cuboid::domain_t<2> matrix_shape_t; typedef indexmaps::cuboid::domain_t<1> vector_shape_t; }} #endif