comparison src/statistics.hpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:add35537fdbb
1 // Copyright 2011, Ian Hobson.
2 //
3 // This file is part of gpsynth.
4 //
5 // gpsynth is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // gpsynth is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with gpsynth in the file COPYING.
17 // If not, see http://www.gnu.org/licenses/.
18
19 // Some useful stats functions
20
21 #pragma once
22
23 #include "range.hpp"
24 #include "std_ex.hpp"
25
26 #include <algorithm>
27 #include <iterator>
28 #include <numeric>
29 #include <sstream>
30 #include <stdexcept>
31
32 namespace stats {
33
34 // Sum
35 template<typename Iterator>
36 typename std::iterator_traits<Iterator>::value_type Sum(Iterator start,
37 Iterator end) {
38 typename std::iterator_traits<Iterator>::value_type initializer(0);
39 return std::accumulate(start, end, initializer);
40 }
41
42 // Sum - container
43 template<typename Container>
44 typename Container::value_type Sum(const Container& container) {
45 return Sum(container.begin(), container.end());
46 }
47
48 // Mean
49 template<typename Iterator>
50 typename std::iterator_traits<Iterator>::value_type Mean(Iterator start,
51 Iterator end) {
52 return Sum(start, end) / std::distance(start, end);
53 }
54
55 // Mean - container
56 template<typename Container>
57 typename Container::value_type Mean(const Container& container) {
58 return Mean(container.begin(), container.end());
59 }
60
61 // measures the MSE between a range and a target
62 template<typename Iterator1, typename Iterator2>
63 typename std::iterator_traits<Iterator1>::value_type
64 MeanSquaredError(Iterator1 start1, Iterator1 end1, Iterator2 start2) {
65 typedef typename std::iterator_traits<Iterator1>::value_type Value;
66 Value n = std::distance(start1, end1);
67 Value error(0);
68 while (start1 != end1) {
69 error += std::pow(*start1 - *start2, Value(2));
70 ++start1;
71 ++start2;
72 }
73 return error / n;
74 }
75
76 // MeanSquaredError - container adaptor
77 template<typename Container>
78 typename Container::value_type MeanSquaredError(const Container& x,
79 const Container& y) {
80 return MeanSquaredError(x.begin(), x.end(), y.begin());
81 }
82
83 // root mean square error
84 template<typename Iterator1, typename Iterator2>
85 double RMSE(Iterator1 start, Iterator1 end, Iterator2 target) {
86 return std::sqrt(MeanSquaredError(start, end, target));
87 }
88
89 // normalized root mean square error, using precomputed minima and maxima
90 template<typename Iterator1, typename Iterator2, typename T>
91 T NRMSE(Iterator1 start, Iterator1 end, Iterator2 target,
92 const stdx::Range<T>& range1, const stdx::Range<T>& range2) {
93 T range = std::max(range1.Maximum(), range2.Maximum())
94 - std::min(range1.Minimum(), range2.Minimum());
95 return RMSE(start, end, target) / range;
96 }
97
98 // Takes a set of numbers with sum <= 1 which define a distribution.
99 // operator() returns index chosen randomly with distribution defined by the
100 // provided probabilites.
101 // if the probabilites have sum < 1 then the difference is taken to imply a
102 // single additional index
103 // e.g. given:
104 // ProbabilitySelector selector(boost::assign::list_of(0.1)(0.8));
105 // selector() will yield
106 // '0' 10%,
107 // '1' 80%,
108 // '2' 10%
109 class ProbabilitySelector {
110 std::vector<double> boundaries_;
111
112 public:
113 ProbabilitySelector() {}
114 ProbabilitySelector(const std::vector<double>& probabilities)
115 {
116 SetProbabilities(probabilities);
117 }
118
119 void SetProbabilities(const std::vector<double>& probabilities) {
120 if (std::count_if(probabilities.begin(), probabilities.end(),
121 stdx::LessThan<double>(0.0))) {
122 throw std::runtime_error("ProbabilitySelector: negative value found");
123 }
124 // assign range boundaries
125 std::partial_sum(probabilities.begin(), probabilities.end(),
126 std::back_inserter(boundaries_));
127 }
128
129 std::size_t operator()() const {
130 double random = rand() / static_cast<double>(RAND_MAX);
131 std::vector<double>::const_iterator index;
132 index = std::upper_bound(boundaries_.begin(), boundaries_.end(), random);
133 return std::distance(boundaries_.begin(), index);
134 }
135
136 bool Initialized() const { return !boundaries_.empty(); }
137 };
138
139 } // stats namespace