Statistics
| Revision:

root / tmp / org.txm.statsengine.r.core.win32 / res / win32 / library / BH / include / boost / accumulators / numeric / functional / vector.hpp @ 2486

History | View | Annotate | Download (12.1 kB)

1
///////////////////////////////////////////////////////////////////////////////
2
/// \file vector.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_VECTOR_HPP_EAN_12_12_2005
9
#define BOOST_NUMERIC_FUNCTIONAL_VECTOR_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 <vector>
16
#include <functional>
17
#include <boost/assert.hpp>
18
#include <boost/mpl/and.hpp>
19
#include <boost/mpl/not.hpp>
20
#include <boost/utility/enable_if.hpp>
21
#include <boost/type_traits/is_same.hpp>
22
#include <boost/type_traits/is_scalar.hpp>
23
#include <boost/type_traits/remove_const.hpp>
24
#include <boost/typeof/std/vector.hpp>
25
#include <boost/accumulators/numeric/functional_fwd.hpp>
26

    
27
namespace boost { namespace numeric
28
{
29
    namespace operators
30
    {
31
        namespace acc_detail
32
        {
33
            template<typename Fun>
34
            struct make_vector
35
            {
36
                typedef std::vector<typename Fun::result_type> type;
37
            };
38
        }
39

    
40
        ///////////////////////////////////////////////////////////////////////////////
41
        // Handle vector<Left> / Right where Right is a scalar.
42
        template<typename Left, typename Right>
43
        typename lazy_enable_if<
44
            is_scalar<Right>
45
          , acc_detail::make_vector<functional::divides<Left, Right> >
46
        >::type
47
        operator /(std::vector<Left> const &left, Right const &right)
48
        {
49
            typedef typename functional::divides<Left, Right>::result_type value_type;
50
            std::vector<value_type> result(left.size());
51
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
52
            {
53
                result[i] = numeric::divides(left[i], right);
54
            }
55
            return result;
56
        }
57

    
58
        ///////////////////////////////////////////////////////////////////////////////
59
        // Handle vector<Left> / vector<Right>.
60
        template<typename Left, typename Right>
61
        std::vector<typename functional::divides<Left, Right>::result_type>
62
        operator /(std::vector<Left> const &left, std::vector<Right> const &right)
63
        {
64
            typedef typename functional::divides<Left, Right>::result_type value_type;
65
            std::vector<value_type> result(left.size());
66
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
67
            {
68
                result[i] = numeric::divides(left[i], right[i]);
69
            }
70
            return result;
71
        }
72

    
73
        ///////////////////////////////////////////////////////////////////////////////
74
        // Handle vector<Left> * Right where Right is a scalar.
75
        template<typename Left, typename Right>
76
        typename lazy_enable_if<
77
            is_scalar<Right>
78
          , acc_detail::make_vector<functional::multiplies<Left, Right> >
79
        >::type
80
        operator *(std::vector<Left> const &left, Right const &right)
81
        {
82
            typedef typename functional::multiplies<Left, Right>::result_type value_type;
83
            std::vector<value_type> result(left.size());
84
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
85
            {
86
                result[i] = numeric::multiplies(left[i], right);
87
            }
88
            return result;
89
        }
90

    
91
        ///////////////////////////////////////////////////////////////////////////////
92
        // Handle Left * vector<Right> where Left is a scalar.
93
        template<typename Left, typename Right>
94
        typename lazy_enable_if<
95
            is_scalar<Left>
96
          , acc_detail::make_vector<functional::multiplies<Left, Right> >
97
        >::type
98
        operator *(Left const &left, std::vector<Right> const &right)
99
        {
100
            typedef typename functional::multiplies<Left, Right>::result_type value_type;
101
            std::vector<value_type> result(right.size());
102
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
103
            {
104
                result[i] = numeric::multiplies(left, right[i]);
105
            }
106
            return result;
107
        }
108

    
109
        ///////////////////////////////////////////////////////////////////////////////
110
        // Handle vector<Left> * vector<Right>
111
        template<typename Left, typename Right>
112
        std::vector<typename functional::multiplies<Left, Right>::result_type>
113
        operator *(std::vector<Left> const &left, std::vector<Right> const &right)
114
        {
115
            typedef typename functional::multiplies<Left, Right>::result_type value_type;
116
            std::vector<value_type> result(left.size());
117
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
118
            {
119
                result[i] = numeric::multiplies(left[i], right[i]);
120
            }
121
            return result;
122
        }
123

    
124
        ///////////////////////////////////////////////////////////////////////////////
125
        // Handle vector<Left> + vector<Right>
126
        template<typename Left, typename Right>
127
        std::vector<typename functional::plus<Left, Right>::result_type>
128
        operator +(std::vector<Left> const &left, std::vector<Right> const &right)
129
        {
130
            typedef typename functional::plus<Left, Right>::result_type value_type;
131
            std::vector<value_type> result(left.size());
132
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
133
            {
134
                result[i] = numeric::plus(left[i], right[i]);
135
            }
136
            return result;
137
        }
138

    
139
        ///////////////////////////////////////////////////////////////////////////////
140
        // Handle vector<Left> - vector<Right>
141
        template<typename Left, typename Right>
142
        std::vector<typename functional::minus<Left, Right>::result_type>
143
        operator -(std::vector<Left> const &left, std::vector<Right> const &right)
144
        {
145
            typedef typename functional::minus<Left, Right>::result_type value_type;
146
            std::vector<value_type> result(left.size());
147
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
148
            {
149
                result[i] = numeric::minus(left[i], right[i]);
150
            }
151
            return result;
152
        }
153

    
154
        ///////////////////////////////////////////////////////////////////////////////
155
        // Handle vector<Left> += vector<Left>
156
        template<typename Left>
157
        std::vector<Left> &
158
        operator +=(std::vector<Left> &left, std::vector<Left> const &right)
159
        {
160
            BOOST_ASSERT(left.size() == right.size());
161
            for(std::size_t i = 0, size = left.size(); i != size; ++i)
162
            {
163
                numeric::plus_assign(left[i], right[i]);
164
            }
165
            return left;
166
        }
167

    
168
        ///////////////////////////////////////////////////////////////////////////////
169
        // Handle -vector<Arg>
170
        template<typename Arg>
171
        std::vector<typename functional::unary_minus<Arg>::result_type>
172
        operator -(std::vector<Arg> const &arg)
173
        {
174
            typedef typename functional::unary_minus<Arg>::result_type value_type;
175
            std::vector<value_type> result(arg.size());
176
            for(std::size_t i = 0, size = result.size(); i != size; ++i)
177
            {
178
                result[i] = numeric::unary_minus(arg[i]);
179
            }
180
            return result;
181
        }
182
    }
183

    
184
    namespace functional
185
    {
186
        struct std_vector_tag;
187

    
188
        template<typename T, typename Al>
189
        struct tag<std::vector<T, Al> >
190
        {
191
            typedef std_vector_tag type;
192
        };
193

    
194
        ///////////////////////////////////////////////////////////////////////////////
195
        // element-wise min of std::vector
196
        template<typename Left, typename Right>
197
        struct min_assign<Left, Right, std_vector_tag, std_vector_tag>
198
          : std::binary_function<Left, Right, void>
199
        {
200
            void operator ()(Left &left, Right &right) const
201
            {
202
                BOOST_ASSERT(left.size() == right.size());
203
                for(std::size_t i = 0, size = left.size(); i != size; ++i)
204
                {
205
                    if(numeric::less(right[i], left[i]))
206
                    {
207
                        left[i] = right[i];
208
                    }
209
                }
210
            }
211
        };
212

    
213
        ///////////////////////////////////////////////////////////////////////////////
214
        // element-wise max of std::vector
215
        template<typename Left, typename Right>
216
        struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
217
          : std::binary_function<Left, Right, void>
218
        {
219
            void operator ()(Left &left, Right &right) const
220
            {
221
                BOOST_ASSERT(left.size() == right.size());
222
                for(std::size_t i = 0, size = left.size(); i != size; ++i)
223
                {
224
                    if(numeric::greater(right[i], left[i]))
225
                    {
226
                        left[i] = right[i];
227
                    }
228
                }
229
            }
230
        };
231

    
232
        // partial specialization for std::vector.
233
        template<typename Left, typename Right>
234
        struct fdiv<Left, Right, std_vector_tag, void>
235
          : mpl::if_<
236
                are_integral<typename Left::value_type, Right>
237
              , divides<Left, double const>
238
              , divides<Left, Right>
239
            >::type
240
        {};
241

    
242
        // promote
243
        template<typename To, typename From>
244
        struct promote<To, From, std_vector_tag, std_vector_tag>
245
          : std::unary_function<From, To>
246
        {
247
            To operator ()(From &arr) const
248
            {
249
                typename remove_const<To>::type res(arr.size());
250
                for(std::size_t i = 0, size = arr.size(); i != size; ++i)
251
                {
252
                    res[i] = numeric::promote<typename To::value_type>(arr[i]);
253
                }
254
                return res;
255
            }
256
        };
257

    
258
        template<typename ToFrom>
259
        struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
260
          : std::unary_function<ToFrom, ToFrom>
261
        {
262
            ToFrom &operator ()(ToFrom &tofrom) const
263
            {
264
                return tofrom;
265
            }
266
        };
267

    
268
        ///////////////////////////////////////////////////////////////////////////////
269
        // functional::as_min
270
        template<typename T>
271
        struct as_min<T, std_vector_tag>
272
          : std::unary_function<T, typename remove_const<T>::type>
273
        {
274
            typename remove_const<T>::type operator ()(T &arr) const
275
            {
276
                return 0 == arr.size()
277
                  ? T()
278
                  : T(arr.size(), numeric::as_min(arr[0]));
279
            }
280
        };
281

    
282
        ///////////////////////////////////////////////////////////////////////////////
283
        // functional::as_max
284
        template<typename T>
285
        struct as_max<T, std_vector_tag>
286
          : std::unary_function<T, typename remove_const<T>::type>
287
        {
288
            typename remove_const<T>::type operator ()(T &arr) const
289
            {
290
                return 0 == arr.size()
291
                  ? T()
292
                  : T(arr.size(), numeric::as_max(arr[0]));
293
            }
294
        };
295

    
296
        ///////////////////////////////////////////////////////////////////////////////
297
        // functional::as_zero
298
        template<typename T>
299
        struct as_zero<T, std_vector_tag>
300
          : std::unary_function<T, typename remove_const<T>::type>
301
        {
302
            typename remove_const<T>::type operator ()(T &arr) const
303
            {
304
                return 0 == arr.size()
305
                  ? T()
306
                  : T(arr.size(), numeric::as_zero(arr[0]));
307
            }
308
        };
309

    
310
        ///////////////////////////////////////////////////////////////////////////////
311
        // functional::as_one
312
        template<typename T>
313
        struct as_one<T, std_vector_tag>
314
          : std::unary_function<T, typename remove_const<T>::type>
315
        {
316
            typename remove_const<T>::type operator ()(T &arr) const
317
            {
318
                return 0 == arr.size()
319
                  ? T()
320
                  : T(arr.size(), numeric::as_one(arr[0]));
321
            }
322
        };
323

    
324
    } // namespace functional
325

    
326
}} // namespace boost::numeric
327

    
328
#endif
329