include/wipal/tool/linear_regression.hxx

00001 /*
00002  * WiPal - A library and a set of tools to manipulate wireless traces.
00003  * Copyright (C) 2007  Universite Pierre et Marie Curie - Paris 6
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00018  * MA  02110-1301  USA
00019  *
00020  * Author: Thomas Claveirole <thomas.claveirole@lip6.fr>
00021  */
00022 #ifndef TOOL_LINEAR_REGRESSION_HXX_
00023 # define TOOL_LINEAR_REGRESSION_HXX_
00024 
00025 # include <gmpxx.h>
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   } // End of namespace tool::lr.
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 } // End of namespace tool.
00117 
00118 #endif // ! TOOL_LINEAR_REGRESSION_HXX_

Generated on Wed Jan 16 16:15:14 2008 for wipal by  doxygen 1.5.4