2809 |
06 Aug 12 |
peter |
1 |
#ifndef _theplu_yat_statistics_average_base |
2809 |
06 Aug 12 |
peter |
2 |
#define _theplu_yat_statistics_average_base |
2809 |
06 Aug 12 |
peter |
3 |
|
2809 |
06 Aug 12 |
peter |
// $Id$ |
2809 |
06 Aug 12 |
peter |
5 |
|
2809 |
06 Aug 12 |
peter |
6 |
/* |
2809 |
06 Aug 12 |
peter |
Copyright (C) 2012 Peter Johansson |
2809 |
06 Aug 12 |
peter |
8 |
|
2809 |
06 Aug 12 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
2809 |
06 Aug 12 |
peter |
10 |
|
2809 |
06 Aug 12 |
peter |
The yat library is free software; you can redistribute it and/or |
2809 |
06 Aug 12 |
peter |
modify it under the terms of the GNU General Public License as |
2809 |
06 Aug 12 |
peter |
published by the Free Software Foundation; either version 3 of the |
2809 |
06 Aug 12 |
peter |
License, or (at your option) any later version. |
2809 |
06 Aug 12 |
peter |
15 |
|
2809 |
06 Aug 12 |
peter |
The yat library is distributed in the hope that it will be useful, |
2809 |
06 Aug 12 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
2809 |
06 Aug 12 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2809 |
06 Aug 12 |
peter |
General Public License for more details. |
2809 |
06 Aug 12 |
peter |
20 |
|
2809 |
06 Aug 12 |
peter |
You should have received a copy of the GNU General Public License |
2809 |
06 Aug 12 |
peter |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
2809 |
06 Aug 12 |
peter |
23 |
*/ |
2809 |
06 Aug 12 |
peter |
24 |
|
2809 |
06 Aug 12 |
peter |
25 |
#include <boost/concept_check.hpp> |
2809 |
06 Aug 12 |
peter |
26 |
|
2809 |
06 Aug 12 |
peter |
27 |
#include <cmath> |
2809 |
06 Aug 12 |
peter |
28 |
#include <limits> |
2809 |
06 Aug 12 |
peter |
29 |
|
2809 |
06 Aug 12 |
peter |
30 |
namespace theplu { |
2809 |
06 Aug 12 |
peter |
31 |
namespace yat { |
2809 |
06 Aug 12 |
peter |
32 |
namespace statistics { |
2809 |
06 Aug 12 |
peter |
33 |
|
2809 |
06 Aug 12 |
peter |
34 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Base class for averager classes |
2809 |
06 Aug 12 |
peter |
36 |
|
2809 |
06 Aug 12 |
peter |
This is a base class templated on the derived class (see |
2809 |
06 Aug 12 |
peter |
curiously recurring template pattern), which implies there is no |
2809 |
06 Aug 12 |
peter |
dynamic polymorphism but the concrete type must be decided at |
2809 |
06 Aug 12 |
peter |
compile time. |
2809 |
06 Aug 12 |
peter |
41 |
|
2809 |
06 Aug 12 |
peter |
The derived class, \c MyClass, needs to have the following features: |
2809 |
06 Aug 12 |
peter |
- \c <a href=http://www.sgi.com/tech/stl/DefaultConstructible.html> |
2809 |
06 Aug 12 |
peter |
DefaultConstructible</a> |
2809 |
06 Aug 12 |
peter |
- \c <a href=\boost_url/utility/Assignable.html> Assignable</a> |
2809 |
06 Aug 12 |
peter |
- \c a function add_impl(double, long int) |
2809 |
06 Aug 12 |
peter |
- \c a function rescale_impl(double) |
2809 |
06 Aug 12 |
peter |
48 |
|
2809 |
06 Aug 12 |
peter |
These two functions need to be public or if you dont want to |
2809 |
06 Aug 12 |
peter |
expose them to the world, make them private and declare \c |
2809 |
06 Aug 12 |
peter |
averager_base<Derived> as friend. |
2809 |
06 Aug 12 |
peter |
52 |
|
2809 |
06 Aug 12 |
peter |
A derived class is typically declared as |
2809 |
06 Aug 12 |
peter |
54 |
|
2809 |
06 Aug 12 |
peter |
\code |
2809 |
06 Aug 12 |
peter |
class MyClass : public averager_base<MyClass> |
2809 |
06 Aug 12 |
peter |
57 |
{ |
2809 |
06 Aug 12 |
peter |
58 |
... |
2809 |
06 Aug 12 |
peter |
private: |
2809 |
06 Aug 12 |
peter |
friend class averager_base<MyClass>; |
2809 |
06 Aug 12 |
peter |
void add_impl(double, long int); |
2809 |
06 Aug 12 |
peter |
void rescale_impl(double); |
2809 |
06 Aug 12 |
peter |
63 |
}; |
2809 |
06 Aug 12 |
peter |
\endcode |
2809 |
06 Aug 12 |
peter |
65 |
|
2809 |
06 Aug 12 |
peter |
\since yat 0.9 |
2809 |
06 Aug 12 |
peter |
67 |
*/ |
2809 |
06 Aug 12 |
peter |
68 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
69 |
class averager_base |
2809 |
06 Aug 12 |
peter |
70 |
{ |
2809 |
06 Aug 12 |
peter |
71 |
public: |
2809 |
06 Aug 12 |
peter |
72 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Constructor |
2809 |
06 Aug 12 |
peter |
74 |
*/ |
2809 |
06 Aug 12 |
peter |
75 |
averager_base(void) : n_(0), mean_(0) |
2809 |
06 Aug 12 |
peter |
76 |
{ |
2809 |
06 Aug 12 |
peter |
77 |
BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<Derived>)); |
2809 |
06 Aug 12 |
peter |
78 |
} |
2809 |
06 Aug 12 |
peter |
79 |
|
2809 |
06 Aug 12 |
peter |
80 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Destructor |
2809 |
06 Aug 12 |
peter |
82 |
*/ |
2809 |
06 Aug 12 |
peter |
83 |
virtual ~averager_base(void)=0; |
2809 |
06 Aug 12 |
peter |
84 |
|
2809 |
06 Aug 12 |
peter |
85 |
/** |
2809 |
06 Aug 12 |
peter |
\brief add a data point |
2809 |
06 Aug 12 |
peter |
87 |
|
2809 |
06 Aug 12 |
peter |
Adding \a n number of data point(s) with value \a x. |
2809 |
06 Aug 12 |
peter |
89 |
*/ |
2809 |
06 Aug 12 |
peter |
90 |
void add(double x, long n=1) {static_cast<Derived*>(this)->add_impl(x, n);} |
2809 |
06 Aug 12 |
peter |
91 |
|
2809 |
06 Aug 12 |
peter |
92 |
/** |
2809 |
06 Aug 12 |
peter |
\brief mean |
2809 |
06 Aug 12 |
peter |
94 |
|
2809 |
06 Aug 12 |
peter |
\return %Mean of presented data, \f$ \frac{1}{n}\sum x_i \f$ |
2809 |
06 Aug 12 |
peter |
96 |
*/ |
2809 |
06 Aug 12 |
peter |
97 |
double mean(void) const |
2809 |
06 Aug 12 |
peter |
98 |
{ return n_ ? mean_ : std::numeric_limits<double>::quiet_NaN(); } |
2809 |
06 Aug 12 |
peter |
99 |
|
2809 |
06 Aug 12 |
peter |
100 |
/** |
2809 |
06 Aug 12 |
peter |
\brief number of data points |
2809 |
06 Aug 12 |
peter |
102 |
|
2809 |
06 Aug 12 |
peter |
\return Number of data points |
2809 |
06 Aug 12 |
peter |
104 |
*/ |
2809 |
06 Aug 12 |
peter |
105 |
long n(void) const { return n_; } |
2809 |
06 Aug 12 |
peter |
106 |
|
2809 |
06 Aug 12 |
peter |
107 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Rescales the object |
2809 |
06 Aug 12 |
peter |
109 |
|
2809 |
06 Aug 12 |
peter |
\f$ \forall x_i \rightarrow a*x_i \f$, |
2809 |
06 Aug 12 |
peter |
111 |
*/ |
2809 |
06 Aug 12 |
peter |
112 |
void rescale(double a) { static_cast<Derived*>(this)->rescale_impl(a); } |
2809 |
06 Aug 12 |
peter |
113 |
|
2809 |
06 Aug 12 |
peter |
114 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Reset object |
2809 |
06 Aug 12 |
peter |
116 |
|
2809 |
06 Aug 12 |
peter |
Restore Averager as if data were never added |
2809 |
06 Aug 12 |
peter |
118 |
*/ |
2809 |
06 Aug 12 |
peter |
119 |
void reset(void) |
2809 |
06 Aug 12 |
peter |
120 |
{ |
2809 |
06 Aug 12 |
peter |
121 |
Derived tmp; |
2809 |
06 Aug 12 |
peter |
122 |
*static_cast<Derived*>(this) = tmp; |
2809 |
06 Aug 12 |
peter |
123 |
} |
2809 |
06 Aug 12 |
peter |
124 |
|
2809 |
06 Aug 12 |
peter |
125 |
/** |
2809 |
06 Aug 12 |
peter |
\return The sum of data values |
2809 |
06 Aug 12 |
peter |
127 |
*/ |
2809 |
06 Aug 12 |
peter |
128 |
double sum_x(void) const { return n_*mean_; } |
2809 |
06 Aug 12 |
peter |
129 |
|
2809 |
06 Aug 12 |
peter |
130 |
protected: |
2809 |
06 Aug 12 |
peter |
131 |
/** |
2809 |
06 Aug 12 |
peter |
number of data points |
2809 |
06 Aug 12 |
peter |
133 |
*/ |
2809 |
06 Aug 12 |
peter |
134 |
long int n_; |
2809 |
06 Aug 12 |
peter |
135 |
|
2809 |
06 Aug 12 |
peter |
136 |
/** |
2809 |
06 Aug 12 |
peter |
\brief mean |
2809 |
06 Aug 12 |
peter |
138 |
*/ |
2809 |
06 Aug 12 |
peter |
139 |
double mean_; |
2809 |
06 Aug 12 |
peter |
140 |
|
2809 |
06 Aug 12 |
peter |
141 |
/** |
2809 |
06 Aug 12 |
peter |
add \a n data points with value \a x |
2809 |
06 Aug 12 |
peter |
143 |
*/ |
2809 |
06 Aug 12 |
peter |
144 |
void add1(double x, long int n); |
2809 |
06 Aug 12 |
peter |
145 |
/** |
2809 |
06 Aug 12 |
peter |
add one data point with value \a delta + mean() |
2809 |
06 Aug 12 |
peter |
147 |
*/ |
2809 |
06 Aug 12 |
peter |
148 |
void add1(double delta); |
2809 |
06 Aug 12 |
peter |
149 |
|
2809 |
06 Aug 12 |
peter |
150 |
/** |
2809 |
06 Aug 12 |
peter |
rescale as \f$ mean \rightarrow x mean \f$ |
2809 |
06 Aug 12 |
peter |
152 |
*/ |
2809 |
06 Aug 12 |
peter |
153 |
double rescale1(double x); |
2809 |
06 Aug 12 |
peter |
154 |
}; |
2809 |
06 Aug 12 |
peter |
155 |
|
2809 |
06 Aug 12 |
peter |
156 |
|
2809 |
06 Aug 12 |
peter |
157 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Base class for averagers calculating mean and variance. |
2809 |
06 Aug 12 |
peter |
159 |
|
2809 |
06 Aug 12 |
peter |
This is an extension of averager_base and provides more |
2809 |
06 Aug 12 |
peter |
functionality related to the second moment (variance). |
2809 |
06 Aug 12 |
peter |
162 |
|
2809 |
06 Aug 12 |
peter |
For requirement on \c Derived see averager_base. |
2809 |
06 Aug 12 |
peter |
164 |
|
2809 |
06 Aug 12 |
peter |
\see Averager which is an example derived class |
2809 |
06 Aug 12 |
peter |
166 |
|
2809 |
06 Aug 12 |
peter |
\since yat 0.9 |
2809 |
06 Aug 12 |
peter |
168 |
*/ |
2809 |
06 Aug 12 |
peter |
169 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
170 |
class averager_base2 : public averager_base<Derived> |
2809 |
06 Aug 12 |
peter |
171 |
{ |
2809 |
06 Aug 12 |
peter |
172 |
public: |
2809 |
06 Aug 12 |
peter |
173 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Constructor |
2809 |
06 Aug 12 |
peter |
175 |
*/ |
2809 |
06 Aug 12 |
peter |
176 |
averager_base2(void) : cm2_(0) {} |
2809 |
06 Aug 12 |
peter |
177 |
|
2809 |
06 Aug 12 |
peter |
178 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Destructor |
2809 |
06 Aug 12 |
peter |
180 |
*/ |
2809 |
06 Aug 12 |
peter |
181 |
virtual ~averager_base2(void)=0; |
2809 |
06 Aug 12 |
peter |
182 |
|
2809 |
06 Aug 12 |
peter |
183 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Coeffient of variation |
2809 |
06 Aug 12 |
peter |
185 |
|
2809 |
06 Aug 12 |
peter |
Coeffient of variation (cv) is defined as ratio between the |
2809 |
06 Aug 12 |
peter |
standard deviation and the mean: \f$ \frac{\sigma}{\mu} \f$. |
2809 |
06 Aug 12 |
peter |
188 |
|
2809 |
06 Aug 12 |
peter |
@return standard deviation divided by mean. |
2809 |
06 Aug 12 |
peter |
190 |
*/ |
2809 |
06 Aug 12 |
peter |
191 |
double cv(void) const { return std() / this->mean(); } |
2809 |
06 Aug 12 |
peter |
192 |
|
2809 |
06 Aug 12 |
peter |
193 |
/** |
2809 |
06 Aug 12 |
peter |
\return Standard error, i.e. standard deviation of the mean |
2809 |
06 Aug 12 |
peter |
\f$ \sqrt{variance()/n} \f$ |
2809 |
06 Aug 12 |
peter |
196 |
*/ |
2809 |
06 Aug 12 |
peter |
197 |
double standard_error(void) const |
2809 |
06 Aug 12 |
peter |
198 |
{ return std::sqrt(variance()/this->n()); } |
2809 |
06 Aug 12 |
peter |
199 |
|
2809 |
06 Aug 12 |
peter |
200 |
/** |
2809 |
06 Aug 12 |
peter |
\brief The standard deviation is defined as the square root of |
2809 |
06 Aug 12 |
peter |
the variance. |
2809 |
06 Aug 12 |
peter |
203 |
|
2809 |
06 Aug 12 |
peter |
\return The standard deviation, root of the variance(). |
2809 |
06 Aug 12 |
peter |
205 |
*/ |
2809 |
06 Aug 12 |
peter |
206 |
double std(void) const { return std::sqrt(variance()); } |
2809 |
06 Aug 12 |
peter |
207 |
|
2809 |
06 Aug 12 |
peter |
208 |
/** |
2809 |
06 Aug 12 |
peter |
\brief The standard deviation is defined as the square root of |
2809 |
06 Aug 12 |
peter |
the variance. |
2809 |
06 Aug 12 |
peter |
211 |
|
2809 |
06 Aug 12 |
peter |
\return Standard deviation around \a m, root of the variance(m). |
2809 |
06 Aug 12 |
peter |
213 |
*/ |
2809 |
06 Aug 12 |
peter |
214 |
double std(double m) const { return std::sqrt(variance(m)); } |
2809 |
06 Aug 12 |
peter |
215 |
|
2809 |
06 Aug 12 |
peter |
216 |
/** |
2809 |
06 Aug 12 |
peter |
\return The sum of squares |
2809 |
06 Aug 12 |
peter |
218 |
*/ |
2809 |
06 Aug 12 |
peter |
219 |
double sum_xx(void) const |
2809 |
06 Aug 12 |
peter |
220 |
{ return cm2_ + this->n_*this->mean_*this->mean_; } |
2809 |
06 Aug 12 |
peter |
221 |
|
2809 |
06 Aug 12 |
peter |
222 |
/** |
2809 |
06 Aug 12 |
peter |
\return \f$ \sum_i (x_i-m)^2 \f$ |
2809 |
06 Aug 12 |
peter |
224 |
*/ |
2809 |
06 Aug 12 |
peter |
225 |
double sum_xx_centered(void) const { return cm2_; } |
2809 |
06 Aug 12 |
peter |
226 |
|
2809 |
06 Aug 12 |
peter |
227 |
/** |
2809 |
06 Aug 12 |
peter |
@brief The variance with known mean |
2809 |
06 Aug 12 |
peter |
229 |
|
2809 |
06 Aug 12 |
peter |
The variance is calculated as |
2809 |
06 Aug 12 |
peter |
\f$ \frac{1}{n}\sum (x_i-m)^2 \f$. |
2809 |
06 Aug 12 |
peter |
232 |
|
2809 |
06 Aug 12 |
peter |
\return Variance when the mean is known to be \a m. |
2809 |
06 Aug 12 |
peter |
234 |
*/ |
2809 |
06 Aug 12 |
peter |
235 |
double variance(double m) const |
2809 |
06 Aug 12 |
peter |
236 |
{ return sum_xx()/this->n() + m*m - 2*m*this->mean();} |
2809 |
06 Aug 12 |
peter |
237 |
|
2809 |
06 Aug 12 |
peter |
238 |
/** |
2809 |
06 Aug 12 |
peter |
\brief The estimated variance |
2809 |
06 Aug 12 |
peter |
240 |
|
2809 |
06 Aug 12 |
peter |
The variance is calculated as \f$ \frac{1}{N}\sum_i |
2809 |
06 Aug 12 |
peter |
(x_i-m)^2 \f$, where \f$ m \f$ is the mean. |
2809 |
06 Aug 12 |
peter |
243 |
|
2809 |
06 Aug 12 |
peter |
\return Estimation of variance |
2809 |
06 Aug 12 |
peter |
245 |
*/ |
2809 |
06 Aug 12 |
peter |
246 |
double variance(void) const { return sum_xx_centered()/this->n_; } |
2809 |
06 Aug 12 |
peter |
247 |
|
2809 |
06 Aug 12 |
peter |
248 |
/** |
2809 |
06 Aug 12 |
peter |
The variance is calculated using the \f$ (n-1) \f$ correction, |
2809 |
06 Aug 12 |
peter |
which means it is the best unbiased estimator of the variance |
2809 |
06 Aug 12 |
peter |
\f$ \frac{1}{N-1}\sum_i (x_i-m)^2 \f$, where \f$ m \f$ is the |
2809 |
06 Aug 12 |
peter |
mean. |
2809 |
06 Aug 12 |
peter |
253 |
|
2809 |
06 Aug 12 |
peter |
@return unbiased estimation of variance |
2809 |
06 Aug 12 |
peter |
255 |
*/ |
2809 |
06 Aug 12 |
peter |
256 |
double variance_unbiased(void) const |
2809 |
06 Aug 12 |
peter |
257 |
{ |
2809 |
06 Aug 12 |
peter |
258 |
return (this->n_>1) ? sum_xx_centered()/(this->n_-1) : |
2809 |
06 Aug 12 |
peter |
259 |
std::numeric_limits<double>::quiet_NaN(); |
2809 |
06 Aug 12 |
peter |
260 |
} |
2809 |
06 Aug 12 |
peter |
261 |
|
2809 |
06 Aug 12 |
peter |
262 |
protected: |
2809 |
06 Aug 12 |
peter |
263 |
/** |
2809 |
06 Aug 12 |
peter |
sum of values squared values centralized \f$ \sum (x-m)^2 \f$ |
2809 |
06 Aug 12 |
peter |
265 |
*/ |
2809 |
06 Aug 12 |
peter |
266 |
double cm2_; |
2809 |
06 Aug 12 |
peter |
267 |
|
2809 |
06 Aug 12 |
peter |
268 |
/** |
2809 |
06 Aug 12 |
peter |
add a set of \a n data points with mean \a mean and centralized |
2809 |
06 Aug 12 |
peter |
squaed sum \a cm |
2809 |
06 Aug 12 |
peter |
271 |
*/ |
2809 |
06 Aug 12 |
peter |
272 |
void add2(double mean, double cm2, long int n); |
2809 |
06 Aug 12 |
peter |
273 |
|
2809 |
06 Aug 12 |
peter |
274 |
/** |
2809 |
06 Aug 12 |
peter |
add one data point with value \a delta + mean() |
2809 |
06 Aug 12 |
peter |
276 |
*/ |
2809 |
06 Aug 12 |
peter |
277 |
void add2(double delta); |
2809 |
06 Aug 12 |
peter |
278 |
|
2809 |
06 Aug 12 |
peter |
279 |
/** |
2809 |
06 Aug 12 |
peter |
rescales \f$ cm2 \rightarrow x^2 cm2 \f$ and calles rescale1(double) |
2809 |
06 Aug 12 |
peter |
281 |
*/ |
2809 |
06 Aug 12 |
peter |
282 |
double rescale2(double x); |
2809 |
06 Aug 12 |
peter |
283 |
private: |
2809 |
06 Aug 12 |
peter |
284 |
}; |
2809 |
06 Aug 12 |
peter |
285 |
|
2809 |
06 Aug 12 |
peter |
286 |
|
2809 |
06 Aug 12 |
peter |
287 |
/** |
2809 |
06 Aug 12 |
peter |
Base class for averagers calculating first (mean), second |
2809 |
06 Aug 12 |
peter |
(variance) and third moment. |
2809 |
06 Aug 12 |
peter |
290 |
|
2809 |
06 Aug 12 |
peter |
For requirement on \c Derived see averager_base. |
2809 |
06 Aug 12 |
peter |
292 |
|
2809 |
06 Aug 12 |
peter |
\since yat 0.9 |
2809 |
06 Aug 12 |
peter |
294 |
*/ |
2809 |
06 Aug 12 |
peter |
295 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
296 |
class averager_base3 : public averager_base2<Derived> |
2809 |
06 Aug 12 |
peter |
297 |
{ |
2809 |
06 Aug 12 |
peter |
298 |
public: |
2809 |
06 Aug 12 |
peter |
299 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Constructor |
2809 |
06 Aug 12 |
peter |
301 |
*/ |
2809 |
06 Aug 12 |
peter |
302 |
averager_base3(void) : averager_base2<Derived>(), cm3_(0) {} |
2809 |
06 Aug 12 |
peter |
303 |
|
2809 |
06 Aug 12 |
peter |
304 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Destructor |
2809 |
06 Aug 12 |
peter |
306 |
*/ |
2809 |
06 Aug 12 |
peter |
307 |
virtual ~averager_base3(void)=0; |
2809 |
06 Aug 12 |
peter |
308 |
|
2809 |
06 Aug 12 |
peter |
309 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Third central moment |
2809 |
06 Aug 12 |
peter |
311 |
|
2809 |
06 Aug 12 |
peter |
Third central moment is calculated as \f$ \frac{1}{n} \sum |
2809 |
06 Aug 12 |
peter |
(x_i-m)^3 \f$ where \c m is the mean. |
2809 |
06 Aug 12 |
peter |
314 |
*/ |
2809 |
06 Aug 12 |
peter |
315 |
double central_moment3(void) const { return cm3_/this->n_; } |
2809 |
06 Aug 12 |
peter |
316 |
|
2809 |
06 Aug 12 |
peter |
317 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Skewness |
2809 |
06 Aug 12 |
peter |
319 |
|
2809 |
06 Aug 12 |
peter |
Skewness is calculated as \f$ \frac{1}{n} \sum (x_i-m) / |
2809 |
06 Aug 12 |
peter |
\sigma^3 \f$ where \f$ \sigma \f$ is standard deviation. |
2809 |
06 Aug 12 |
peter |
322 |
|
2809 |
06 Aug 12 |
peter |
\note this function uses a biased variance estimate [1/n] |
2809 |
06 Aug 12 |
peter |
compared to skewness(utility::VectorBase&), which uses an |
2809 |
06 Aug 12 |
peter |
unbiased variance estimate [1/(n-1)] and may thus give |
2809 |
06 Aug 12 |
peter |
different results for small \c n. |
2809 |
06 Aug 12 |
peter |
327 |
*/ |
2809 |
06 Aug 12 |
peter |
328 |
double skewness(void) const |
2809 |
06 Aug 12 |
peter |
329 |
{ return central_moment3()/std::pow(this->std(),3); } |
2809 |
06 Aug 12 |
peter |
330 |
|
2809 |
06 Aug 12 |
peter |
331 |
/** |
2809 |
06 Aug 12 |
peter |
\return sum cubed centered |
2809 |
06 Aug 12 |
peter |
333 |
|
2809 |
06 Aug 12 |
peter |
\f$ \sum (x_i-m)^3 \f$ |
2809 |
06 Aug 12 |
peter |
335 |
*/ |
2809 |
06 Aug 12 |
peter |
336 |
double sum_x3_centered(void) const { return cm3_; } |
2809 |
06 Aug 12 |
peter |
337 |
|
2809 |
06 Aug 12 |
peter |
338 |
protected: |
2809 |
06 Aug 12 |
peter |
339 |
/** |
2809 |
06 Aug 12 |
peter |
sum cubed centered |
2809 |
06 Aug 12 |
peter |
341 |
*/ |
2809 |
06 Aug 12 |
peter |
342 |
double cm3_; |
2809 |
06 Aug 12 |
peter |
343 |
|
2809 |
06 Aug 12 |
peter |
344 |
/** |
2809 |
06 Aug 12 |
peter |
add a set of \a n data points with mean \c mean, sum squared |
2809 |
06 Aug 12 |
peter |
centered \a cm2, and sum cubed centered \a cm3. |
2809 |
06 Aug 12 |
peter |
347 |
*/ |
2809 |
06 Aug 12 |
peter |
348 |
void add3(double mean, double cm2, double cm3, long int n); |
2809 |
06 Aug 12 |
peter |
349 |
|
2809 |
06 Aug 12 |
peter |
350 |
/** |
2809 |
06 Aug 12 |
peter |
add one data point with value \c delta + mean() |
2809 |
06 Aug 12 |
peter |
352 |
*/ |
2809 |
06 Aug 12 |
peter |
353 |
void add3(double delta); |
2809 |
06 Aug 12 |
peter |
354 |
|
2809 |
06 Aug 12 |
peter |
355 |
/** |
2809 |
06 Aug 12 |
peter |
rescales \f$ cm3 = x^3 cm3 \f$ and calles rescale2(double) |
2809 |
06 Aug 12 |
peter |
357 |
*/ |
2809 |
06 Aug 12 |
peter |
358 |
double rescale3(double x); |
2809 |
06 Aug 12 |
peter |
359 |
}; |
2809 |
06 Aug 12 |
peter |
360 |
|
2809 |
06 Aug 12 |
peter |
361 |
/** |
2809 |
06 Aug 12 |
peter |
Base class for averagers calculating first (mean), second |
2809 |
06 Aug 12 |
peter |
(variance), third moment, and fourth moment. |
2809 |
06 Aug 12 |
peter |
364 |
|
2809 |
06 Aug 12 |
peter |
For requirement on \c Derived see averager_base. |
2809 |
06 Aug 12 |
peter |
366 |
|
2809 |
06 Aug 12 |
peter |
\since yat 0.9 |
2809 |
06 Aug 12 |
peter |
368 |
*/ |
2809 |
06 Aug 12 |
peter |
369 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
370 |
class averager_base4 : public averager_base3<Derived> |
2809 |
06 Aug 12 |
peter |
371 |
{ |
2809 |
06 Aug 12 |
peter |
372 |
public: |
2809 |
06 Aug 12 |
peter |
373 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Constructor |
2809 |
06 Aug 12 |
peter |
375 |
*/ |
2809 |
06 Aug 12 |
peter |
376 |
averager_base4(void) : averager_base3<Derived>(), cm4_(0) {} |
2809 |
06 Aug 12 |
peter |
377 |
|
2809 |
06 Aug 12 |
peter |
378 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Destructor |
2809 |
06 Aug 12 |
peter |
380 |
*/ |
2809 |
06 Aug 12 |
peter |
381 |
virtual ~averager_base4(void)=0; |
2809 |
06 Aug 12 |
peter |
382 |
|
2809 |
06 Aug 12 |
peter |
383 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Fourth central moment |
2809 |
06 Aug 12 |
peter |
385 |
|
2809 |
06 Aug 12 |
peter |
Fourth central moment is calculated as \f$ \frac{1}{n} \sum |
2809 |
06 Aug 12 |
peter |
(x_i-m)^4 \f$ where \c m is the mean. |
2809 |
06 Aug 12 |
peter |
388 |
*/ |
2809 |
06 Aug 12 |
peter |
389 |
double central_moment4(void) const { return cm4_/this->n_; } |
2809 |
06 Aug 12 |
peter |
390 |
|
2809 |
06 Aug 12 |
peter |
391 |
/** |
2809 |
06 Aug 12 |
peter |
\brief Kurtosis |
2809 |
06 Aug 12 |
peter |
393 |
|
2809 |
06 Aug 12 |
peter |
Kurtosis is calculated as \f$ \frac{1}{n} \sum (x-m)^4 / |
2809 |
06 Aug 12 |
peter |
\sigma^4 - 3.0 \f$ where \c m is mean, and \f$ \sigma \f$ is |
2809 |
06 Aug 12 |
peter |
standard deviation. |
2809 |
06 Aug 12 |
peter |
397 |
|
2809 |
06 Aug 12 |
peter |
\note this function uses a biased variance estimate [1/n] |
2809 |
06 Aug 12 |
peter |
compared to kurtosis(utility::VectorBase&), which uses an |
2809 |
06 Aug 12 |
peter |
unbiased variance estimate [1/(n-1)] and may thus give |
2809 |
06 Aug 12 |
peter |
different results for small \c n. |
2809 |
06 Aug 12 |
peter |
402 |
*/ |
2809 |
06 Aug 12 |
peter |
403 |
double kurtosis(void) const |
2809 |
06 Aug 12 |
peter |
404 |
{ return central_moment4()/std::pow(this->variance(),2) - 3.0; } |
2809 |
06 Aug 12 |
peter |
405 |
|
2809 |
06 Aug 12 |
peter |
406 |
/** |
2809 |
06 Aug 12 |
peter |
\brief sum quadrupled centered |
2809 |
06 Aug 12 |
peter |
408 |
|
2809 |
06 Aug 12 |
peter |
Calculated as \f$ \frac{1}{n} \sum (x_i-m)^4 \f$ |
2809 |
06 Aug 12 |
peter |
410 |
*/ |
2809 |
06 Aug 12 |
peter |
411 |
double sum_x4_centered(void) const { return cm4_; } |
2809 |
06 Aug 12 |
peter |
412 |
protected: |
2809 |
06 Aug 12 |
peter |
413 |
/** |
2809 |
06 Aug 12 |
peter |
\brief sum quadrupled centered |
2809 |
06 Aug 12 |
peter |
415 |
*/ |
2809 |
06 Aug 12 |
peter |
416 |
double cm4_; |
2809 |
06 Aug 12 |
peter |
417 |
|
2809 |
06 Aug 12 |
peter |
418 |
/** |
2809 |
06 Aug 12 |
peter |
add a set of \a n data points with mean \c mean, sum squared |
2809 |
06 Aug 12 |
peter |
centered \a cm2, sum cubed centered \a cm3, and sum quadrupled |
2809 |
06 Aug 12 |
peter |
centered \a cm4. |
2809 |
06 Aug 12 |
peter |
422 |
*/ |
2809 |
06 Aug 12 |
peter |
423 |
void add4(double mean, double cm2, double cm3, double cm4, long int n); |
2809 |
06 Aug 12 |
peter |
424 |
|
2809 |
06 Aug 12 |
peter |
425 |
/** |
2809 |
06 Aug 12 |
peter |
add one data point with value \c delta + mean() |
2809 |
06 Aug 12 |
peter |
427 |
*/ |
2809 |
06 Aug 12 |
peter |
428 |
void add4(double delta); |
2809 |
06 Aug 12 |
peter |
429 |
|
2809 |
06 Aug 12 |
peter |
430 |
/** |
2809 |
06 Aug 12 |
peter |
rescales \f$ cm4 = x^4 cm4 \f$ and calles |
2809 |
06 Aug 12 |
peter |
rescale2(double) |
2809 |
06 Aug 12 |
peter |
433 |
*/ |
2809 |
06 Aug 12 |
peter |
434 |
double rescale4(double x); |
2809 |
06 Aug 12 |
peter |
435 |
}; |
2809 |
06 Aug 12 |
peter |
436 |
|
2809 |
06 Aug 12 |
peter |
///// template implementations |
2809 |
06 Aug 12 |
peter |
438 |
|
2809 |
06 Aug 12 |
peter |
439 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
440 |
averager_base<Derived>::~averager_base(void) {} |
2809 |
06 Aug 12 |
peter |
441 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
442 |
averager_base2<Derived>::~averager_base2(void) {} |
2809 |
06 Aug 12 |
peter |
443 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
444 |
averager_base3<Derived>::~averager_base3(void) {} |
2809 |
06 Aug 12 |
peter |
445 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
446 |
averager_base4<Derived>::~averager_base4(void) {} |
2809 |
06 Aug 12 |
peter |
447 |
|
2809 |
06 Aug 12 |
peter |
448 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
449 |
void averager_base<Derived>::add1(double x, long int n) |
2809 |
06 Aug 12 |
peter |
450 |
{ |
2809 |
06 Aug 12 |
peter |
451 |
if (n == -this->n_) { |
2809 |
06 Aug 12 |
peter |
452 |
this->reset(); |
2809 |
06 Aug 12 |
peter |
453 |
return; |
2809 |
06 Aug 12 |
peter |
454 |
} |
2809 |
06 Aug 12 |
peter |
455 |
this->mean_ = (this->n_*this->mean_ + n*x) / (this->n_ + n); |
2809 |
06 Aug 12 |
peter |
456 |
this->n_+=n; |
2809 |
06 Aug 12 |
peter |
457 |
} |
2809 |
06 Aug 12 |
peter |
458 |
|
2809 |
06 Aug 12 |
peter |
459 |
|
2809 |
06 Aug 12 |
peter |
460 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
461 |
void averager_base<Derived>::add1(double delta) |
2809 |
06 Aug 12 |
peter |
462 |
{ |
2809 |
06 Aug 12 |
peter |
463 |
++this->n_; |
2809 |
06 Aug 12 |
peter |
464 |
this->mean_ += delta * 1/(this->n_); |
2809 |
06 Aug 12 |
peter |
465 |
} |
2809 |
06 Aug 12 |
peter |
466 |
|
2809 |
06 Aug 12 |
peter |
467 |
|
2809 |
06 Aug 12 |
peter |
468 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
469 |
void averager_base2<Derived>::add2(double m, double cm2, long int n) |
2809 |
06 Aug 12 |
peter |
470 |
{ |
2809 |
06 Aug 12 |
peter |
471 |
if (n == -this->n_) { |
2809 |
06 Aug 12 |
peter |
472 |
this->reset(); |
2809 |
06 Aug 12 |
peter |
473 |
return; |
2809 |
06 Aug 12 |
peter |
474 |
} |
2809 |
06 Aug 12 |
peter |
475 |
const double delta = this->mean_ - m; |
2809 |
06 Aug 12 |
peter |
476 |
this->cm2_ += cm2 + this->n_*n*delta*delta/(this->n_+n); |
2809 |
06 Aug 12 |
peter |
477 |
this->add1(m, n); |
2809 |
06 Aug 12 |
peter |
478 |
} |
2809 |
06 Aug 12 |
peter |
479 |
|
2809 |
06 Aug 12 |
peter |
480 |
|
2809 |
06 Aug 12 |
peter |
481 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
482 |
void averager_base2<Derived>::add2(double delta) |
2809 |
06 Aug 12 |
peter |
483 |
{ |
2809 |
06 Aug 12 |
peter |
484 |
this->cm2_ += this->n_*delta*delta/(this->n_+1); |
2809 |
06 Aug 12 |
peter |
485 |
this->add1(delta); |
2809 |
06 Aug 12 |
peter |
486 |
} |
2809 |
06 Aug 12 |
peter |
487 |
|
2809 |
06 Aug 12 |
peter |
488 |
|
2809 |
06 Aug 12 |
peter |
489 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
490 |
void averager_base3<Derived>::add3(double mean, double cm2, double cm3, |
2809 |
06 Aug 12 |
peter |
491 |
long int n) |
2809 |
06 Aug 12 |
peter |
492 |
{ |
2809 |
06 Aug 12 |
peter |
493 |
if (n == -this->n_) { |
2809 |
06 Aug 12 |
peter |
494 |
this->reset(); |
2809 |
06 Aug 12 |
peter |
495 |
return; |
2809 |
06 Aug 12 |
peter |
496 |
} |
2809 |
06 Aug 12 |
peter |
497 |
const double n_inverse = 1.0/(this->n_+n); |
2809 |
06 Aug 12 |
peter |
498 |
const double delta = mean - this->mean_; |
2809 |
06 Aug 12 |
peter |
499 |
const double r = n_inverse*delta; |
2809 |
06 Aug 12 |
peter |
500 |
|
2809 |
06 Aug 12 |
peter |
501 |
this->cm3_ += cm3 + r*r*delta*this->n_*n*(this->n_-n) + |
2809 |
06 Aug 12 |
peter |
502 |
3*r*(this->n_*cm2 - n*this->cm2_); |
2809 |
06 Aug 12 |
peter |
503 |
this->add2(mean, cm2, n); |
2809 |
06 Aug 12 |
peter |
504 |
} |
2809 |
06 Aug 12 |
peter |
505 |
|
2809 |
06 Aug 12 |
peter |
506 |
|
2809 |
06 Aug 12 |
peter |
507 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
508 |
void averager_base3<Derived>::add3(double delta) |
2809 |
06 Aug 12 |
peter |
509 |
{ |
2809 |
06 Aug 12 |
peter |
510 |
const double r = delta/(this->n_+1); |
2809 |
06 Aug 12 |
peter |
511 |
|
2809 |
06 Aug 12 |
peter |
512 |
this->cm3_ += r*r*delta*this->n_*(this->n_-1) - 3*r*this->cm2_; |
2809 |
06 Aug 12 |
peter |
513 |
this->add2(delta); |
2809 |
06 Aug 12 |
peter |
514 |
} |
2809 |
06 Aug 12 |
peter |
515 |
|
2809 |
06 Aug 12 |
peter |
516 |
|
2809 |
06 Aug 12 |
peter |
517 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
518 |
void averager_base4<Derived>::add4(double mean, double cm2, double cm3, |
2809 |
06 Aug 12 |
peter |
519 |
double cm4, long int n) |
2809 |
06 Aug 12 |
peter |
520 |
{ |
2809 |
06 Aug 12 |
peter |
521 |
if (n == -this->n_) { |
2809 |
06 Aug 12 |
peter |
522 |
this->reset(); |
2809 |
06 Aug 12 |
peter |
523 |
return; |
2809 |
06 Aug 12 |
peter |
524 |
} |
2809 |
06 Aug 12 |
peter |
525 |
const double n_inverse = 1.0/(this->n_+n); |
2809 |
06 Aug 12 |
peter |
526 |
const double delta = mean - this->mean_; |
2809 |
06 Aug 12 |
peter |
527 |
const double r = n_inverse*delta; |
2809 |
06 Aug 12 |
peter |
528 |
|
2809 |
06 Aug 12 |
peter |
529 |
cm4_ += cm4 + |
2809 |
06 Aug 12 |
peter |
530 |
std::pow(r,3)*delta*this->n_*n*(this->n_*this->n_-this->n_*n+n*n) + |
2809 |
06 Aug 12 |
peter |
531 |
6*r*r*(this->n_*this->n_*cm2+n*n*this->cm2_) + |
2809 |
06 Aug 12 |
peter |
532 |
4*r*(this->n_*cm3-n*this->cm3_); |
2809 |
06 Aug 12 |
peter |
533 |
this->add3(mean, cm2, cm3, n); |
2809 |
06 Aug 12 |
peter |
534 |
} |
2809 |
06 Aug 12 |
peter |
535 |
|
2809 |
06 Aug 12 |
peter |
536 |
|
2809 |
06 Aug 12 |
peter |
537 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
538 |
void averager_base4<Derived>::add4(double delta) |
2809 |
06 Aug 12 |
peter |
539 |
{ |
2809 |
06 Aug 12 |
peter |
540 |
const double r = delta/(this->n_+1); |
2809 |
06 Aug 12 |
peter |
541 |
|
2809 |
06 Aug 12 |
peter |
542 |
cm4_ += |
2809 |
06 Aug 12 |
peter |
543 |
std::pow(r,3)*delta*this->n_*(this->n_*this->n_-this->n_+1) + |
2809 |
06 Aug 12 |
peter |
544 |
6*r*r*(this->cm2_) + |
2809 |
06 Aug 12 |
peter |
545 |
4*r*(0-this->cm3_); |
2809 |
06 Aug 12 |
peter |
546 |
|
2809 |
06 Aug 12 |
peter |
547 |
this->add3(delta); |
2809 |
06 Aug 12 |
peter |
548 |
} |
2809 |
06 Aug 12 |
peter |
549 |
|
2809 |
06 Aug 12 |
peter |
550 |
|
2809 |
06 Aug 12 |
peter |
551 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
552 |
double averager_base<Derived>::rescale1(double x) |
2809 |
06 Aug 12 |
peter |
553 |
{ |
2809 |
06 Aug 12 |
peter |
554 |
this->mean_ *= x; |
2809 |
06 Aug 12 |
peter |
555 |
return x; |
2809 |
06 Aug 12 |
peter |
556 |
} |
2809 |
06 Aug 12 |
peter |
557 |
|
2809 |
06 Aug 12 |
peter |
558 |
|
2809 |
06 Aug 12 |
peter |
559 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
560 |
double averager_base2<Derived>::rescale2(double x) |
2809 |
06 Aug 12 |
peter |
561 |
{ |
2809 |
06 Aug 12 |
peter |
562 |
this->rescale1(x); |
2809 |
06 Aug 12 |
peter |
563 |
double factor = x*x; |
2809 |
06 Aug 12 |
peter |
564 |
this->cm2_ *= factor; |
2809 |
06 Aug 12 |
peter |
565 |
return factor; |
2809 |
06 Aug 12 |
peter |
566 |
} |
2809 |
06 Aug 12 |
peter |
567 |
|
2809 |
06 Aug 12 |
peter |
568 |
|
2809 |
06 Aug 12 |
peter |
569 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
570 |
double averager_base3<Derived>::rescale3(double x) |
2809 |
06 Aug 12 |
peter |
571 |
{ |
2809 |
06 Aug 12 |
peter |
572 |
double factor = x*this->rescale2(x); |
2809 |
06 Aug 12 |
peter |
573 |
this->cm3_ *= factor; |
2809 |
06 Aug 12 |
peter |
574 |
return factor; |
2809 |
06 Aug 12 |
peter |
575 |
} |
2809 |
06 Aug 12 |
peter |
576 |
|
2809 |
06 Aug 12 |
peter |
577 |
|
2809 |
06 Aug 12 |
peter |
578 |
template<class Derived> |
2809 |
06 Aug 12 |
peter |
579 |
double averager_base4<Derived>::rescale4(double x) |
2809 |
06 Aug 12 |
peter |
580 |
{ |
2809 |
06 Aug 12 |
peter |
581 |
double factor = x*this->rescale3(x); |
2809 |
06 Aug 12 |
peter |
582 |
this->cm3_ *= factor; |
2809 |
06 Aug 12 |
peter |
583 |
return factor; |
2809 |
06 Aug 12 |
peter |
584 |
} |
2809 |
06 Aug 12 |
peter |
585 |
|
2809 |
06 Aug 12 |
peter |
586 |
}}} |
2809 |
06 Aug 12 |
peter |
587 |
#endif |