Changeset 1128 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Jun 29, 2004, 1:21:08 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r1123 r1128 5 5 #include <float.h> 6 6 #include <math.h> 7 8 #include <gsl/gsl_multifit_nlin.h> 9 #include <gsl/gsl_rng.h> 10 #include <gsl/gsl_randist.h> 11 #include <gsl/gsl_vector.h> 12 #include <gsl/gsl_blas.h> 7 13 8 14 #include "psMemory.h" … … 18 24 #include <math.h> 19 25 20 #include <gsl/gsl_multifit_nlin.h>21 #include <gsl/gsl_rng.h>22 #include <gsl/gsl_randist.h>23 #include <gsl/gsl_vector.h>24 #include <gsl/gsl_blas.h>25 26 26 #define MAX_LMM_NUM_ITERATIONS 500 27 27 typedef struct … … 45 45 // The second argument must have the same size 46 46 // as *initialGuess and *paramMask. 47 48 49 50 #define NUM_DATA 40 51 52 53 struct data 54 { 55 size_t n; 56 double *y; 57 double *sigma; 58 }; 59 60 /****************************************************************************** 61 expb_f(x, params, f): This function performs 62 63 x: these are the parameters of the function that must be determined. 64 params: the actual input data is here. 65 params->n the number of input data points 66 params->y the data range 67 params->sigma the errors associated with each data point. 68 f: the result is returned here. Actually, it is the function evaluated 69 at the data point, minus the expected value of the function, and then 70 divided by the errors. 71 *****************************************************************************/ 72 int expb_f(const gsl_vector *x, 73 void *params, 74 gsl_vector *f) 75 { 76 size_t n = ((struct data *)params)->n; 77 double *y = ((struct data *)params)->y; 78 double *sigma = ((struct data *) params)->sigma; 79 double A; 80 double lambda; 81 double b; 82 int i; 83 double Yi; 84 85 A = gsl_vector_get(x, 0); 86 lambda = gsl_vector_get(x, 1); 87 b = gsl_vector_get(x, 2); 88 for (i = 0; i < n; i++) { 89 Yi = A * exp(-lambda * ((double) i)) + b; 90 Yi = (Yi - y[i]) / sigma[i]; 91 gsl_vector_set(f, i, Yi); 92 printf("gsl_vector_set(outData, %d, %.1f)\n", i, 93 gsl_vector_get(f, i)); 94 95 // printf("--------- expb_f((%.1f) %.1f %.1f %.1f) is %.1f [%.1f] ---------\n", 96 // (double) i, A, lambda, b, A * exp(-lambda * ((double) i)) + b, 97 // Yi); 98 } 99 100 return GSL_SUCCESS; 101 } 102 103 /****************************************************************************** 104 *****************************************************************************/ 105 int expb_df(const gsl_vector *x, 106 void *params, 107 gsl_matrix *J) 108 { 109 size_t n = ((struct data *)params)->n; 110 double *sigma = ((struct data *) params)->sigma; 111 double t, s, e; 112 size_t i, j; 113 114 double A = gsl_vector_get(x, 0); 115 double lambda = gsl_vector_get(x, 1); 116 117 118 for (i = 0; i < n; i++) { 119 // Jacobian matrix J(i,j) = dfi / dxj, 120 // where fi = (Yi - yi)/sigma[i], 121 // Yi = A * exp(-lambda * i) + b 122 // and the xj are the parameters (A,lambda,b) 123 t = i; 124 s = sigma[i]; 125 e = exp(-lambda *t); 126 gsl_matrix_set(J, i, 0, e/s); 127 gsl_matrix_set(J, i, 1, -t * A * e/s); 128 gsl_matrix_set(J, i, 2, 1/s); 129 // printf("--------- myFuncDeriv((%.1f) %.1f %.1f %.1f (%d)) is %.1f [%.1f] ---------\n", 130 // (double) i, A, lambda, gsl_vector_get(x, 2), 0, e, e/s); 131 // printf("--------- myFuncDeriv((%.1f) %.1f %.1f %.1f (%d)) is %.1f [%.1f] ---------\n", 132 // (double) i, A, lambda, gsl_vector_get(x, 2), 1, -t * A * e, -t * A * e/s); 133 // printf("--------- myFuncDeriv((%.1f) %.1f %.1f %.1f (%d)) is %.1f [%.1f] ---------\n", 134 // (double) i, A, lambda, gsl_vector_get(x, 2), 2, 1.0, 1.0/s); 135 for (j=0;j<3;j++) { 136 printf("gsl_matrix_set(J, %d, %d, %.1f)\n", i, j, 137 gsl_matrix_get(J, i, j)); 138 } 139 140 141 } 142 143 return GSL_SUCCESS; 144 } 145 146 /****************************************************************************** 147 *****************************************************************************/ 148 int expb_fdf(const gsl_vector *x, 149 void *params, 150 gsl_vector *f, gsl_matrix *J) 151 { 152 expb_f (x, params, f); 153 expb_df (x, params, J); 154 155 return GSL_SUCCESS; 156 } 157 158 159 47 160 48 161 … … 104 217 105 218 if (mask != NULL) { 219 printf("--------------- WHOA ---------------: MASK NOT NULL\n"); 106 220 j = 0; 107 221 for (i=0;i<mask->n;i++) { … … 122 236 123 237 for (i=0;i<domain->numRows;i++) { 124 printf("Data item %d is ( ", i);238 // printf("Data item %d is ( ", i); 125 239 for (j=0;j<domain->numCols;j++) { 126 240 tmpVecPtr->data.F32[j] = domain->data.F32[i][j]; 127 printf("%.1f ", tmpVecPtr->data.F32[j]);241 // printf("%.1f ", tmpVecPtr->data.F32[j]); 128 242 } 129 243 tmpf = evalModel(tmpVecPtr, inputParameterList); 130 printf(" ). Output is %.1f\n", tmpf);244 // printf(" ). Output is %.1f\n", tmpf); 131 245 132 246 gsl_vector_set(outData, i, (tmpf - data->data.F32[i])/ 133 247 errors->data.F32[i]); 248 printf("gsl_vector_set(outData, %d, %.1f)\n", i, 249 gsl_vector_get(outData, i)); 250 134 251 //printf("--------- MYFUNC((%.1f) %.1f %.1f %.1f) is [%.1f] ---------\n", 135 252 //tmpVecPtr->data.F32[0], … … 138 255 //inputParameterList->data.F32[2], 139 256 //(tmpf - data->data.F32[i])/errors->data.F32[i]); 140 141 }142 143 for (i=0;i<domain->numRows;i++) {144 printf("gsl_vector_set(outData, %d, %.1f)\n", i,145 gsl_vector_get(outData, i));146 257 } 147 258 … … 176 287 177 288 if (mask != NULL) { 289 printf("--------------- WHOA ---------------: MASK NOT NULL\n"); 178 290 j = 0; 179 291 for (i=0;i<mask->n;i++) { … … 207 319 208 320 gsl_matrix_set(J, i, j, (tmpf/errors->data.F32[i])); 209 }210 }211 212 213 for (i=0;i<domain->numRows;i++) {214 for (j=0;j<inputParameterList->n;j++) {215 321 printf("gsl_matrix_set(J, %d, %d, %.1f)\n", i, j, 216 322 gsl_matrix_get(J, i, j)); 217 323 } 218 324 } 219 220 221 325 222 326 psFree(inputParameterList); … … 235 339 return GSL_SUCCESS; 236 340 } 341 342 int print_state(size_t iter, 343 gsl_multifit_fdfsolver *s) 344 { 345 printf ("iter: %3u x = % 15.8f % 15.8f % 15.8f " 346 "|f(x)| = %g\n", 347 iter, 348 gsl_vector_get(s->x, 0), 349 gsl_vector_get(s->x, 1), 350 gsl_vector_get(s->x, 2), 351 gsl_blas_dnrm2(s->f)); 352 return 0; 353 } 354 355 #define FIT(i) gsl_vector_get(s->x, i) 356 #define ERR(i) sqrt(gsl_matrix_get(covar,i,i)) 357 358 359 int try03() 360 { 361 const gsl_multifit_fdfsolver_type *T; 362 gsl_multifit_fdfsolver *s; 363 int status; 364 size_t i, iter = 0; 365 const size_t n = NUM_DATA; 366 const size_t p = 3; 367 gsl_multifit_function_fdf f; 368 double y[NUM_DATA], sigma[NUM_DATA]; 369 gsl_matrix *covar = gsl_matrix_alloc (p, p); 370 struct data d = { 371 n, y, sigma 372 }; 373 double x_init[3] = { 1.0, 0.0, 0.0 }; 374 gsl_vector_view x = gsl_vector_view_array (x_init, p); 375 376 printf("Calling try03()\n"); 377 const gsl_rng_type *type; 378 gsl_rng *r; 379 380 gsl_rng_env_setup(); 381 382 type = gsl_rng_default; 383 r = gsl_rng_alloc (type); 384 385 f.f = &expb_f; 386 f.df = &expb_df; 387 f.fdf = &expb_fdf; 388 f.n = n; // Equals N, equals the number of data points. 389 f.p = p; // Equals 3 390 f.params = &d; 391 392 /* This is the data to be fitted */ 393 394 for (i = 0; i < n; i++) { 395 double t = i; 396 y[i] = 1.0 + 5 * exp (-0.1 * t) 397 + gsl_ran_gaussian (r, 0.1); 398 sigma[i] = 0.1; 399 // printf ("data: %d %g %g\n", i, y[i], sigma[i]); 400 // printf("data->data.F32[%d][0] = %f;\n", i, y[i]); 401 }; 402 403 T = gsl_multifit_fdfsolver_lmsder; 404 s = gsl_multifit_fdfsolver_alloc (T, n, p); 405 gsl_multifit_fdfsolver_set(s, &f, &x.vector); 406 print_state(iter, s); 407 do { 408 iter++; 409 status = gsl_multifit_fdfsolver_iterate (s); 410 printf ("status = %s\n", gsl_strerror (status)); 411 print_state (iter, s); 412 if (status) 413 break; 414 status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4); 415 } while (status == GSL_CONTINUE && iter < 500); 416 417 gsl_multifit_covar (s->J, 0.0, covar); 418 419 gsl_matrix_fprintf (stdout, covar, "%g"); 420 421 printf ("A = %.5f +/- %.5f\n", FIT(0), ERR(0)); 422 printf ("lambda = %.5f +/- %.5f\n", FIT(1), ERR(1)); 423 printf ("b = %.5f +/- %.5f\n", FIT(2), ERR(2)); 424 425 { 426 double chi = gsl_blas_dnrm2(s->f); 427 printf("chisq/dof = %g\n", pow(chi, 2.0)/ (n - p)); 428 } 429 430 printf ("status = %s\n", gsl_strerror (status)); 431 432 gsl_multifit_fdfsolver_free (s); 433 printf("Called try03()\n"); 434 return 0; 435 } 436 437 237 438 238 439 … … 252 453 { 253 454 printf("Calling psMinimizeChi2()\n"); 455 try03(); 254 456 255 457 int numData = domain->numRows; // Number of data points … … 295 497 xInit = (double *) psAlloc(inputData.paramCount * sizeof(double)); 296 498 if (paramMask != NULL) { 499 printf("--------------- WHOA ---------------: MASK NOT NULL\n"); 297 500 j = 0; 298 501 for (i=0;i<initialGuess->n;i++) { … … 330 533 printf("inputData.paramCount is %d\n", inputData.paramCount); 331 534 printf("numData is %d\n", numData); 332 // Creates the vector for x which GSL uses. Must deallocate. 535 536 333 537 gsl_vector_view x = gsl_vector_view_array(xInit, inputData.paramCount); 334 538 T = gsl_multifit_fdfsolver_lmsder; 335 336 // Create an instance of the GSL solver that we will be iterating on.337 // It will have numData data points and inputData.paramCount parameters.338 539 s = gsl_multifit_fdfsolver_alloc(T, numData, inputData.paramCount); 339 340 // Initialize the GSL minimizer to use function defined by the data341 // structure "f" and x.vector as an initial guess for the parameters.342 343 540 gsl_multifit_fdfsolver_set(s, &f, &x.vector); 344 345 // Each iteration of the following loop will perform one step in an346 // attempt to minimized chi-squared for the function. The loop exits347 // either when the change in parameters is small enough, or when the348 // maximum number of iterations is reached.349 541 do { 350 542 iter++; … … 360 552 361 553 status = gsl_multifit_fdfsolver_iterate(s); 554 printf ("psMinimize() status = %s\n", gsl_strerror (status)); 362 555 // If there was a problem, abort. 363 556 if (status) { … … 375 568 // into the solution. 376 569 if (paramMask != NULL) { 570 printf("--------------- WHOA ---------------: MASK NOT NULL\n"); 377 571 j = 0; 378 572 for (i=0;i<initialGuess->n;i++) { … … 583 777 * success. 584 778 */ 779 780 781 585 782 void polyOrderCheck(float **A, 586 783 int N,
Note:
See TracChangeset
for help on using the changeset viewer.
