-
Notifications
You must be signed in to change notification settings - Fork 63
/
unumeric.h
151 lines (137 loc) · 4.32 KB
/
unumeric.h
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <[email protected]>
// This file is free software, distributed under the MIT License.
#pragma once
namespace ustl {
/// Returns the sum of all elements in [first, last) added to \p init.
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename T>
inline T accumulate (InputIterator first, InputIterator last, T init)
{
while (first < last)
init += *first++;
return (init);
}
/// Returns the sum of all elements in [first, last) via \p op, added to \p init.
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename T, typename BinaryFunction>
inline T accumulate (InputIterator first, InputIterator last, T init, BinaryFunction binary_op)
{
while (first < last)
init = binary_op (init, *first++);
return (init);
}
/// Assigns range [value, value + (last - first)) to [first, last)
/// \ingroup NumericAlgorithms
///
template <typename ForwardIterator, typename T>
inline void iota (ForwardIterator first, ForwardIterator last, T value)
{
while (first < last)
*first++ = value++;
}
/// Returns the sum of products of respective elements in the given ranges.
/// \ingroup NumericAlgorithms
///
template <typename InputIterator1, typename InputIterator2, typename T>
inline T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init)
{
while (first1 < last1)
init += *first1++ * *first2++;
return (init);
}
/// Returns the sum of products of respective elements in the given ranges.
/// \ingroup NumericAlgorithms
///
template <typename InputIterator1, typename InputIterator2, typename T,
typename BinaryOperation1, typename BinaryOperation2>
inline T inner_product
(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init,
BinaryOperation1 sumOp, BinaryOperation2 productOp)
{
while (first1 < last1)
init = sumOp (init, productOp (*first1++, *first2++));
return (init);
}
/// Writes result such that result[i] = sum (first...first+i)
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename OutputIterator>
inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result)
{
if (first < last)
*result = *first++;
while (first < last)
*++result = *first++ + *result;
return (result);
}
/// Writes result such that result[i] = sumOp (first...first+i)
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename OutputIterator, typename BinaryOperation>
inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation sumOp)
{
if (first < last)
*result = *first++;
while (first < last)
*++result = sumOp (*first++, *result);
return (result);
}
/// Writes result such that result[i] = first[i] - first[i - 1]
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename OutputIterator>
inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result)
{
if (first < last)
*result++ = *first++;
while (first < last)
*result++ = *first - *(first - 1);
return (result);
}
/// Writes result such that result[i] = differenceOp (first[i], first[i - 1])
/// \ingroup NumericAlgorithms
///
template <typename InputIterator, typename OutputIterator, typename BinaryOperation>
inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation differenceOp)
{
if (first < last)
*result++ = *first++;
while (first < last)
*result++ = differenceOp (*first, *(first - 1));
return (result);
}
/// \brief Returns x^n.
/// Donald Knuth's Russian Peasant algorithm.
/// \ingroup NumericAlgorithms
///
template <typename T>
inline T power (T x, unsigned n)
{
T result (n % 2 ? x : 1);
while (n /= 2) {
x *= x;
if (n % 2)
result *= x;
}
return (result);
}
/// \brief Returns x^n, using \p op instead of multiplication.
/// Donald Knuth's Russian Peasant algorithm.
/// \ingroup NumericAlgorithms
///
template <typename T, typename BinaryOperation>
inline T power (T x, unsigned n, BinaryOperation op)
{
T result (n % 2 ? x : 1);
while (n /= 2) {
x = op (x, x);
if (n % 2)
result = op (result, x);
}
return (result);
}
} // namespace ustl