PageRenderTime 36ms CodeModel.GetById 13ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/accumulators/numeric/functional/valarray.hpp

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