Mercurial > hg > gpsynth
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 |