00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef TOOL_LINEAR_REGRESSION_HXX_
00023 # define TOOL_LINEAR_REGRESSION_HXX_
00024
00025 # include <stdexcept>
00026
00027 # include "linear_regression.hh"
00028
00029 namespace tool
00030 {
00031
00032 namespace lr
00033 {
00034
00035 template <class ImplType>
00036 template <class T1, class T2>
00037 ImplType
00038 pair<ImplType>::x(const std::pair<T1, T2>& p) const
00039 {
00040 return p.first;
00041 }
00042
00043 template <class ImplType>
00044 template <class T1, class T2>
00045 ImplType
00046 pair<ImplType>::y(const std::pair<T1, T2>& p) const
00047 {
00048 return p.second;
00049 }
00050
00051 template <class ImplType>
00052 template <class T1, class T2>
00053 ImplType
00054 pair_with_microseconds<ImplType>::x(const std::pair<T1, T2>& p) const
00055 {
00056 return p.first.microseconds();
00057 }
00058
00059 template <class ImplType>
00060 template <class T1, class T2>
00061 ImplType
00062 pair_with_microseconds<ImplType>::y(const std::pair<T1, T2>& p) const
00063 {
00064 return p.second.microseconds();
00065 }
00066
00067 }
00068
00069 template <class ImplType, class Adapter, class InputIterator>
00070 std::pair<ImplType, ImplType>
00071 linear_regression(const InputIterator& first,
00072 const InputIterator& last,
00073 Adapter adapt)
00074 {
00075 typename InputIterator::difference_type n = 0;
00076 ImplType x_mean (0);
00077 ImplType y_mean (0);
00078
00079 for (InputIterator i = first; i != last; ++i)
00080 {
00081 x_mean += adapt.x(*i);
00082 y_mean += adapt.y(*i);
00083 ++n;
00084 }
00085
00086 if (not n)
00087 throw std::invalid_argument ("Not enough elements to perform a linear "
00088 "regression");
00089
00090 y_mean /= n;
00091 x_mean /= n;
00092
00093 ImplType cov (0);
00094 ImplType V_x (0);
00095
00096 for (InputIterator i = first; i != last; ++i)
00097 {
00098 const ImplType x_diff = adapt.x(*i) - x_mean;
00099 const ImplType y_diff = adapt.y(*i) - y_mean;
00100
00101 cov += y_diff * x_diff;
00102 V_x += x_diff * x_diff;
00103 }
00104 cov /= n;
00105 V_x /= n;
00106
00107 if (V_x == 0)
00108 throw std::invalid_argument ("Elements variance is null");
00109
00110 const ImplType a = cov / V_x;
00111 const ImplType b = y_mean - a * x_mean;
00112
00113 return std::make_pair(a, b);
00114 }
00115
00116 }
00117
00118 #endif // ! TOOL_LINEAR_REGRESSION_HXX_