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 wpl
00030 {
00031
00032 namespace tool
00033 {
00034
00035 namespace lr
00036 {
00037
00038 template <class ImplType>
00039 template <class T1, class T2>
00040 ImplType
00041 pair<ImplType>::x(const std::pair<T1, T2>& p) const
00042 {
00043 return p.first;
00044 }
00045
00046 template <class ImplType>
00047 template <class T1, class T2>
00048 ImplType
00049 pair<ImplType>::y(const std::pair<T1, T2>& p) const
00050 {
00051 return p.second;
00052 }
00053
00054 template <class ImplType>
00055 template <class T1, class T2>
00056 ImplType
00057 pair_with_microseconds<ImplType>::x(const std::pair<T1, T2>& p) const
00058 {
00059 return p.first.microseconds();
00060 }
00061
00062 template <class ImplType>
00063 template <class T1, class T2>
00064 ImplType
00065 pair_with_microseconds<ImplType>::y(const std::pair<T1, T2>& p) const
00066 {
00067 return p.second.microseconds();
00068 }
00069
00070 }
00071
00072 template <class ImplType, class Adapter, class InputIterator>
00073 std::pair<ImplType, ImplType>
00074 linear_regression(const InputIterator& first,
00075 const InputIterator& last,
00076 Adapter adapt)
00077 {
00078 typename InputIterator::difference_type n = 0;
00079 ImplType x_mean (0);
00080 ImplType y_mean (0);
00081
00082 for (InputIterator i = first; i != last; ++i)
00083 {
00084 x_mean += adapt.x(*i);
00085 y_mean += adapt.y(*i);
00086 ++n;
00087 }
00088
00089 if (not n)
00090 throw std::invalid_argument ("Not enough elements to perform a linear "
00091 "regression");
00092
00093 y_mean /= n;
00094 x_mean /= n;
00095
00096 ImplType cov (0);
00097 ImplType V_x (0);
00098
00099 for (InputIterator i = first; i != last; ++i)
00100 {
00101 const ImplType x_diff = adapt.x(*i) - x_mean;
00102 const ImplType y_diff = adapt.y(*i) - y_mean;
00103
00104 cov += y_diff * x_diff;
00105 V_x += x_diff * x_diff;
00106 }
00107 cov /= n;
00108 V_x /= n;
00109
00110 if (V_x == 0)
00111 throw std::invalid_argument ("Elements variance is null");
00112
00113 const ImplType a = cov / V_x;
00114 const ImplType b = y_mean - a * x_mean;
00115
00116 return std::make_pair(a, b);
00117 }
00118
00119 }
00120
00121 }
00122
00123 #endif // ! TOOL_LINEAR_REGRESSION_HXX_