source: tags/release-1.1.4/src/Utils/linear_regression.cc @ 1441

Last change on this file since 1441 was 301, checked in by Matthew Whiting, 17 years ago

Mostly adding the distribution text to the start of files, with a few additional comments added too.

File size: 4.0 KB
Line 
1// -----------------------------------------------------------------------
2// linear_regression.cc: Performs linear regression on a set of (x,y)
3//                       values.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <math.h>
31int linear_regression(int num, float *x, float *y, int ilow, int ihigh, float &slope, float &errSlope, float &intercept, float &errIntercept, float &r)
32{
33  /**
34   * Computes the linear best fit to data: $y=a x + b$, where $x$ and
35   * $y$ are arrays of size num, $a$ is the slope and $b$ the
36   * y-intercept.  The values used in the arrays are those from ilow
37   * to ihigh.  (ie. if the full arrays are being used, then ilow=0
38   * and ihigh=num-1.  Returns the values of slope & intercept (with
39   * errors) as well as r, the regression coefficient.
40   *
41   * \param num Size of the x & y arrays.
42   * \param x   Array of abscissae.
43   * \param y   Array of ordinates.
44   * \param ilow Minimum index of the arrays to be used (ilow=0 means
45   *             start at the beginning).
46   * \param ihigh Maximum index of the arrays to be used (ihigh=num-1
47   *              means finish at the end).
48   * \param slope Returns value of the slope of the best fit line.
49   * \param errSlope Returns value of the estimated error in the slope
50   *                  value.
51   * \param intercept Returns value of the y-intercept of the best fit
52   *                  line.
53   * \param errIntercept Returns value of the estimated error in the
54   *                     value of the y-intercept.
55   * \param r Returns the value of the regression coefficient.
56   * \return If everything works, returns 0. If slope is infinite (eg,
57   * all points have same x value), returns 1.
58   */
59
60  if (ilow>ihigh) {
61    std::cerr << "Error! linear_regression.cc :: ilow (" << ilow
62              << ") > ihigh (" << ihigh << ")!!\n";
63    return 1;
64  }
65  if (ihigh>num-1) {
66    std::cerr << "Error! linear_regression.cc :: ihigh (" <<ihigh
67              << ") out of bounds of array (>" << num-1 << ")!!\n";
68    return 1;
69  }
70  if(ilow<0){
71    std::cerr << "Error! linear_regression.cc :: ilow (" << ilow
72              << ") < 0. !!\n";
73    return 1;
74  }
75
76  double sumx,sumy,sumxx,sumxy,sumyy;
77  sumx=0.;
78  sumy=0.;
79  sumxx=0.;
80  sumxy=0.;
81  sumyy=0.;
82  int count=0;
83  for (int i=ilow;i<=ihigh;i++){
84    count++;
85    sumx = sumx + x[i];
86    sumy = sumy + y[i];
87    sumxx = sumxx + x[i]*x[i];
88    sumxy = sumxy + x[i]*y[i];
89    sumyy = sumyy + y[i]*y[i];
90  }
91
92  const float SMALLTHING=1.e-6;
93  if(fabs(count*sumxx-sumx*sumx)<SMALLTHING) return 1;
94  else{
95
96    slope = (count*sumxy - sumx*sumy)/(count*sumxx - sumx*sumx);
97    errSlope = count / (count*sumxx - sumx*sumx);
98
99    intercept = (sumy*sumxx - sumxy*sumx)/(count*sumxx - sumx*sumx);
100    errIntercept = sumxx / (count*sumxx - sumx*sumx);
101   
102    r = (count*sumxy - sumx*sumy) /
103      (sqrt(count*sumxx-sumx*sumx) * sqrt(count*sumyy-sumy*sumy) );
104
105    return 0;
106
107  }
108}
Note: See TracBrowser for help on using the repository browser.