#pragma once #include <algorithm> #include <numeric> #include <type_traits> /* * Some simple wrappers around stl algorithms to improve readability of code * that uses them. * * For example, a simple sum() wrapper for finding the sum of a container, * is much more readable than using std::accumulate() * */ namespace nest { namespace mc { namespace algorithms{ template <typename C> typename C::value_type sum(C const& c) { using value_type = typename C::value_type; return std::accumulate(c.begin(), c.end(), value_type{0}); } template <typename C> typename C::value_type mean(C const& c) { return sum(c)/c.size(); } template <typename C> C make_index(C const& c) { static_assert( std::is_integral<typename C::value_type>::value, "make_index only applies to integral types" ); C out(c.size()+1); out[0] = 0; std::partial_sum(c.begin(), c.end(), out.begin()+1); return out; } /// works like std::is_sorted(), but with stronger condition that succesive /// elements must be greater than those before them template <typename C> bool is_strictly_monotonic_increasing(C const& c) { using value_type = typename C::value_type; return std::is_sorted( c.begin(), c.end(), [] (value_type const& lhs, value_type const& rhs) { return lhs <= rhs; } ); } template <typename C> bool is_strictly_monotonic_decreasing(C const& c) { using value_type = typename C::value_type; return std::is_sorted( c.begin(), c.end(), [] (value_type const& lhs, value_type const& rhs) { return lhs >= rhs; } ); } template < typename C, typename = typename std::enable_if<std::is_integral<typename C::value_type>::value> > bool is_minimal_degree(C const& c) { static_assert( std::is_integral<typename C::value_type>::value, "is_minimal_degree only applies to integral types" ); using value_type = typename C::value_type; auto i = value_type(0); for(auto v : c) { if(i++<v) { return false; } } return true; } template <typename C> bool is_positive(C const& c) { static_assert( std::is_integral<typename C::value_type>::value, "is_positive only applies to integral types" ); for(auto v : c) { if(v<1) { return false; } } return true; } } // namespace algorithms } // namespace mc } // namespace nest