SigUtil  0.95
Utility modules for modern C++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
basic_statistics.hpp
Go to the documentation of this file.
1 /*
2 Copyrightrandom_unique_numbers 2014 Akihiro Nishimura
3 
4 This software is released under the MIT License.
5 http://opensource.org/licenses/mit-license.php
6 */
7 
8 #ifndef SIG_UTIL_STATIC_UTIL_HPP
9 #define SIG_UTIL_STATIC_UTIL_HPP
10 
11 #include "../calculation/for_each.hpp"
12 
14 
15 namespace sig
16 {
17 
19 
34 template <class R = void, class C = void>
35 auto sum(C const& data)
37 {
39 
40  return std::accumulate(std::begin(data), std::end(data), static_cast<RT>(0), std::plus<RT>{});
41 }
42 
44 
58 template <class R = void, class C = void, class Pred = void>
59 auto sum(C const& data, Pred const& access_func)
61 {
62  using T = typename impl::container_traits<C>::value_type;
64 
65  return std::accumulate(std::begin(data), std::end(data), static_cast<RT>(0), [&](RT sum, T const& e){ return sum + access_func(e); });
66 }
67 
69 
83 template <class R = void, class CC = void>
84 auto sum_row(CC const& matrix, uint index)
85 {
86  assert(index < matrix.size());
87  return sum<R>(matrix[index]);
88 }
89 
91 
105 template <class R = void, class CC = void>
106 auto sum_col(CC const& matrix, uint index)
107 {
108  using T = typename impl::container_traits<CC>::value_type;
109 
110  return sum<R>(matrix, [index](T const& row){ assert(index < row.size()); return row[index]; });
111 }
112 
113 
115 
130 template <class R = void, class C = void>
131 auto product(C const& data)
133 {
135 
136  return std::accumulate(std::begin(data), std::end(data), static_cast<RT>(1), std::multiplies<RT>{});
137 }
138 
140 
154 template <class R = void, class C = void, class Pred = void>
155 auto product(C const& data, Pred const& access_func)
157 {
158  using T = typename impl::container_traits<C>::value_type;
160 
161  return std::accumulate(std::begin(data), std::end(data), static_cast<RT>(1), [&](RT sum, T const& e){ return sum * access_func(e); });
162 }
163 
165 
179 template <class R = void, class CC = void>
180 auto product_row(CC const& matrix, uint index)
181 {
182  assert(index < matrix.size());
183  return product<R>(matrix[index]);
184 }
185 
187 
201 template <class R = void, class CC = void>
202 auto product_col(CC const& matrix, uint index)
203 {
204  using T = typename impl::container_traits<CC>::value_type;
205 
206  return product<R>(matrix, [index](T const& row){ assert(index < row.size()); return row[index]; });
207 }
208 
209 
211 
222 template <class C>
223 double average(C const& data)
224 {
225  return static_cast<double>(sum<double>(data)) / data.size();
226 }
227 
229 
240 template <class C>
241 double variance(C const& data)
242 {
243  using T = typename impl::container_traits<C>::value_type;
244 
245  double mean = average(data);
246  return std::accumulate(std::begin(data), std::end(data), 0.0, [mean](double sum, T e){ return sum + std::pow(e - mean, 2); }) / data.size();
247 }
248 
250 
265 template <class C, typename std::enable_if<std::is_floating_point<typename impl::container_traits<C>::value_type>::value>::type*& = enabler>
266 bool normalize(C& data)
267 {
268  using T = typename impl::container_traits<C>::value_type;
269 
270  T min = *std::begin(data);
271  T max = *std::begin(data);
272 
273  for (auto e : data){
274  if (e < min) min = e;
275  else if (e > max) max = e;
276  }
277  T diff = max - min;
278  for_each([min, max, diff](T& e){ e = (e - min) / (diff); }, data);
279 
280  return true;
281 }
282 
284 
302 template <class R = double, class C = void>
303 auto normalize(C const& data, int dummy = 0)
304  ->typename impl::container_traits<C>::template rebind<R>
305 {
306  using RT = typename impl::container_traits<C>::template rebind<R>;
307 
308  auto result = sig::copy<RT>(data);
309  normalize(result);
310 
311  return result;
312 }
313 
315 
330 template <class C, typename std::enable_if<std::is_floating_point<typename impl::container_traits<C>::value_type>::value>::type*& = enabler>
331 bool standardize(C& data)
332 {
333  using T = typename impl::container_traits<C>::value_type;
334 
335  double mean = average(data);
336  double var = variance(data);
337 
338  for_each([mean, var](T& e){ e = (e - mean) / var; }, data);
339 
340  return true;
341 }
342 
344 
362 template <class R = double, class C = void>
363 auto standardize(C const& data, int dummy = 0)
364  ->typename impl::container_traits<C>::template rebind<R>
365 {
366  using RT = typename impl::container_traits<C>::template rebind<R>;
367 
368  auto result = sig::copy<RT>(data);
369  standardize(result);
370 
371  return result;
372 }
373 
375 
391 template <class C,
392  typename std::enable_if<std::is_floating_point<typename impl::container_traits<C>::value_type>::value>::type*& = enabler
393 >
394 bool normalize_dist(C& data)
395 {
396  double sum = sig::sum(data);
397  for (auto& e : data) e /= sum;
398 
399  return true;
400 }
401 
403 
421 template <class R = double, class C = void>
422 auto normalize_dist(C const& data, int dummy = 0)
423  ->typename impl::container_traits<C>::template rebind<R>
424 {
425  using RT = typename impl::container_traits<C>::template rebind<R>;
426 
427  auto result = sig::copy<RT>(data);
428  normalize_dist(result);
429 
430  return result;
431 }
432 
433 }
434 
435 #endif
void for_each(F &&func, Cs &&...containers)
複数コンテナを反復処理
Definition: for_each.hpp:46
auto sum_row(CC const &matrix, uint index)
行列の指定行の総和
bool normalize(C &data)
正規化(Normalization)
auto end(C &&c) -> std::move_iterator< typename RC::iterator >
void * enabler
auto product_row(CC const &matrix, uint index)
行列の指定行の総乗
double variance(C const &data)
分散
double average(C const &data)
平均
auto product_col(CC const &matrix, uint index)
行列の指定列の総乗
auto min(T v) -> T
auto max(T v) -> T
bool standardize(C &data)
標準化(Standardization)
auto sum_col(CC const &matrix, uint index)
行列の指定列の総和
auto product(C const &data) -> typename impl::SameIf< R, void, typename impl::container_traits< C >::value_type, R >::type
総乗
Definition: array.hpp:15
bool normalize_dist(C &data)
確率分布の正規化
auto sum(C const &data) -> typename impl::SameIf< R, void, typename impl::container_traits< C >::value_type, R >::type
総和
auto begin(C &&c) -> std::move_iterator< typename RC::iterator >