Changeset 1093
- Timestamp:
- Jun 24, 2004, 8:51:20 PM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 4 edited
-
dataManip/psMinimize.c (modified) (13 diffs)
-
dataManip/psMinimize.h (modified) (1 diff)
-
math/psMinimize.c (modified) (13 diffs)
-
math/psMinimize.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/dataManip/psMinimize.c
r1086 r1093 19 19 #include "psFunctions.h" 20 20 #include "psSort.h" 21 #include "psMinimize.h" 21 22 #include "float.h" 22 23 #include <math.h> 23 // NOTE: rewrite so there is no maximum order for the polynomials. 24 #define MAX_POLY_ORDER 10 25 #define MAX_POLYNOMIAL_TERMS (((MAX_POLY_ORDER+1) * (MAX_POLY_ORDER + 2)) / 2) 26 int MyInfoLevel = 0; 27 24 25 #define MAX_LMM_NUM_ITERATIONS 500 28 26 typedef struct 29 27 { 30 28 size_t n; // Number of data points points in domain. 31 29 int count; // Number of non-masked parameters. 32 psVector *restrict initialGuess; 33 psImage *domain; // 34 psVector *data; 35 psVector *errors; 36 psVector *paramMask; 37 // The first argument to evalModel() and 38 // d_evalModel() specifies the data point. 39 // It must have the same size as the second 40 // dimension of *domain. 41 // The second argument must have the same size 42 // as *initialGuess and *paramMask. 30 psVector *restrict initialGuess; 31 const psImage *restrict domain; 32 const psVector *restrict data; 33 const psVector *restrict errors; 34 const psVector *restrict paramMask; 43 35 float (*evalModel) (psVector *, psVector *); 44 float (*d_evalModel) (psVector *, psVector * );36 float (*d_evalModel) (psVector *, psVector *, int); 45 37 } 46 38 psModelData; 39 // The first argument to evalModel() and 40 // d_evalModel() specifies the data point. 41 // It must have the same size as the second 42 // dimension of *domain. 43 // The second argument must have the same size 44 // as *initialGuess and *paramMask. 47 45 48 46 … … 65 63 for the user supplied function which is to be minimized. The GSL 66 64 minimization routines have no knowledge of the user-supplied function. They 67 only c lal this routine, which then calls the user-supplied function. The65 only call this routine, which then calls the user-supplied function. The 68 66 arguments are: 69 67 x: These are the parameter which are to be varied by GSL in order to 70 68 minimized chi2 over the data set. 71 69 params: 72 f 70 f: 73 71 74 72 … … 79 77 gsl_vector *f) 80 78 { 81 psImage *domain = ((psModelData *)params)->domain; 82 psVector *data = ((psModelData *)params)->data; 83 psVector *errors = ((psModelData *) params)->errors; 84 psVector *mask = ((psModelData *) params)->paramMask; 85 psVector *initialGuess = ((psModelData *)params)->initialGuess; 79 int i; // Loop index variable. 80 int j; // Loop index variable. 81 float tmpf; // Temporary floating point variable. 82 const psImage *restrict domain = ((psModelData *)params)->domain; 83 const psVector *restrict data = ((psModelData *)params)->data; 84 const psVector *restrict errors = ((psModelData *) params)->errors; 85 const psVector *restrict mask = ((psModelData *) params)->paramMask; 86 psVector *restrict initialGuess = ((psModelData *)params)->initialGuess; 87 float (*evalModel)(psVector *, psVector *) = ((psModelData *) params)->evalModel; 86 88 psVector *inputParameterList = NULL; 87 // float (*evalModel)(psVector *, psVector *) = ((psModelData *) params)->evalModel;88 size_t i; 89 int j; 90 float tmpf;91 92 // The GSL routines will call this function swith the masked parameters89 psVector *tmpVecPtr = NULL; 90 91 92 tmpVecPtr = psVectorAlloc(domain->numCols, PS_TYPE_F32); 93 94 // The GSL routines will call this function with the masked parameters 93 95 // removed. However, the user-supplied function (to be modified) does not 94 96 // have those parameters removed. Here will create a new parameter list … … 112 114 113 115 for (i=0;i<domain->numRows;i++) { 114 //GUS tmpf = evalModel(inputParameterList, domain->data.F32[i]); 116 for (j=0;j<tmpVecPtr->n;j++) { 117 tmpVecPtr->data.F32[j] = domain->data.F32[i][j]; 118 } 119 tmpf = evalModel(inputParameterList, tmpVecPtr); 115 120 gsl_vector_set(f, i, (tmpf - data->data.F32[i])/errors->data.F32[i]); 116 121 } 117 122 123 psFree(inputParameterList); 124 psFree(tmpVecPtr); 118 125 return GSL_SUCCESS; 119 126 } … … 123 130 gsl_matrix *J) 124 131 { 125 // size_t n = ((psModelData *)params)->n; 126 psImage *domain = ((psModelData *)params)->domain; 127 // psVector *data = ((psModelData *)params)->data; 128 psVector *errors = ((psModelData *) params)->errors; 129 psVector *mask = ((psModelData *) params)->paramMask; 130 psVector *initialGuess = ((psModelData *)params)->initialGuess; 132 const psImage *restrict domain = ((psModelData *)params)->domain; 133 const psVector *restrict errors = ((psModelData *) params)->errors; 134 const psVector *restrict mask = ((psModelData *) params)->paramMask; 135 psVector *restrict initialGuess = ((psModelData *)params)->initialGuess; 131 136 psVector *inputParameterList = NULL; 132 // int count = 0; 133 // float (*d_evalModel) = ((psModelData *) params)->evalModel; 137 psVector *tmpVecPtr = NULL; 138 float (*d_evalModel)(psVector *, psVector *, int) = ((psModelData *) params)->d_evalModel; 139 134 140 size_t i; 135 141 int j; 136 142 float tmpf; 143 144 tmpVecPtr = psVectorAlloc(domain->numCols, PS_TYPE_F32); 137 145 138 146 // The GSL routines will call this functions with the masked parameters … … 157 165 158 166 for (i=0;i<domain->numRows;i++) { 167 for (j=0;j<tmpVecPtr->n;j++) { 168 tmpVecPtr->data.F32[j] = domain->data.F32[i][j]; 169 } 170 159 171 for (j=0;j<inputParameterList->n;j++) { 160 //GUS tmpf = d_evalModel(inputParameterList, domain->data.F32[i], j); 161 172 tmpf = d_evalModel(inputParameterList, tmpVecPtr, j); 162 173 gsl_matrix_set(J, i, j, (tmpf/errors->data.F32[i])); 163 174 } 164 175 } 165 176 177 psFree(inputParameterList); 178 psFree(tmpVecPtr); 166 179 return GSL_SUCCESS; 167 180 } … … 185 198 psVector * 186 199 psMinimizeChi2(float (*evalModel)(const psVector *restrict, const psVector *restrict), 187 float (*DevalModel)( psVector *, psVector *),188 const ps Vector*restrict domain,200 float (*DevalModel)(const psVector *restrict, const psVector *restrict, int), 201 const psImage *restrict domain, 189 202 const psVector *restrict data, 190 203 const psVector *restrict errors, … … 193 206 float *chiSq) 194 207 { 195 size_t n = domain->n; 208 209 int numData = domain->numCols; // Number of data points 210 gsl_multifit_fdfsolver *s = NULL; // GSL data structure. 211 int status; // Return status for the GSL solver. 212 int i = 0; // Loop index variable. 213 int j = 0; // Loop index variable. 214 int iter = 0; // Iteration counter. 215 psModelData *inputData = NULL; // Contains data that the user-supplied 216 // function/derivate need. 217 gsl_multifit_function_fdf f; // GSL structure that contains the 218 // functions/derivative to be solved. 219 double *xInit = NULL; // The initial guess at the parameters 220 // with masked parameters removed. 196 221 const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; 197 gsl_multifit_fdfsolver *s = NULL; 198 int status; 199 size_t i = 0; 200 int j = 0; 201 size_t iter = 0; 202 psModelData *inputData = NULL; 203 gsl_multifit_function_fdf f; 204 double *xInit = NULL; 222 // This tells GSL to use the Levenberg- 223 // Marquardt algorithm for chi2 224 // minimization. 205 225 206 226 inputData = (psModelData *) psAlloc(sizeof(psModelData)); 207 inputData->n = n ;227 inputData->n = numData; 208 228 inputData->count = 0; 209 229 inputData->initialGuess = initialGuess; 210 //inputData->domain = domain;230 inputData->domain = domain; 211 231 // inputData->data = data; 212 232 // inputData->errors = errors; … … 226 246 } 227 247 228 229 230 248 // The initial guess at the parameters for the function are written into 231 249 // the vector inputParameterList. If the paramMask is not NULL, then those 232 // parameters are masked out. How can this possibly work? The user- 233 // supplied function will require a fixed number of parameters. 250 // parameters are masked out. 234 251 235 252 xInit = (double *) psAlloc(inputData->count * sizeof(double)); … … 257 274 r = gsl_rng_alloc(type); 258 275 276 // Initialize the main data structure used by the GSL solver. This will 277 // contain pointers to the function to be minimized, it's derivative 278 // function, the number of data points, the number of free parameters, 279 // and the data structures those functions use. 280 259 281 f.f = &gsl_function_f; 260 282 f.df = &gsl_function_df; 261 283 f.fdf = &gsl_my_function_fdf; 262 f.n = n ;284 f.n = numData; 263 285 f.p = inputData->count; 264 286 f.params = &inputData; 265 287 266 // This tells GSL to use the Levenberg-Marquardt algorithm for chi2 267 // minimization. 268 // T = gsl_multifit_fdfsolver_lmsder; 269 270 // Creates an instance of the GSL solver that we will be iterating on. 271 s = gsl_multifit_fdfsolver_alloc(T, n, inputData->count); 272 273 // Initialize the GSL minimizer. 288 // Create an instance of the GSL solver that we will be iterating on. 289 // It will have numData data points and inputData->count parameters. 290 s = gsl_multifit_fdfsolver_alloc(T, numData, inputData->count); 291 292 // Initialize the GSL minimizer to use function defined by the data 293 // structure "f" and x.vector as an initial guess for the parameters. 274 294 gsl_multifit_fdfsolver_set(s, &f, &x.vector); 275 295 276 // print_state(iter, s); 296 297 // Each iteration of the following loop will perform one step in an 298 // attempt to minimized chi-squared for the function. The loop exits 299 // either when the change in parameters is small enough, or when the 300 // maximum number of iterations is reached. 277 301 do { 278 302 iter++; … … 280 304 status = gsl_multifit_fdfsolver_iterate(s); 281 305 282 // printf("status = %s\n", gsl_strerror(status));283 // print_state(iter, s);284 285 306 // If there was a problem, abort. 286 307 if (status) { … … 288 309 } 289 310 290 // Checks whether the (L2-norm) computed derivative and the difference291 // between the real/actual for that test x-vector. If were close292 // enough exit loop.293 294 311 // Test if the parameters changed by a small enough amount. 295 312 status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4); 296 } while (status == GSL_CONTINUE && iter < 500); 297 298 299 300 313 } while (status == GSL_CONTINUE && iter < MAX_LMM_NUM_ITERATIONS); 314 315 316 // In the above steps we had removed the masked elements from the 317 // the solver. This next code blocks puts those masked elements 318 // into the solution. 301 319 if (paramMask != NULL) { 302 320 j = 0; … … 314 332 } 315 333 334 // Calculate the chi-squared for the derived solution. 316 335 *chiSq = gsl_blas_dnrm2(s->f); 336 337 // Free all allocated memory 338 // NOTE: Free x. 317 339 gsl_multifit_fdfsolver_free(s); 318 // Free all allocated memory319 340 psFree(xInit); 320 341 psFree(inputData); 321 342 343 // Bye bye. 322 344 return(initialGuess); 323 345 } 324 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 // NOTE: rewrite so there is no maximum order for the polynomials. 362 #define MAX_POLY_ORDER 10 363 #define MAX_POLYNOMIAL_TERMS (((MAX_POLY_ORDER+1) * (MAX_POLY_ORDER + 2)) / 2) 364 int MyInfoLevel = 0; 325 365 /** @brief This procedure calculates various combinations of powers of x and y 326 366 * and stores them in the data structure sums[][]. After it completes: -
trunk/psLib/src/dataManip/psMinimize.h
r974 r1093 12 12 */ 13 13 14 /** This routine must ninimize a particularnon-linear function */15 ps FloatArray*16 psMinimize(float (*myFunction)(const ps FloatArray*restrict), ///< Function to minimize17 ps FloatArray*restrict initialGuess, ///< Initial guess18 ps IntArray*restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant14 /** This routine must minimize a non-linear function */ 15 psVector * 16 psMinimize(float (*myFunction)(const psVector *restrict), ///< Function to minimize 17 psVector *restrict initialGuess, ///< Initial guess 18 psVector *restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant 19 19 ); 20 20 21 21 22 22 /** Minimize chi^2 for input data */ 23 psFloatArray * 24 psMinimizeChi2(float (*evalModel)(const psFloatArray *restrict, 25 const psFloatArray *restrict), ///< Model to fit; (domain and params) 26 const psFloatArray *restrict domain, ///< The domain values for the corresponding measurements 27 const psFloatArray *restrict data, ///< Data to fit 28 const psFloatArray *restrict errors, ///< Errors in the data 29 psFloatArray *restrict initialGuess, ///< Initial guess 30 const psIntArray *restrict paramMask ///< 1 = fit for parameter, 0 = hold parameter constant 23 psVector * 24 psMinimizeChi2(float (*evalModel)(const psVector *restrict, 25 const psVector *restrict), ///< Model to fit; (domain and params) 26 float (*DevalModel)(const psVector *restrict, 27 const psVector *restrict, 28 int), ///< Derivative of model to fit; (domain and params) 29 const psImage *restrict domain, ///< The domain values for the corresponding measurements 30 const psVector *restrict data, ///< Data to fit 31 const psVector *restrict errors, ///< Errors in the data 32 psVector *restrict initialGuess, ///< Initial guess 33 const psVector *restrict paramMask, ///< 1 = fit for parameter, 0 = hold parameter constant 34 float *chiSq 31 35 ); 32 36 33 /** Derive a polynomial fit by chi^2 minimisation --- can be done analytically*/37 /** Derive a polynomial fit by chi^2 minimisation (analytically) */ 34 38 psPolynomial1D * 35 39 psGetArrayPolynomial(psPolynomial1D myPoly, ///< Polynomial to fit 36 const ps FloatArray*restrict x, ///< Ordinates (or NULL to just use the indices)37 const ps FloatArray*restrict y, ///< Coordinates38 const ps FloatArray*restrict yErr ///< Errors in coordinates, or NULL40 const psVector *restrict x, ///< Ordinates (or NULL to just use the indices) 41 const psVector *restrict y, ///< Coordinates 42 const psVector *restrict yErr ///< Errors in coordinates, or NULL 39 43 ); 40 44 -
trunk/psLib/src/math/psMinimize.c
r1086 r1093 19 19 #include "psFunctions.h" 20 20 #include "psSort.h" 21 #include "psMinimize.h" 21 22 #include "float.h" 22 23 #include <math.h> 23 // NOTE: rewrite so there is no maximum order for the polynomials. 24 #define MAX_POLY_ORDER 10 25 #define MAX_POLYNOMIAL_TERMS (((MAX_POLY_ORDER+1) * (MAX_POLY_ORDER + 2)) / 2) 26 int MyInfoLevel = 0; 27 24 25 #define MAX_LMM_NUM_ITERATIONS 500 28 26 typedef struct 29 27 { 30 28 size_t n; // Number of data points points in domain. 31 29 int count; // Number of non-masked parameters. 32 psVector *restrict initialGuess; 33 psImage *domain; // 34 psVector *data; 35 psVector *errors; 36 psVector *paramMask; 37 // The first argument to evalModel() and 38 // d_evalModel() specifies the data point. 39 // It must have the same size as the second 40 // dimension of *domain. 41 // The second argument must have the same size 42 // as *initialGuess and *paramMask. 30 psVector *restrict initialGuess; 31 const psImage *restrict domain; 32 const psVector *restrict data; 33 const psVector *restrict errors; 34 const psVector *restrict paramMask; 43 35 float (*evalModel) (psVector *, psVector *); 44 float (*d_evalModel) (psVector *, psVector * );36 float (*d_evalModel) (psVector *, psVector *, int); 45 37 } 46 38 psModelData; 39 // The first argument to evalModel() and 40 // d_evalModel() specifies the data point. 41 // It must have the same size as the second 42 // dimension of *domain. 43 // The second argument must have the same size 44 // as *initialGuess and *paramMask. 47 45 48 46 … … 65 63 for the user supplied function which is to be minimized. The GSL 66 64 minimization routines have no knowledge of the user-supplied function. They 67 only c lal this routine, which then calls the user-supplied function. The65 only call this routine, which then calls the user-supplied function. The 68 66 arguments are: 69 67 x: These are the parameter which are to be varied by GSL in order to 70 68 minimized chi2 over the data set. 71 69 params: 72 f 70 f: 73 71 74 72 … … 79 77 gsl_vector *f) 80 78 { 81 psImage *domain = ((psModelData *)params)->domain; 82 psVector *data = ((psModelData *)params)->data; 83 psVector *errors = ((psModelData *) params)->errors; 84 psVector *mask = ((psModelData *) params)->paramMask; 85 psVector *initialGuess = ((psModelData *)params)->initialGuess; 79 int i; // Loop index variable. 80 int j; // Loop index variable. 81 float tmpf; // Temporary floating point variable. 82 const psImage *restrict domain = ((psModelData *)params)->domain; 83 const psVector *restrict data = ((psModelData *)params)->data; 84 const psVector *restrict errors = ((psModelData *) params)->errors; 85 const psVector *restrict mask = ((psModelData *) params)->paramMask; 86 psVector *restrict initialGuess = ((psModelData *)params)->initialGuess; 87 float (*evalModel)(psVector *, psVector *) = ((psModelData *) params)->evalModel; 86 88 psVector *inputParameterList = NULL; 87 // float (*evalModel)(psVector *, psVector *) = ((psModelData *) params)->evalModel;88 size_t i; 89 int j; 90 float tmpf;91 92 // The GSL routines will call this function swith the masked parameters89 psVector *tmpVecPtr = NULL; 90 91 92 tmpVecPtr = psVectorAlloc(domain->numCols, PS_TYPE_F32); 93 94 // The GSL routines will call this function with the masked parameters 93 95 // removed. However, the user-supplied function (to be modified) does not 94 96 // have those parameters removed. Here will create a new parameter list … … 112 114 113 115 for (i=0;i<domain->numRows;i++) { 114 //GUS tmpf = evalModel(inputParameterList, domain->data.F32[i]); 116 for (j=0;j<tmpVecPtr->n;j++) { 117 tmpVecPtr->data.F32[j] = domain->data.F32[i][j]; 118 } 119 tmpf = evalModel(inputParameterList, tmpVecPtr); 115 120 gsl_vector_set(f, i, (tmpf - data->data.F32[i])/errors->data.F32[i]); 116 121 } 117 122 123 psFree(inputParameterList); 124 psFree(tmpVecPtr); 118 125 return GSL_SUCCESS; 119 126 } … … 123 130 gsl_matrix *J) 124 131 { 125 // size_t n = ((psModelData *)params)->n; 126 psImage *domain = ((psModelData *)params)->domain; 127 // psVector *data = ((psModelData *)params)->data; 128 psVector *errors = ((psModelData *) params)->errors; 129 psVector *mask = ((psModelData *) params)->paramMask; 130 psVector *initialGuess = ((psModelData *)params)->initialGuess; 132 const psImage *restrict domain = ((psModelData *)params)->domain; 133 const psVector *restrict errors = ((psModelData *) params)->errors; 134 const psVector *restrict mask = ((psModelData *) params)->paramMask; 135 psVector *restrict initialGuess = ((psModelData *)params)->initialGuess; 131 136 psVector *inputParameterList = NULL; 132 // int count = 0; 133 // float (*d_evalModel) = ((psModelData *) params)->evalModel; 137 psVector *tmpVecPtr = NULL; 138 float (*d_evalModel)(psVector *, psVector *, int) = ((psModelData *) params)->d_evalModel; 139 134 140 size_t i; 135 141 int j; 136 142 float tmpf; 143 144 tmpVecPtr = psVectorAlloc(domain->numCols, PS_TYPE_F32); 137 145 138 146 // The GSL routines will call this functions with the masked parameters … … 157 165 158 166 for (i=0;i<domain->numRows;i++) { 167 for (j=0;j<tmpVecPtr->n;j++) { 168 tmpVecPtr->data.F32[j] = domain->data.F32[i][j]; 169 } 170 159 171 for (j=0;j<inputParameterList->n;j++) { 160 //GUS tmpf = d_evalModel(inputParameterList, domain->data.F32[i], j); 161 172 tmpf = d_evalModel(inputParameterList, tmpVecPtr, j); 162 173 gsl_matrix_set(J, i, j, (tmpf/errors->data.F32[i])); 163 174 } 164 175 } 165 176 177 psFree(inputParameterList); 178 psFree(tmpVecPtr); 166 179 return GSL_SUCCESS; 167 180 } … … 185 198 psVector * 186 199 psMinimizeChi2(float (*evalModel)(const psVector *restrict, const psVector *restrict), 187 float (*DevalModel)( psVector *, psVector *),188 const ps Vector*restrict domain,200 float (*DevalModel)(const psVector *restrict, const psVector *restrict, int), 201 const psImage *restrict domain, 189 202 const psVector *restrict data, 190 203 const psVector *restrict errors, … … 193 206 float *chiSq) 194 207 { 195 size_t n = domain->n; 208 209 int numData = domain->numCols; // Number of data points 210 gsl_multifit_fdfsolver *s = NULL; // GSL data structure. 211 int status; // Return status for the GSL solver. 212 int i = 0; // Loop index variable. 213 int j = 0; // Loop index variable. 214 int iter = 0; // Iteration counter. 215 psModelData *inputData = NULL; // Contains data that the user-supplied 216 // function/derivate need. 217 gsl_multifit_function_fdf f; // GSL structure that contains the 218 // functions/derivative to be solved. 219 double *xInit = NULL; // The initial guess at the parameters 220 // with masked parameters removed. 196 221 const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; 197 gsl_multifit_fdfsolver *s = NULL; 198 int status; 199 size_t i = 0; 200 int j = 0; 201 size_t iter = 0; 202 psModelData *inputData = NULL; 203 gsl_multifit_function_fdf f; 204 double *xInit = NULL; 222 // This tells GSL to use the Levenberg- 223 // Marquardt algorithm for chi2 224 // minimization. 205 225 206 226 inputData = (psModelData *) psAlloc(sizeof(psModelData)); 207 inputData->n = n ;227 inputData->n = numData; 208 228 inputData->count = 0; 209 229 inputData->initialGuess = initialGuess; 210 //inputData->domain = domain;230 inputData->domain = domain; 211 231 // inputData->data = data; 212 232 // inputData->errors = errors; … … 226 246 } 227 247 228 229 230 248 // The initial guess at the parameters for the function are written into 231 249 // the vector inputParameterList. If the paramMask is not NULL, then those 232 // parameters are masked out. How can this possibly work? The user- 233 // supplied function will require a fixed number of parameters. 250 // parameters are masked out. 234 251 235 252 xInit = (double *) psAlloc(inputData->count * sizeof(double)); … … 257 274 r = gsl_rng_alloc(type); 258 275 276 // Initialize the main data structure used by the GSL solver. This will 277 // contain pointers to the function to be minimized, it's derivative 278 // function, the number of data points, the number of free parameters, 279 // and the data structures those functions use. 280 259 281 f.f = &gsl_function_f; 260 282 f.df = &gsl_function_df; 261 283 f.fdf = &gsl_my_function_fdf; 262 f.n = n ;284 f.n = numData; 263 285 f.p = inputData->count; 264 286 f.params = &inputData; 265 287 266 // This tells GSL to use the Levenberg-Marquardt algorithm for chi2 267 // minimization. 268 // T = gsl_multifit_fdfsolver_lmsder; 269 270 // Creates an instance of the GSL solver that we will be iterating on. 271 s = gsl_multifit_fdfsolver_alloc(T, n, inputData->count); 272 273 // Initialize the GSL minimizer. 288 // Create an instance of the GSL solver that we will be iterating on. 289 // It will have numData data points and inputData->count parameters. 290 s = gsl_multifit_fdfsolver_alloc(T, numData, inputData->count); 291 292 // Initialize the GSL minimizer to use function defined by the data 293 // structure "f" and x.vector as an initial guess for the parameters. 274 294 gsl_multifit_fdfsolver_set(s, &f, &x.vector); 275 295 276 // print_state(iter, s); 296 297 // Each iteration of the following loop will perform one step in an 298 // attempt to minimized chi-squared for the function. The loop exits 299 // either when the change in parameters is small enough, or when the 300 // maximum number of iterations is reached. 277 301 do { 278 302 iter++; … … 280 304 status = gsl_multifit_fdfsolver_iterate(s); 281 305 282 // printf("status = %s\n", gsl_strerror(status));283 // print_state(iter, s);284 285 306 // If there was a problem, abort. 286 307 if (status) { … … 288 309 } 289 310 290 // Checks whether the (L2-norm) computed derivative and the difference291 // between the real/actual for that test x-vector. If were close292 // enough exit loop.293 294 311 // Test if the parameters changed by a small enough amount. 295 312 status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4); 296 } while (status == GSL_CONTINUE && iter < 500); 297 298 299 300 313 } while (status == GSL_CONTINUE && iter < MAX_LMM_NUM_ITERATIONS); 314 315 316 // In the above steps we had removed the masked elements from the 317 // the solver. This next code blocks puts those masked elements 318 // into the solution. 301 319 if (paramMask != NULL) { 302 320 j = 0; … … 314 332 } 315 333 334 // Calculate the chi-squared for the derived solution. 316 335 *chiSq = gsl_blas_dnrm2(s->f); 336 337 // Free all allocated memory 338 // NOTE: Free x. 317 339 gsl_multifit_fdfsolver_free(s); 318 // Free all allocated memory319 340 psFree(xInit); 320 341 psFree(inputData); 321 342 343 // Bye bye. 322 344 return(initialGuess); 323 345 } 324 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 // NOTE: rewrite so there is no maximum order for the polynomials. 362 #define MAX_POLY_ORDER 10 363 #define MAX_POLYNOMIAL_TERMS (((MAX_POLY_ORDER+1) * (MAX_POLY_ORDER + 2)) / 2) 364 int MyInfoLevel = 0; 325 365 /** @brief This procedure calculates various combinations of powers of x and y 326 366 * and stores them in the data structure sums[][]. After it completes: -
trunk/psLib/src/math/psMinimize.h
r974 r1093 12 12 */ 13 13 14 /** This routine must ninimize a particularnon-linear function */15 ps FloatArray*16 psMinimize(float (*myFunction)(const ps FloatArray*restrict), ///< Function to minimize17 ps FloatArray*restrict initialGuess, ///< Initial guess18 ps IntArray*restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant14 /** This routine must minimize a non-linear function */ 15 psVector * 16 psMinimize(float (*myFunction)(const psVector *restrict), ///< Function to minimize 17 psVector *restrict initialGuess, ///< Initial guess 18 psVector *restrict paramMask //!< 1 = fit for parameter, 0 = hold parameter constant 19 19 ); 20 20 21 21 22 22 /** Minimize chi^2 for input data */ 23 psFloatArray * 24 psMinimizeChi2(float (*evalModel)(const psFloatArray *restrict, 25 const psFloatArray *restrict), ///< Model to fit; (domain and params) 26 const psFloatArray *restrict domain, ///< The domain values for the corresponding measurements 27 const psFloatArray *restrict data, ///< Data to fit 28 const psFloatArray *restrict errors, ///< Errors in the data 29 psFloatArray *restrict initialGuess, ///< Initial guess 30 const psIntArray *restrict paramMask ///< 1 = fit for parameter, 0 = hold parameter constant 23 psVector * 24 psMinimizeChi2(float (*evalModel)(const psVector *restrict, 25 const psVector *restrict), ///< Model to fit; (domain and params) 26 float (*DevalModel)(const psVector *restrict, 27 const psVector *restrict, 28 int), ///< Derivative of model to fit; (domain and params) 29 const psImage *restrict domain, ///< The domain values for the corresponding measurements 30 const psVector *restrict data, ///< Data to fit 31 const psVector *restrict errors, ///< Errors in the data 32 psVector *restrict initialGuess, ///< Initial guess 33 const psVector *restrict paramMask, ///< 1 = fit for parameter, 0 = hold parameter constant 34 float *chiSq 31 35 ); 32 36 33 /** Derive a polynomial fit by chi^2 minimisation --- can be done analytically*/37 /** Derive a polynomial fit by chi^2 minimisation (analytically) */ 34 38 psPolynomial1D * 35 39 psGetArrayPolynomial(psPolynomial1D myPoly, ///< Polynomial to fit 36 const ps FloatArray*restrict x, ///< Ordinates (or NULL to just use the indices)37 const ps FloatArray*restrict y, ///< Coordinates38 const ps FloatArray*restrict yErr ///< Errors in coordinates, or NULL40 const psVector *restrict x, ///< Ordinates (or NULL to just use the indices) 41 const psVector *restrict y, ///< Coordinates 42 const psVector *restrict yErr ///< Errors in coordinates, or NULL 39 43 ); 40 44
Note:
See TracChangeset
for help on using the changeset viewer.
