00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef MATH_ACCUMULATE_INCLUDE
00014 #define MATH_ACCUMULATE_INCLUDE
00015
00016 #include <concepts>
00017
00018 #include <boost/numeric/linear_algebra/identity.hpp>
00019 #include <boost/numeric/linear_algebra/new_concepts.hpp>
00020
00021 namespace math {
00022
00023
00024 template <std::InputIterator Iter, std::CopyConstructible Value, typename Op>
00025 requires std::Callable2<Op, Value, Value>
00026 && std::CopyAssignable<Value, std::Callable2<Op, Value, Value>::result_type>
00027 Value inline accumulate(Iter first, Iter last, Value init, Op op)
00028 {
00029
00030 for (; first != last; ++first)
00031 init= op(init, Value(*first));
00032 return init;
00033 }
00034
00035
00036 template <std::RandomAccessIterator Iter, std::CopyConstructible Value, typename Op>
00037 requires std::Callable2<Op, Value, Value>
00038 && std::CopyAssignable<Value, std::Callable2<Op, Value, Value>::result_type>
00039 && Commutative<Op, Value>
00040 && Monoid<Op, Value>
00041 && std::Convertible<Monoid<Op, Value>::identity_result_type, Value>
00042 Value inline accumulate(Iter first, Iter last, Value init, Op op)
00043 {
00044
00045 typedef typename std::RandomAccessIterator<Iter>::difference_type difference_type;
00046 Value t0= identity(op, init), t1= identity(op, init),
00047 t2= identity(op, init), t3= init;
00048 difference_type size= last - first, bsize= size >> 2 << 2, i;
00049
00050 for (i= 0; i < bsize; i+= 4) {
00051 t0= op(t0, Value(first[i]));
00052 t1= op(t1, Value(first[i+1]));
00053 t2= op(t2, Value(first[i+2]));
00054 t3= op(t3, Value(first[i+3]));
00055 }
00056 for (; i < size; i++)
00057 t0= op(t0, Value(first[i]));
00058
00059 t0= op(t0, t1), t2= op(t2, t3), t0= op(t0, t2);
00060 return t0;
00061 }
00062
00063 }
00064
00065 #endif // MATH_ACCUMULATE_INCLUDE