2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * @file SimpleLinearRegression.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in Histogram.h
26 * This file is part of the DGtal library.
30//////////////////////////////////////////////////////////////////////////////
31///////////////////////////////////////////////////////////////////////////////
32// IMPLEMENTATION of inline methods.
33///////////////////////////////////////////////////////////////////////////////
35//////////////////////////////////////////////////////////////////////////////
38#include <boost/math/distributions/students_t.hpp>
39//////////////////////////////////////////////////////////////////////////////
41///////////////////////////////////////////////////////////////////////////////
42// Implementation of inline methods //
45 * Adds the samples (y,x). Does not compute immediately the
46 * regression. See 'computeRegression' for computing the
47 * regression with the current samples.
49 * @param begin_x an iterator on the first x-data
50 * @param end_x an iterator after the last x-data
51 * @param begin_y an iterator on the first y-data
53 * @see computeRegression
55template <class XIterator, class YIterator>
58DGtal::SimpleLinearRegression::addSamples
59( XIterator begin_x, XIterator end_x, YIterator begin_y )
61 for ( ; begin_x != end_x; ++begin_x, ++begin_y )
63 addSample( *begin_x, *begin_y );
70DGtal::SimpleLinearRegression::addSample(const double x, const double y )
82 * @return the slope of the linear regression (B1 in Y=B0+B1*X).
86DGtal::SimpleLinearRegression::slope() const
92 * @return the intercept of the linear regression (B0 in Y=B0+B1*X).
96DGtal::SimpleLinearRegression::intercept() const
102 * Given a new x, predicts its y (hat{y}) according to the linear
105 * @param x any value.
106 * @return the estimated y value, ie hat{y} = B0 + B1*x.
110DGtal::SimpleLinearRegression::estimateY( double x ) const
112 return x * myB[ 1 ] + myB[ 0 ];
116 * @return the current estimation of the variance of the Gaussian
118 * perturbation (i.e. variance of U).
122DGtal::SimpleLinearRegression::estimateVariance() const
124 ASSERT( ( myN >= 3 ) && "[DGtal::SimpleLinearRegression::estimateVariance] need at least 3 datas to estimate variance.");
125 return myNormU2 / ( myN - 2 );
131DGtal::SimpleLinearRegression::~SimpleLinearRegression()
137 * The object is invalid.
139 * @param eps_zero the value below which the absolute value of the
140 * determinant is considered null.
142DGtal::SimpleLinearRegression::SimpleLinearRegression( double eps_zero )
143 : myEpsilonZero( eps_zero ), myN( 0 )
153DGtal::SimpleLinearRegression::clear()
168 * Computes the regression of the current parameters.
170 * @return 'true' if the regression was valid (non null number of
171 * samples, rank of X is 2), 'false' otherwise.
175DGtal::SimpleLinearRegression::computeRegression()
177 if ( myN <= 2 ) return false;
178 myD = myN * mySumX2 - ( mySumX * mySumX );
180 if ( ( myD > -myEpsilonZero ) && ( myD < myEpsilonZero ) )
185 myB[ 1 ] = ( -mySumX * mySumY + myN * mySumXY ) / myD;
186 myB[ 0 ] = mySumY/(double)myN - myB[ 1 ]*mySumX/(double)myN;
189 for ( unsigned int i = 0; i < myN; ++i )
191 double u = myY[ i ] - myB[ 0 ] - myB[ 1 ] * myX[ i ];
202 * Given a test confidence value (1-[a]), return the expected interval
203 * of value for Y, given a new [x], so that the model is still
204 * linear. One may thus check if a new pair (y,x) is still in the
205 * current linear model or not.
207 * @param x any x value.
209 * @param a the expected confidence value for the test (a=0.05
210 * means 95% of confidence).
212 * @return the expected interval [min_y, max_y] such that any
213 * value y within confirms the current linear model.
216std::pair<double,double>
217DGtal::SimpleLinearRegression::trustIntervalForY( const double x,
218 const double a ) const
220 double t = ( mySumX2 - 2.0 * x * mySumX + myN * x * x ) / myD;
221 double c = sqrt( estimateVariance() * ( 1 + t ) );
222 boost::math::students_t_distribution<double> T( myN - 2 );
223 double q = boost::math::quantile( T, 1.0 - a/2.0 );
224 return std::make_pair( estimateY( x ) - q*c, estimateY( x ) + q*c );
229///////////////////////////////////////////////////////////////////////////////
230// Interface - public :
233 * Writes/Displays the object on an output stream.
234 * @param that_stream the output stream where the object is written.
238DGtal::SimpleLinearRegression::selfDisplay( std::ostream& that_stream ) const
240 that_stream << "[SimpleLinearRegression] Number of samples="<< myN;
244 * Checks the validity/consistency of the object.
245 * @return 'true' if the object is valid, 'false' otherwise.
248DGtal::SimpleLinearRegression::isValid() const
255///////////////////////////////////////////////////////////////////////////////
256// Implementation of inline functions and external operators //
259 * Overloads 'operator<<' for displaying objects of class 'SimpleLinearRegression'.
260 * @param that_stream the output stream where the object is written.
261 * @param that_object_to_display the object of class 'SimpleLinearRegression' to write.
262 * @return the output stream after the writing.
265DGtal::operator<<( std::ostream & that_stream,
266 const SimpleLinearRegression & that_object_to_display )
268 that_object_to_display.selfDisplay( that_stream );
273///////////////////////////////////////////////////////////////////////////////