STL ALGO NUMERIC

Five typical Numeric algorithm

In <stl_numeric.h>

These algorithms all provide two function version, the one is naive/nature operation, and the other is user-defined operation passed by functor.

STL REQUIRES which you can ignore, when read source code. So I just commented out these statements.

__VALUE_TYPE which can find in “stl_iterator_base.h”

Accumulate

If you want to get the sum of [first, last), you should set init with zero.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class _InputIterator, class _Tp>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{

//__STL_REQUIRES(_InputIterator, _InputIterator);
for ( ; __first != __last; ++__first)
__init = __init + *__first;
return __init;
}


template <class _InputIterator, class _Tp, class _BinaryOperation>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
_BinaryOperation __binary_op)

{

//__STL_REQUIRES(_InputIterator, _InputIterator);
for ( ; __first != __last; ++__first)
__init = __binary_op(__init, *__first);
return __init;
}

Inner Product

In the second version, you can also define + and * when you calculate inner product.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
template <class _InputIterator1, class _InputIterator2, class _Tp>
_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init)

{

// __STL_REQUIRES(_InputIterator2, _InputIterator);
// __STL_REQUIRES(_InputIterator2, _InputIterator);
for ( ; __first1 != __last1; ++__first1, ++__first2)
__init = __init + (*__first1 * *__first2);
return __init;
}


template <class _InputIterator1, class _InputIterator2, class _Tp,
class _BinaryOperation1, class _BinaryOperation2>
_Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _Tp __init,
_BinaryOperation1 __binary_op1,
_BinaryOperation2 __binary_op2)

{

// __STL_REQUIRES(_InputIterator2, _InputIterator);
// __STL_REQUIRES(_InputIterator2, _InputIterator);
for ( ; __first1 != __last1; ++__first1, ++__first2)
__init = __binary_op1(__init, __binary_op2(*__first1, *__first2));
return __init;
}

Partial Sum

This function return local sum, e.g.

1
2
3
4
v[0] = v[0]
v[1] = v[0] + v[1]
v[2] = v[0] + v[1] + v[2]
...

return the next of last one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
template <class _InputIterator, class _OutputIterator, class _Tp>
_OutputIterator
__partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*)
{
_Tp __value = *__first;
while (++__first != __last) {
__value = __value + *__first;
*++__result = __value;
}
return ++__result;
}

template <class _InputIterator, class _OutputIterator>
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)

{

// __STL_REQUIRES(_InputIterator, _InputIterator);
// __STL_REQUIRES(_OutputIterator, _OutputIterator);
if (__first == __last) return __result;
*__result = *__first;
return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first));
}


template <class _InputIterator, class _OutputIterator, class _Tp,
class _BinaryOperation>
_OutputIterator
__partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*, _BinaryOperation __binary_op)
{
_Tp __value = *__first;
while (++__first != __last) {
__value = __binary_op(__value, *__first);
*++__result = __value;
}
return ++__result;
}

template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator
partial_sum(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)

{

// __STL_REQUIRES(_InputIterator, _InputIterator);
// __STL_REQUIRES(_OutputIterator, _OutputIterator);
if (__first == __last) return __result;
*__result = *__first;
return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first),
__binary_op);
}

Adjacent Difference

This function return difference between adjacent elements, e.g.

1
2
3
4
v[0] = v[1] - v[0]
v[1] = v[2] - v[1]
v[2] = v[3] - v[2]
...

return the next of last one

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
template <class _InputIterator, class _OutputIterator, class _Tp>
_OutputIterator
__adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*)
{
_Tp __value = *__first;
while (++__first != __last) {
_Tp __tmp = *__first;
*++__result = __tmp - __value;
__value = __tmp;
}
return ++__result;
}

template <class _InputIterator, class _OutputIterator>
_OutputIterator
adjacent_difference(_InputIterator __first,
_InputIterator __last, _OutputIterator __result)

{

// __STL_REQUIRES(_InputIterator, _InputIterator);
// __STL_REQUIRES(_OutputIterator, _OutputIterator);
if (__first == __last) return __result;
*__result = *__first;
return __adjacent_difference(__first, __last, __result,
__VALUE_TYPE(__first));
}


template <class _InputIterator, class _OutputIterator, class _Tp,
class _BinaryOperation>
_OutputIterator
__adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Tp*,
_BinaryOperation __binary_op) {
_Tp __value = *__first;
while (++__first != __last) {
_Tp __tmp = *__first;
*++__result = __binary_op(__tmp, __value);
__value = __tmp;
}
return ++__result;
}

template <class _InputIterator, class _OutputIterator, class _BinaryOperation>
_OutputIterator
adjacent_difference(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryOperation __binary_op)

{

// __STL_REQUIRES(_InputIterator, _InputIterator);
// __STL_REQUIRES(_OutputIterator, _OutputIterator);
if (__first == __last) return __result;
*__result = *__first;
return __adjacent_difference(__first, __last, __result,
__VALUE_TYPE(__first),
__binary_op);
}

Power

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
template <class _Tp, class _Integer, class _MonoidOperation>
_Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr)
{
if (__n == 0)
return identity_element(__opr); //which can find in <stl_function.h>
else {
// when even number
while ((__n & 1) == 0) {
__n >>= 1;
__x = __opr(__x, __x);
}
//
_Tp __result = __x;
__n >>= 1;
while (__n != 0) {
__x = __opr(__x, __x);
if ((__n & 1) != 0)
__result = __opr(__result, __x);
__n >>= 1;
}
return __result;
}
}

template <class _Tp, class _Integer>
inline _Tp __power(_Tp __x, _Integer __n)
{
return __power(__x, __n, multiplies<_Tp>());
}

// Alias for the internal name __power. Note that power is an extension,
// not part of the C++ standard.

template <class _Tp, class _Integer, class _MonoidOperation>
inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr)
{

return __power(__x, __n, __opr);
}

template <class _Tp, class _Integer>
inline _Tp power(_Tp __x, _Integer __n)
{

return __power(__x, __n);
}

Additional

iota is not part of the C++ standard. It is an extension.

Itoa

The function can generate a sequence which in ascending order.

1
2
3
4
5
6
7
8
9
template <class _ForwardIter, class _Tp>
void
iota(_ForwardIter __first, _ForwardIter __last, _Tp __value)
{

// __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator);
// __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type);
while (__first != __last)
*__first++ = __value++;
}

Contents
  1. 1. Five typical Numeric algorithm
    1. 1.1. Accumulate
    2. 1.2. Inner Product
    3. 1.3. Partial Sum
    4. 1.4. Adjacent Difference
    5. 1.5. Power
  2. 2. Additional
    1. 2.1. Itoa