Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

least_squares.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 1993,1994,1995 David MacDonald, 00004 McConnell Brain Imaging Centre, 00005 Montreal Neurological Institute, McGill University. 00006 Permission to use, copy, modify, and distribute this 00007 software and its documentation for any purpose and without 00008 fee is hereby granted, provided that the above copyright 00009 notice appear in all copies. The author and McGill University 00010 make no representations about the suitability of this 00011 software for any purpose. It is provided "as is" without 00012 express or implied warranty. 00013 ---------------------------------------------------------------------------- */ 00014 00015 #include <volume_io/internal_volume_io.h> 00016 #include <bicpl/geom.h> 00017 #include <bicpl/numerical.h> 00018 00019 #ifndef lint 00020 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Numerical/least_squares.c,v 1.8 2000/02/06 15:30:40 stever Exp $"; 00021 #endif 00022 00023 /* ----------------------------- MNI Header ----------------------------------- 00024 @NAME : least_squares 00025 @INPUT : n_points 00026 n_dims 00027 points 00028 values 00029 @OUTPUT : parameters 00030 @RETURNS : 00031 @DESCRIPTION: Computes the standard problem of a least squares fit of the 00032 equation: 00033 values(points[i]) = parameters[0] + 00034 parameters[1] * points[i][0] + 00035 parameters[2] * points[i][1] + 00036 ... 00037 parameters[n_dims] * points[i][n_dims-1]. 00038 00039 @METHOD : 00040 @GLOBALS : 00041 @CALLS : 00042 @CREATED : 1993 David MacDonald 00043 @MODIFIED : 00044 ---------------------------------------------------------------------------- */ 00045 00046 public BOOLEAN least_squares( 00047 int n_points, 00048 int n_dims, 00049 Real **points, 00050 Real values[], 00051 Real parameters[] ) 00052 { 00053 int pt, i; 00054 linear_least_squares lsq; 00055 Real *p; 00056 BOOLEAN success; 00057 00058 initialize_linear_least_squares( &lsq, n_dims+1 ); 00059 00060 ALLOC( p, n_dims+1 ); 00061 00062 for_less( pt, 0, n_points ) 00063 { 00064 p[0] = 1.0; 00065 for_less( i, 0, n_dims ) 00066 p[i+1] = points[pt][i]; 00067 00068 add_to_linear_least_squares( &lsq, p, values[pt] ); 00069 } 00070 00071 FREE( p ); 00072 00073 success = get_linear_least_squares_solution( &lsq, parameters ); 00074 00075 delete_linear_least_squares( &lsq ); 00076 00077 return( success ); 00078 } 00079 00080 /* ----------------------------- MNI Header ----------------------------------- 00081 @NAME : initialize_linear_least_squares 00082 @INPUT : lsq 00083 n_parameters 00084 @OUTPUT : 00085 @RETURNS : 00086 @DESCRIPTION: Initializes the general least squares structure. 00087 @METHOD : 00088 @GLOBALS : 00089 @CALLS : 00090 @CREATED : 1993 David MacDonald 00091 @MODIFIED : 00092 ---------------------------------------------------------------------------- */ 00093 00094 public void initialize_linear_least_squares( 00095 linear_least_squares *lsq, 00096 int n_parameters ) 00097 { 00098 int i, j; 00099 00100 lsq->n_parameters = n_parameters; 00101 00102 if( n_parameters > 0 ) 00103 { 00104 ALLOC2D( lsq->second_derivs, n_parameters, n_parameters ); 00105 ALLOC( lsq->constants, n_parameters ); 00106 00107 for_less( i, 0, n_parameters ) 00108 { 00109 for_less( j, 0, n_parameters ) 00110 lsq->second_derivs[i][j] = 0.0; 00111 lsq->constants[i] = 0.0; 00112 } 00113 } 00114 } 00115 00116 /* ----------------------------- MNI Header ----------------------------------- 00117 @NAME : add_to_linear_least_squares 00118 @INPUT : lsq 00119 parameter_coefs[n_parameters] 00120 constant 00121 @OUTPUT : 00122 @RETURNS : 00123 @DESCRIPTION: Adds to the linear least squares. For instance if you 00124 are solving for: 00125 00126 minimize sum ( a * x + b * y + c - z )^2 00127 a,b,c n i i i 00128 00129 Then you would call this function n times, each time with 00130 parameter_coefs[0] = x[i], 00131 parameter_coefs[1] = y[i], 00132 constant = z[i], 00133 @METHOD : 00134 @GLOBALS : 00135 @CALLS : 00136 @CREATED : 1993 David MacDonald 00137 @MODIFIED : 00138 ---------------------------------------------------------------------------- */ 00139 00140 public void add_to_linear_least_squares( 00141 linear_least_squares *lsq, 00142 Real parameter_coefs[], 00143 Real constant ) 00144 { 00145 int i, j; 00146 00147 for_less( i, 0, lsq->n_parameters ) 00148 { 00149 for_less( j, i, lsq->n_parameters ) 00150 lsq->second_derivs[i][j] += parameter_coefs[i] * parameter_coefs[j]; 00151 00152 lsq->constants[i] += parameter_coefs[i] * constant; 00153 } 00154 } 00155 00156 /* ----------------------------- MNI Header ----------------------------------- 00157 @NAME : get_linear_least_squares_solution 00158 @INPUT : lsq 00159 @OUTPUT : solution 00160 @RETURNS : TRUE if successful 00161 @DESCRIPTION: Returns the solution to the linear least squares problem. 00162 @METHOD : 00163 @GLOBALS : 00164 @CALLS : 00165 @CREATED : 1993 David MacDonald 00166 @MODIFIED : 00167 ---------------------------------------------------------------------------- */ 00168 00169 public BOOLEAN get_linear_least_squares_solution( 00170 linear_least_squares *lsq, 00171 Real solution[] ) 00172 { 00173 BOOLEAN solved; 00174 int i, j; 00175 00176 for_less( i, 0, lsq->n_parameters ) 00177 { 00178 for_less( j, i+1, lsq->n_parameters ) 00179 lsq->second_derivs[j][i] = lsq->second_derivs[i][j]; 00180 } 00181 00182 solved = solve_linear_system( lsq->n_parameters, lsq->second_derivs, 00183 lsq->constants, solution ); 00184 00185 if( !solved ) 00186 { 00187 print_error( 00188 "Could not solve least squares, non-invertible matrix.\n" ); 00189 00190 for_less( i, 0, lsq->n_parameters ) 00191 solution[i] = 0.0; 00192 } 00193 00194 return( solved ); 00195 } 00196 00197 /* ----------------------------- MNI Header ----------------------------------- 00198 @NAME : delete_linear_least_squares 00199 @INPUT : lsq 00200 @OUTPUT : 00201 @RETURNS : 00202 @DESCRIPTION: Deletes the linear least squares structure. 00203 @METHOD : 00204 @GLOBALS : 00205 @CALLS : 00206 @CREATED : 1993 David MacDonald 00207 @MODIFIED : 00208 ---------------------------------------------------------------------------- */ 00209 00210 public void delete_linear_least_squares( 00211 linear_least_squares *lsq ) 00212 { 00213 FREE2D( lsq->second_derivs ); 00214 FREE( lsq->constants ); 00215 }

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7