leastsqs.cxx

00001 // leastsqs.c -- Implements a simple linear least squares best fit routine
00002 //
00003 // Written by Curtis Olson, started September 1997.
00004 //
00005 // Copyright (C) 1997  Curtis L. Olson  - http://www.flightgear.org/~curt
00006 //
00007 // This library is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Library General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 2 of the License, or (at your option) any later version.
00011 //
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Library General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020 //
00021 // $Id: leastsqs_8cxx-source.html,v 1.15 2007-12-17 15:37:05 curt Exp $
00022 //
00023 
00024 
00025 #include <stdio.h>
00026 
00027 #include "leastsqs.hxx"
00028 
00029 
00030 /* 
00031 Least squares fit:
00032 
00033 y = b0 + b1x
00034 
00035      n*sum(xi*yi) - (sum(xi)*sum(yi))
00036 b1 = --------------------------------
00037      n*sum(xi^2) - (sum(xi))^2
00038 
00039 
00040 b0 = sum(yi)/n - b1*(sum(xi)/n)
00041 */
00042 
00043 double sum_xi, sum_yi, sum_xi_2, sum_xi_yi;
00044 int sum_n;
00045 
00046 void least_squares(double *x, double *y, int n, double *m, double *b) {
00047     int i;
00048 
00049     sum_xi = sum_yi = sum_xi_2 = sum_xi_yi = 0.0;
00050     sum_n = n;
00051 
00052     for ( i = 0; i < n; i++ ) {
00053         sum_xi += x[i];
00054         sum_yi += y[i];
00055         sum_xi_2 += x[i] * x[i];
00056         sum_xi_yi += x[i] * y[i];
00057     }
00058 
00059     /* printf("sum(xi)=%.2f  sum(yi)=%.2f  sum(xi^2)=%.2f  sum(xi*yi)=%.2f\n",
00060            sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
00061 
00062     *m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) / 
00063         ( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
00064     *b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
00065 
00066     /* printf("slope = %.2f  intercept = %.2f\n", *m, *b); */
00067 }
00068 
00069 
00070 /* incrimentally update existing values with a new data point */
00071 void least_squares_update(double x, double y, double *m, double *b) {
00072     ++sum_n;
00073 
00074     sum_xi += x;
00075     sum_yi += y;
00076     sum_xi_2 += x * x;
00077     sum_xi_yi += x * y;
00078 
00079     /* printf("sum(xi)=%.2f  sum(yi)=%.2f  sum(xi^2)=%.2f  sum(xi*yi)=%.2f\n",
00080            sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
00081 
00082     *m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) / 
00083         ( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
00084     *b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
00085 
00086     /* printf("slope = %.2f  intercept = %.2f\n", *m, *b); */
00087 }
00088 
00089 
00090 /* 
00091   return the least squares error:
00092 
00093               (y[i] - y_hat[i])^2
00094               -------------------
00095                       n
00096  */
00097 double least_squares_error(double *x, double *y, int n, double m, double b) {
00098     int i;
00099     double error, sum;
00100 
00101     sum = 0.0;
00102 
00103     for ( i = 0; i < n; i++ ) {
00104         error = y[i] - (m * x[i] + b);
00105         sum += error * error;
00106         // printf("%.2f %.2f\n", error, sum);
00107     }
00108 
00109     return ( sum / (double)n );
00110 }
00111 
00112 
00113 /* 
00114   return the maximum least squares error:
00115 
00116               (y[i] - y_hat[i])^2
00117  */
00118 double least_squares_max_error(double *x, double *y, int n, double m, double b){
00119     int i;
00120     double error, max_error;
00121 
00122     max_error = 0.0;
00123 
00124     for ( i = 0; i < n; i++ ) {
00125         error = y[i] - (m * x[i] + b);
00126         error = error * error;
00127         if ( error > max_error ) {
00128             max_error = error;
00129         }
00130     }
00131 
00132     return ( max_error );
00133 }
00134 
00135 

Generated on Mon Dec 17 09:30:54 2007 for SimGear by  doxygen 1.5.1