annotate DEPENDENCIES/generic/include/boost/accumulators/numeric/functional/valarray.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 /// \file valarray.hpp
Chris@16 3 ///
Chris@16 4 // Copyright 2005 Eric Niebler. Distributed under the Boost
Chris@16 5 // Software License, Version 1.0. (See accompanying file
Chris@16 6 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7
Chris@16 8 #ifndef BOOST_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
Chris@16 9 #define BOOST_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
Chris@16 10
Chris@16 11 #ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
Chris@16 12 # error Include this file before boost/accumulators/numeric/functional.hpp
Chris@16 13 #endif
Chris@16 14
Chris@16 15 #include <valarray>
Chris@16 16 #include <functional>
Chris@16 17 #include <boost/assert.hpp>
Chris@16 18 #include <boost/mpl/and.hpp>
Chris@16 19 #include <boost/mpl/not.hpp>
Chris@16 20 #include <boost/mpl/assert.hpp>
Chris@16 21 #include <boost/utility/enable_if.hpp>
Chris@16 22 #include <boost/type_traits/is_same.hpp>
Chris@16 23 #include <boost/type_traits/is_scalar.hpp>
Chris@16 24 #include <boost/type_traits/remove_const.hpp>
Chris@16 25 #include <boost/typeof/std/valarray.hpp>
Chris@16 26 #include <boost/accumulators/numeric/functional_fwd.hpp>
Chris@16 27
Chris@16 28 namespace boost { namespace numeric
Chris@16 29 {
Chris@16 30 namespace operators
Chris@16 31 {
Chris@16 32 namespace acc_detail
Chris@16 33 {
Chris@16 34 template<typename Fun>
Chris@16 35 struct make_valarray
Chris@16 36 {
Chris@16 37 typedef std::valarray<typename Fun::result_type> type;
Chris@16 38 };
Chris@16 39 }
Chris@16 40
Chris@16 41 ///////////////////////////////////////////////////////////////////////////////
Chris@16 42 // Handle valarray<Left> / Right where Right is a scalar and Right != Left.
Chris@16 43 template<typename Left, typename Right>
Chris@16 44 typename lazy_enable_if<
Chris@16 45 mpl::and_<is_scalar<Right>, mpl::not_<is_same<Left, Right> > >
Chris@16 46 , acc_detail::make_valarray<functional::divides<Left, Right> >
Chris@16 47 >::type
Chris@16 48 operator /(std::valarray<Left> const &left, Right const &right)
Chris@16 49 {
Chris@16 50 typedef typename functional::divides<Left, Right>::result_type value_type;
Chris@16 51 std::valarray<value_type> result(left.size());
Chris@16 52 for(std::size_t i = 0, size = result.size(); i != size; ++i)
Chris@16 53 {
Chris@16 54 result[i] = numeric::divides(left[i], right);
Chris@16 55 }
Chris@16 56 return result;
Chris@16 57 }
Chris@16 58
Chris@16 59 ///////////////////////////////////////////////////////////////////////////////
Chris@16 60 // Handle valarray<Left> * Right where Right is a scalar and Right != Left.
Chris@16 61 template<typename Left, typename Right>
Chris@16 62 typename lazy_enable_if<
Chris@16 63 mpl::and_<is_scalar<Right>, mpl::not_<is_same<Left, Right> > >
Chris@16 64 , acc_detail::make_valarray<functional::multiplies<Left, Right> >
Chris@16 65 >::type
Chris@16 66 operator *(std::valarray<Left> const &left, Right const &right)
Chris@16 67 {
Chris@16 68 typedef typename functional::multiplies<Left, Right>::result_type value_type;
Chris@16 69 std::valarray<value_type> result(left.size());
Chris@16 70 for(std::size_t i = 0, size = result.size(); i != size; ++i)
Chris@16 71 {
Chris@16 72 result[i] = numeric::multiplies(left[i], right);
Chris@16 73 }
Chris@16 74 return result;
Chris@16 75 }
Chris@16 76
Chris@16 77 ///////////////////////////////////////////////////////////////////////////////
Chris@16 78 // Handle valarray<Left> + valarray<Right> where Right != Left.
Chris@16 79 template<typename Left, typename Right>
Chris@16 80 typename lazy_disable_if<
Chris@16 81 is_same<Left, Right>
Chris@16 82 , acc_detail::make_valarray<functional::plus<Left, Right> >
Chris@16 83 >::type
Chris@16 84 operator +(std::valarray<Left> const &left, std::valarray<Right> const &right)
Chris@16 85 {
Chris@16 86 typedef typename functional::plus<Left, Right>::result_type value_type;
Chris@16 87 std::valarray<value_type> result(left.size());
Chris@16 88 for(std::size_t i = 0, size = result.size(); i != size; ++i)
Chris@16 89 {
Chris@16 90 result[i] = numeric::plus(left[i], right[i]);
Chris@16 91 }
Chris@16 92 return result;
Chris@16 93 }
Chris@16 94 }
Chris@16 95
Chris@16 96 namespace functional
Chris@16 97 {
Chris@16 98 struct std_valarray_tag;
Chris@16 99
Chris@16 100 template<typename T>
Chris@16 101 struct tag<std::valarray<T> >
Chris@16 102 {
Chris@16 103 typedef std_valarray_tag type;
Chris@16 104 };
Chris@16 105
Chris@16 106 #ifdef __GLIBCXX__
Chris@16 107 template<typename T, typename U>
Chris@16 108 struct tag<std::_Expr<T, U> >
Chris@16 109 {
Chris@16 110 typedef std_valarray_tag type;
Chris@16 111 };
Chris@16 112 #endif
Chris@16 113
Chris@16 114 /// INTERNAL ONLY
Chris@16 115 ///
Chris@16 116 // This is necessary because the GCC stdlib uses expression templates, and
Chris@16 117 // typeof(som-valarray-expression) is not an instance of std::valarray
Chris@16 118 #define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \
Chris@16 119 template<typename Left, typename Right> \
Chris@16 120 struct Name<Left, Right, std_valarray_tag, std_valarray_tag> \
Chris@16 121 : std::binary_function< \
Chris@16 122 Left \
Chris@16 123 , Right \
Chris@16 124 , std::valarray< \
Chris@16 125 typename Name< \
Chris@16 126 typename Left::value_type \
Chris@16 127 , typename Right::value_type \
Chris@16 128 >::result_type \
Chris@16 129 > \
Chris@16 130 > \
Chris@16 131 { \
Chris@16 132 typedef typename Left::value_type left_value_type; \
Chris@16 133 typedef typename Right::value_type right_value_type; \
Chris@16 134 typedef \
Chris@16 135 std::valarray< \
Chris@16 136 typename Name<left_value_type, right_value_type>::result_type \
Chris@16 137 > \
Chris@16 138 result_type; \
Chris@16 139 result_type \
Chris@16 140 operator ()(Left &left, Right &right) const \
Chris@16 141 { \
Chris@16 142 return numeric::promote<std::valarray<left_value_type> >(left) \
Chris@16 143 Op numeric::promote<std::valarray<right_value_type> >(right); \
Chris@16 144 } \
Chris@16 145 }; \
Chris@16 146 template<typename Left, typename Right> \
Chris@16 147 struct Name<Left, Right, std_valarray_tag, void> \
Chris@16 148 : std::binary_function< \
Chris@16 149 Left \
Chris@16 150 , Right \
Chris@16 151 , std::valarray< \
Chris@16 152 typename Name<typename Left::value_type, Right>::result_type \
Chris@16 153 > \
Chris@16 154 > \
Chris@16 155 { \
Chris@16 156 typedef typename Left::value_type left_value_type; \
Chris@16 157 typedef \
Chris@16 158 std::valarray< \
Chris@16 159 typename Name<left_value_type, Right>::result_type \
Chris@16 160 > \
Chris@16 161 result_type; \
Chris@16 162 result_type \
Chris@16 163 operator ()(Left &left, Right &right) const \
Chris@16 164 { \
Chris@16 165 return numeric::promote<std::valarray<left_value_type> >(left) Op right;\
Chris@16 166 } \
Chris@16 167 }; \
Chris@16 168 template<typename Left, typename Right> \
Chris@16 169 struct Name<Left, Right, void, std_valarray_tag> \
Chris@16 170 : std::binary_function< \
Chris@16 171 Left \
Chris@16 172 , Right \
Chris@16 173 , std::valarray< \
Chris@16 174 typename Name<Left, typename Right::value_type>::result_type \
Chris@16 175 > \
Chris@16 176 > \
Chris@16 177 { \
Chris@16 178 typedef typename Right::value_type right_value_type; \
Chris@16 179 typedef \
Chris@16 180 std::valarray< \
Chris@16 181 typename Name<Left, right_value_type>::result_type \
Chris@16 182 > \
Chris@16 183 result_type; \
Chris@16 184 result_type \
Chris@16 185 operator ()(Left &left, Right &right) const \
Chris@16 186 { \
Chris@16 187 return left Op numeric::promote<std::valarray<right_value_type> >(right);\
Chris@16 188 } \
Chris@16 189 };
Chris@16 190
Chris@16 191 BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(plus, +)
Chris@16 192 BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(minus, -)
Chris@16 193 BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(multiplies, *)
Chris@16 194 BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(divides, /)
Chris@16 195 BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(modulus, %)
Chris@16 196
Chris@16 197 #undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP
Chris@16 198
Chris@16 199 ///////////////////////////////////////////////////////////////////////////////
Chris@16 200 // element-wise min of std::valarray
Chris@16 201 template<typename Left, typename Right>
Chris@16 202 struct min_assign<Left, Right, std_valarray_tag, std_valarray_tag>
Chris@16 203 : std::binary_function<Left, Right, void>
Chris@16 204 {
Chris@16 205 void operator ()(Left &left, Right &right) const
Chris@16 206 {
Chris@16 207 BOOST_ASSERT(left.size() == right.size());
Chris@16 208 for(std::size_t i = 0, size = left.size(); i != size; ++i)
Chris@16 209 {
Chris@16 210 if(numeric::less(right[i], left[i]))
Chris@16 211 {
Chris@16 212 left[i] = right[i];
Chris@16 213 }
Chris@16 214 }
Chris@16 215 }
Chris@16 216 };
Chris@16 217
Chris@16 218 ///////////////////////////////////////////////////////////////////////////////
Chris@16 219 // element-wise max of std::valarray
Chris@16 220 template<typename Left, typename Right>
Chris@16 221 struct max_assign<Left, Right, std_valarray_tag, std_valarray_tag>
Chris@16 222 : std::binary_function<Left, Right, void>
Chris@16 223 {
Chris@16 224 void operator ()(Left &left, Right &right) const
Chris@16 225 {
Chris@16 226 BOOST_ASSERT(left.size() == right.size());
Chris@16 227 for(std::size_t i = 0, size = left.size(); i != size; ++i)
Chris@16 228 {
Chris@16 229 if(numeric::greater(right[i], left[i]))
Chris@16 230 {
Chris@16 231 left[i] = right[i];
Chris@16 232 }
Chris@16 233 }
Chris@16 234 }
Chris@16 235 };
Chris@16 236
Chris@16 237 // partial specialization of numeric::fdiv<> for std::valarray.
Chris@16 238 template<typename Left, typename Right, typename RightTag>
Chris@16 239 struct fdiv<Left, Right, std_valarray_tag, RightTag>
Chris@16 240 : mpl::if_<
Chris@16 241 are_integral<typename Left::value_type, Right>
Chris@16 242 , divides<Left, double const>
Chris@16 243 , divides<Left, Right>
Chris@16 244 >::type
Chris@16 245 {};
Chris@16 246
Chris@16 247 // promote
Chris@16 248 template<typename To, typename From>
Chris@16 249 struct promote<To, From, std_valarray_tag, std_valarray_tag>
Chris@16 250 : std::unary_function<From, To>
Chris@16 251 {
Chris@16 252 To operator ()(From &arr) const
Chris@16 253 {
Chris@16 254 typename remove_const<To>::type res(arr.size());
Chris@16 255 for(std::size_t i = 0, size = arr.size(); i != size; ++i)
Chris@16 256 {
Chris@16 257 res[i] = numeric::promote<typename To::value_type>(arr[i]);
Chris@16 258 }
Chris@16 259 return res;
Chris@16 260 }
Chris@16 261 };
Chris@16 262
Chris@16 263 template<typename ToFrom>
Chris@16 264 struct promote<ToFrom, ToFrom, std_valarray_tag, std_valarray_tag>
Chris@16 265 : std::unary_function<ToFrom, ToFrom>
Chris@16 266 {
Chris@16 267 ToFrom &operator ()(ToFrom &tofrom) const
Chris@16 268 {
Chris@16 269 return tofrom;
Chris@16 270 }
Chris@16 271 };
Chris@16 272
Chris@16 273 // for "promoting" a std::valarray<bool> to a bool, useful for
Chris@16 274 // comparing 2 valarrays for equality:
Chris@16 275 // if(numeric::promote<bool>(a == b))
Chris@16 276 template<typename From>
Chris@16 277 struct promote<bool, From, void, std_valarray_tag>
Chris@16 278 : std::unary_function<From, bool>
Chris@16 279 {
Chris@16 280 bool operator ()(From &arr) const
Chris@16 281 {
Chris@16 282 BOOST_MPL_ASSERT((is_same<bool, typename From::value_type>));
Chris@16 283 for(std::size_t i = 0, size = arr.size(); i != size; ++i)
Chris@16 284 {
Chris@16 285 if(!arr[i])
Chris@16 286 {
Chris@16 287 return false;
Chris@16 288 }
Chris@16 289 }
Chris@16 290 return true;
Chris@16 291 }
Chris@16 292 };
Chris@16 293
Chris@16 294 template<typename From>
Chris@16 295 struct promote<bool const, From, void, std_valarray_tag>
Chris@16 296 : promote<bool, From, void, std_valarray_tag>
Chris@16 297 {};
Chris@16 298
Chris@16 299 ///////////////////////////////////////////////////////////////////////////////
Chris@16 300 // functional::as_min
Chris@16 301 template<typename T>
Chris@16 302 struct as_min<T, std_valarray_tag>
Chris@16 303 : std::unary_function<T, typename remove_const<T>::type>
Chris@16 304 {
Chris@16 305 typename remove_const<T>::type operator ()(T &arr) const
Chris@16 306 {
Chris@16 307 return 0 == arr.size()
Chris@16 308 ? T()
Chris@16 309 : T(numeric::as_min(arr[0]), arr.size());
Chris@16 310 }
Chris@16 311 };
Chris@16 312
Chris@16 313 ///////////////////////////////////////////////////////////////////////////////
Chris@16 314 // functional::as_max
Chris@16 315 template<typename T>
Chris@16 316 struct as_max<T, std_valarray_tag>
Chris@16 317 : std::unary_function<T, typename remove_const<T>::type>
Chris@16 318 {
Chris@16 319 typename remove_const<T>::type operator ()(T &arr) const
Chris@16 320 {
Chris@16 321 return 0 == arr.size()
Chris@16 322 ? T()
Chris@16 323 : T(numeric::as_max(arr[0]), arr.size());
Chris@16 324 }
Chris@16 325 };
Chris@16 326
Chris@16 327 ///////////////////////////////////////////////////////////////////////////////
Chris@16 328 // functional::as_zero
Chris@16 329 template<typename T>
Chris@16 330 struct as_zero<T, std_valarray_tag>
Chris@16 331 : std::unary_function<T, typename remove_const<T>::type>
Chris@16 332 {
Chris@16 333 typename remove_const<T>::type operator ()(T &arr) const
Chris@16 334 {
Chris@16 335 return 0 == arr.size()
Chris@16 336 ? T()
Chris@16 337 : T(numeric::as_zero(arr[0]), arr.size());
Chris@16 338 }
Chris@16 339 };
Chris@16 340
Chris@16 341 ///////////////////////////////////////////////////////////////////////////////
Chris@16 342 // functional::as_one
Chris@16 343 template<typename T>
Chris@16 344 struct as_one<T, std_valarray_tag>
Chris@16 345 : std::unary_function<T, typename remove_const<T>::type>
Chris@16 346 {
Chris@16 347 typename remove_const<T>::type operator ()(T &arr) const
Chris@16 348 {
Chris@16 349 return 0 == arr.size()
Chris@16 350 ? T()
Chris@16 351 : T(numeric::as_one(arr[0]), arr.size());
Chris@16 352 }
Chris@16 353 };
Chris@16 354
Chris@16 355 } // namespace functional
Chris@16 356
Chris@16 357 }} // namespace boost::numeric
Chris@16 358
Chris@16 359 #endif
Chris@16 360