Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:19

0001 ///////////////////////////////////////////////////////////////////////////////
0002 /// \file vector.hpp
0003 ///
0004 //  Copyright 2005 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 
0008 #ifndef BOOST_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
0009 #define BOOST_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
0010 
0011 #ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
0012 # error Include this file before boost/accumulators/numeric/functional.hpp
0013 #endif
0014 
0015 #include <vector>
0016 #include <functional>
0017 #include <boost/assert.hpp>
0018 #include <boost/mpl/and.hpp>
0019 #include <boost/mpl/not.hpp>
0020 #include <boost/utility/enable_if.hpp>
0021 #include <boost/type_traits/is_same.hpp>
0022 #include <boost/type_traits/is_scalar.hpp>
0023 #include <boost/type_traits/remove_const.hpp>
0024 #include <boost/typeof/std/vector.hpp>
0025 #include <boost/accumulators/numeric/functional_fwd.hpp>
0026 
0027 namespace boost { namespace numeric
0028 {
0029     namespace operators
0030     {
0031         namespace acc_detail
0032         {
0033             template<typename Fun>
0034             struct make_vector
0035             {
0036                 typedef std::vector<typename Fun::result_type> type;
0037             };
0038         }
0039 
0040         ///////////////////////////////////////////////////////////////////////////////
0041         // Handle vector<Left> / Right where Right is a scalar.
0042         template<typename Left, typename Right>
0043         typename lazy_enable_if<
0044             is_scalar<Right>
0045           , acc_detail::make_vector<functional::divides<Left, Right> >
0046         >::type
0047         operator /(std::vector<Left> const &left, Right const &right)
0048         {
0049             typedef typename functional::divides<Left, Right>::result_type value_type;
0050             std::vector<value_type> result(left.size());
0051             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0052             {
0053                 result[i] = numeric::divides(left[i], right);
0054             }
0055             return result;
0056         }
0057 
0058         ///////////////////////////////////////////////////////////////////////////////
0059         // Handle vector<Left> / vector<Right>.
0060         template<typename Left, typename Right>
0061         std::vector<typename functional::divides<Left, Right>::result_type>
0062         operator /(std::vector<Left> const &left, std::vector<Right> const &right)
0063         {
0064             typedef typename functional::divides<Left, Right>::result_type value_type;
0065             std::vector<value_type> result(left.size());
0066             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0067             {
0068                 result[i] = numeric::divides(left[i], right[i]);
0069             }
0070             return result;
0071         }
0072 
0073         ///////////////////////////////////////////////////////////////////////////////
0074         // Handle vector<Left> * Right where Right is a scalar.
0075         template<typename Left, typename Right>
0076         typename lazy_enable_if<
0077             is_scalar<Right>
0078           , acc_detail::make_vector<functional::multiplies<Left, Right> >
0079         >::type
0080         operator *(std::vector<Left> const &left, Right const &right)
0081         {
0082             typedef typename functional::multiplies<Left, Right>::result_type value_type;
0083             std::vector<value_type> result(left.size());
0084             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0085             {
0086                 result[i] = numeric::multiplies(left[i], right);
0087             }
0088             return result;
0089         }
0090 
0091         ///////////////////////////////////////////////////////////////////////////////
0092         // Handle Left * vector<Right> where Left is a scalar.
0093         template<typename Left, typename Right>
0094         typename lazy_enable_if<
0095             is_scalar<Left>
0096           , acc_detail::make_vector<functional::multiplies<Left, Right> >
0097         >::type
0098         operator *(Left const &left, std::vector<Right> const &right)
0099         {
0100             typedef typename functional::multiplies<Left, Right>::result_type value_type;
0101             std::vector<value_type> result(right.size());
0102             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0103             {
0104                 result[i] = numeric::multiplies(left, right[i]);
0105             }
0106             return result;
0107         }
0108 
0109         ///////////////////////////////////////////////////////////////////////////////
0110         // Handle vector<Left> * vector<Right>
0111         template<typename Left, typename Right>
0112         std::vector<typename functional::multiplies<Left, Right>::result_type>
0113         operator *(std::vector<Left> const &left, std::vector<Right> const &right)
0114         {
0115             typedef typename functional::multiplies<Left, Right>::result_type value_type;
0116             std::vector<value_type> result(left.size());
0117             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0118             {
0119                 result[i] = numeric::multiplies(left[i], right[i]);
0120             }
0121             return result;
0122         }
0123 
0124         ///////////////////////////////////////////////////////////////////////////////
0125         // Handle vector<Left> + vector<Right>
0126         template<typename Left, typename Right>
0127         std::vector<typename functional::plus<Left, Right>::result_type>
0128         operator +(std::vector<Left> const &left, std::vector<Right> const &right)
0129         {
0130             typedef typename functional::plus<Left, Right>::result_type value_type;
0131             std::vector<value_type> result(left.size());
0132             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0133             {
0134                 result[i] = numeric::plus(left[i], right[i]);
0135             }
0136             return result;
0137         }
0138 
0139         ///////////////////////////////////////////////////////////////////////////////
0140         // Handle vector<Left> - vector<Right>
0141         template<typename Left, typename Right>
0142         std::vector<typename functional::minus<Left, Right>::result_type>
0143         operator -(std::vector<Left> const &left, std::vector<Right> const &right)
0144         {
0145             typedef typename functional::minus<Left, Right>::result_type value_type;
0146             std::vector<value_type> result(left.size());
0147             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0148             {
0149                 result[i] = numeric::minus(left[i], right[i]);
0150             }
0151             return result;
0152         }
0153 
0154         ///////////////////////////////////////////////////////////////////////////////
0155         // Handle vector<Left> += vector<Left>
0156         template<typename Left>
0157         std::vector<Left> &
0158         operator +=(std::vector<Left> &left, std::vector<Left> const &right)
0159         {
0160             BOOST_ASSERT(left.size() == right.size());
0161             for(std::size_t i = 0, size = left.size(); i != size; ++i)
0162             {
0163                 numeric::plus_assign(left[i], right[i]);
0164             }
0165             return left;
0166         }
0167 
0168         ///////////////////////////////////////////////////////////////////////////////
0169         // Handle -vector<Arg>
0170         template<typename Arg>
0171         std::vector<typename functional::unary_minus<Arg>::result_type>
0172         operator -(std::vector<Arg> const &arg)
0173         {
0174             typedef typename functional::unary_minus<Arg>::result_type value_type;
0175             std::vector<value_type> result(arg.size());
0176             for(std::size_t i = 0, size = result.size(); i != size; ++i)
0177             {
0178                 result[i] = numeric::unary_minus(arg[i]);
0179             }
0180             return result;
0181         }
0182     }
0183 
0184     namespace functional
0185     {
0186         struct std_vector_tag;
0187 
0188         template<typename T, typename Al>
0189         struct tag<std::vector<T, Al> >
0190         {
0191             typedef std_vector_tag type;
0192         };
0193 
0194         ///////////////////////////////////////////////////////////////////////////////
0195         // element-wise min of std::vector
0196         template<typename Left, typename Right>
0197         struct min_assign<Left, Right, std_vector_tag, std_vector_tag>
0198         {
0199             typedef Left first_argument_type;
0200             typedef Right second_argument_type;
0201             typedef void result_type;
0202 
0203             void operator ()(Left &left, Right &right) const
0204             {
0205                 BOOST_ASSERT(left.size() == right.size());
0206                 for(std::size_t i = 0, size = left.size(); i != size; ++i)
0207                 {
0208                     if(numeric::less(right[i], left[i]))
0209                     {
0210                         left[i] = right[i];
0211                     }
0212                 }
0213             }
0214         };
0215 
0216         ///////////////////////////////////////////////////////////////////////////////
0217         // element-wise max of std::vector
0218         template<typename Left, typename Right>
0219         struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
0220         {
0221             typedef Left first_argument_type;
0222             typedef Right second_argument_type;
0223             typedef void result_type;
0224 
0225             void operator ()(Left &left, Right &right) const
0226             {
0227                 BOOST_ASSERT(left.size() == right.size());
0228                 for(std::size_t i = 0, size = left.size(); i != size; ++i)
0229                 {
0230                     if(numeric::greater(right[i], left[i]))
0231                     {
0232                         left[i] = right[i];
0233                     }
0234                 }
0235             }
0236         };
0237 
0238         // partial specialization for std::vector.
0239         template<typename Left, typename Right>
0240         struct fdiv<Left, Right, std_vector_tag, void>
0241           : mpl::if_<
0242                 are_integral<typename Left::value_type, Right>
0243               , divides<Left, double const>
0244               , divides<Left, Right>
0245             >::type
0246         {};
0247 
0248         // promote
0249         template<typename To, typename From>
0250         struct promote<To, From, std_vector_tag, std_vector_tag>
0251         {
0252             typedef From argument_type;
0253             typedef To result_type;
0254 
0255             To operator ()(From &arr) const
0256             {
0257                 typename remove_const<To>::type res(arr.size());
0258                 for(std::size_t i = 0, size = arr.size(); i != size; ++i)
0259                 {
0260                     res[i] = numeric::promote<typename To::value_type>(arr[i]);
0261                 }
0262                 return res;
0263             }
0264         };
0265 
0266         template<typename ToFrom>
0267         struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
0268         {
0269             typedef ToFrom argument_type;
0270             typedef ToFrom result_type;
0271 
0272             ToFrom &operator ()(ToFrom &tofrom) const
0273             {
0274                 return tofrom;
0275             }
0276         };
0277 
0278         ///////////////////////////////////////////////////////////////////////////////
0279         // functional::as_min
0280         template<typename T>
0281         struct as_min<T, std_vector_tag>
0282         {
0283             typedef T argument_type;
0284             typedef typename remove_const<T>::type result_type;
0285 
0286             typename remove_const<T>::type operator ()(T &arr) const
0287             {
0288                 return 0 == arr.size()
0289                   ? T()
0290                   : T(arr.size(), numeric::as_min(arr[0]));
0291             }
0292         };
0293 
0294         ///////////////////////////////////////////////////////////////////////////////
0295         // functional::as_max
0296         template<typename T>
0297         struct as_max<T, std_vector_tag>
0298         {
0299             typedef T argument_type;
0300             typedef typename remove_const<T>::type result_type;
0301 
0302             typename remove_const<T>::type operator ()(T &arr) const
0303             {
0304                 return 0 == arr.size()
0305                   ? T()
0306                   : T(arr.size(), numeric::as_max(arr[0]));
0307             }
0308         };
0309 
0310         ///////////////////////////////////////////////////////////////////////////////
0311         // functional::as_zero
0312         template<typename T>
0313         struct as_zero<T, std_vector_tag>
0314         {
0315             typedef T argument_type;
0316             typedef typename remove_const<T>::type result_type;
0317 
0318             typename remove_const<T>::type operator ()(T &arr) const
0319             {
0320                 return 0 == arr.size()
0321                   ? T()
0322                   : T(arr.size(), numeric::as_zero(arr[0]));
0323             }
0324         };
0325 
0326         ///////////////////////////////////////////////////////////////////////////////
0327         // functional::as_one
0328         template<typename T>
0329         struct as_one<T, std_vector_tag>
0330         {
0331             typedef T argument_type;
0332             typedef typename remove_const<T>::type result_type;
0333 
0334             typename remove_const<T>::type operator ()(T &arr) const
0335             {
0336                 return 0 == arr.size()
0337                   ? T()
0338                   : T(arr.size(), numeric::as_one(arr[0]));
0339             }
0340         };
0341 
0342     } // namespace functional
0343 
0344 }} // namespace boost::numeric
0345 
0346 #endif
0347