00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
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
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
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
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
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
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
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 }