Changeset 1860
- Timestamp:
- Sep 22, 2004, 7:43:25 PM (22 years ago)
- Location:
- trunk/psLib/src
- Files:
-
- 2 edited
-
dataManip/psMinimize.c (modified) (14 diffs)
-
math/psMinimize.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/dataManip/psMinimize.c
r1859 r1860 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.4 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09-23 0 4:56:41$11 * @version $Revision: 1.46 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-23 05:43:25 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 15 * 16 16 * XXX: must follow coding name standards on local functions. 17 * 18 * XXX: Section 4.5.1.1 (predefined functions for Gauss minimization via 19 * LMM) is not addressed here. We are waiting for subsequent SDRs 20 * which will redfeine the LMM functions. 17 21 * 18 22 */ … … 38 42 #include "psImage.h" 39 43 #include "psTrace.h" 44 #include "psLogMsg.h" 40 45 #include "psError.h" 41 46 #include "psAbort.h" … … 94 99 /*****************************************************************************/ 95 100 static psMinimizeChi2PowellFunc Chi2PowellFunc = NULL; 96 //static psMinimizePowellFunc PowellFunc = NULL;97 101 static psVector *myValue; 98 102 static psVector *myError; … … 121 125 int i = 0; 122 126 double xSum = 0.0; 127 if (sums == NULL) { 128 sums = psVectorAlloc(polyOrder, PS_TYPE_F64); 129 } 123 130 124 131 xSum = 1.0; … … 139 146 140 147 tmp = psVectorAlloc(x, PS_TYPE_F32); 141 142 148 for (i = 0; i < x; i++) { 143 149 tmp->data.F32[i] = (((float)2 * i) / ((float)x)) - 1.0; … … 224 230 } 225 231 226 227 /*****************************************************************************/228 /* FUNCTION IMPLEMENTATION - PUBLIC */229 /*****************************************************************************/230 231 /*****************************************************************************232 psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y233 vectors, this routine generates the cublic splines which satisfy those data234 points.235 236 The formula for calculating the spline polynomials is derived from Numerical237 Recipes in C. The basic idea is that the polynomial is238 (1) y = (A * y[0]) +239 (2) (B * y[1]) +240 (3) ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 +241 (4) ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0242 Where:243 H = x[1]-x[0]244 A = (x[1]-x)/H245 B = (x-x[0])/H246 The bulk of the code in this routine is the expansion of the above equation247 into a polynomial in terms of x, and then saving the coefficients of the248 powers of x in the spline polynomials. This gets pretty complicated.249 250 XXX: usage of yErr is not specified in IfA documentation.251 *****************************************************************************/252 253 psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline, ///< The spline which will be generated.254 const psVector* restrict x, ///< Ordinates (or NULL to just use the indices)255 const psVector* restrict y, ///< Coordinates256 const psVector* restrict yErr) ///< Errors in coordinates, or NULL257 {258 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,259 "---- psVectorFitSpline1D() begin ----\n");260 int numSplines = (y->n)-1;261 float tmp;262 float H;263 int i;264 265 if (mySpline == NULL) {266 //XXX psErrorMsg()267 }268 mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y);269 for (i=0;i<y->n;i++)270 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,271 "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]);272 273 for (i=0;i<numSplines;i++) {274 H = x->data.F32[i+1] - x->data.F32[i];275 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,276 "X data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H);277 //278 // ******** Calulate 0-order term ********279 //280 // From (1)281 (mySpline->spline[i])->coeff[0] = (y->data.F32[i] * x->data.F32[i+1]/H);282 // From (2)283 ((mySpline->spline[i])->coeff[0])-= ((y->data.F32[i+1] * x->data.F32[i])/H);284 // From (3)285 tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);286 tmp-= (x->data.F32[i+1] / H);287 tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0;288 ((mySpline->spline[i])->coeff[0])+= tmp;289 // From (4)290 tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H);291 tmp+= (x->data.F32[i] / H);292 tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0;293 ((mySpline->spline[i])->coeff[0])+= tmp;294 295 //296 // ******** Calulate 1-order term ********297 //298 // From (1)299 (mySpline->spline[i])->coeff[1] = -(y->data.F32[i]) / H;300 // From (2)301 ((mySpline->spline[i])->coeff[1])+= (y->data.F32[i+1] / H);302 // From (3)303 tmp = -3.0 * (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);304 tmp+= (1.0 / H);305 tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0;306 ((mySpline->spline[i])->coeff[1])+= tmp;307 // From (4)308 tmp = 3.0 * (x->data.F32[i] * x->data.F32[i]) / (H * H * H);309 tmp-= (1.0 / H);310 tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0;311 ((mySpline->spline[i])->coeff[1])+= tmp;312 313 //314 // ******** Calulate 2-order term ********315 //316 // From (3)317 (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / (6.0 * H);318 // From (4)319 ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / (6.0 * H));320 321 //322 // ******** Calulate 3-order term ********323 //324 // From (3)325 (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H);326 // From (4)327 ((mySpline->spline[i])->coeff[3])+= ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H);328 329 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,330 "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]);331 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,332 "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]);333 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,334 "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]);335 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,336 "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]);337 338 }339 340 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,341 "---- psVectorFitSpline1D() end ----\n");342 return(mySpline);343 }344 232 345 233 /****************************************************************************** … … 387 275 388 276 277 /*****************************************************************************/ 278 /* FUNCTION IMPLEMENTATION - PUBLIC */ 279 /*****************************************************************************/ 280 281 /***************************************************************************** 282 psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y 283 vectors, this routine generates the linear or cublic splines which satisfy 284 those data points. 285 286 The formula for calculating the spline polynomials is derived from Numerical 287 Recipes in C. The basic idea is that the polynomial is 288 (1) y = (A * y[0]) + 289 (2) (B * y[1]) + 290 (3) ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 + 291 (4) ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0 292 Where: 293 H = x[1]-x[0] 294 A = (x[1]-x)/H 295 B = (x-x[0])/H 296 The bulk of the code in this routine is the expansion of the above equation 297 into a polynomial in terms of x, and then saving the coefficients of the 298 powers of x in the spline polynomials. This gets pretty complicated. 299 300 XXX: usage of yErr is not specified in IfA documentation. 301 XXX: Must do: if yErr==NULL, set all errors equal. 302 303 XXX: Is the x argument redundant? What do we do if the x argument is 304 supplied, but does not equal the domains specified in mySpline? 305 306 XXX: can psSpline be NULL? 307 308 XXX: Implemented in F32 only, must add F64. 309 *****************************************************************************/ 310 psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline, ///< The spline which will be generated. 311 const psVector* restrict x, ///< Ordinates (or NULL to just use the indices) 312 const psVector* restrict y, ///< Coordinates 313 const psVector* restrict yErr) ///< Errors in coordinates, or NULL 314 { 315 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 316 "---- psVectorFitSpline1D() begin ----\n"); 317 int numSplines = (y->n)-1; 318 float tmp; 319 float H; 320 int i; 321 float slope; 322 323 if (mySpline == NULL) { 324 //XXX psErrorMsg() 325 } 326 if (y == NULL) { 327 //XXX psErrorMsg() 328 } 329 330 if (y->n != (1 + mySpline->n)) { 331 psLogMsg(__func__, PS_LOG_WARN, 332 "data size / spline size mismatch (%d %d)\n", 333 y->n, mySpline->n); 334 // XXX: psErrorMsg() 335 } 336 337 // If these are linear splines, which means their polynomials will have 338 // two coefficients, then we do the simple calculation. 339 if (2 == (mySpline->spline[0])->n) { 340 for (i=0;i<mySpline->n;i++) { 341 slope = (y->data.F32[i+1] - y->data.F32[i]) / 342 (mySpline->domains[i+1] - mySpline->domains[i]); 343 (mySpline->spline[i])->coeff[0] = y->data.F32[i] - 344 (slope * mySpline->domains[i]); 345 346 (mySpline->spline[i])->coeff[1] = slope; 347 psTrace(".psLib.dataManip.psFunctions.psSpline1DGen", 4, 348 "---- mySpline %d coeffs are (%f, %f)\n", i, 349 (mySpline->spline[i])->coeff[0], 350 (mySpline->spline[i])->coeff[1]); 351 } 352 psTrace(".psLib.dataManip.psFunctions.psSpline1DGen", 4, 353 "---- Exiting psSpline1DGen()\n"); 354 return((psSpline1D *) mySpline); 355 } 356 357 // Check if these are cubic splines (n==4). If not, psError. 358 if (4 != (mySpline->spline[0])->n) { 359 psLogMsg(__func__, PS_LOG_WARN, 360 "Don't know how to generate %d-order splines.", 361 (mySpline->spline[0])->n-1); 362 // XXX: psErrorMsg() 363 return(NULL); 364 } 365 366 // If we get here, then we know these are cubic splines. We first 367 // generate the second derivatives at each data point. 368 mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y); 369 for (i=0;i<y->n;i++) 370 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 371 "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]); 372 373 // We generate the coefficients of the spline polynomials. I can't 374 // concisely explain how this code works. See above function comments 375 // and Numerical Recipes in C. 376 for (i=0;i<numSplines;i++) { 377 H = x->data.F32[i+1] - x->data.F32[i]; 378 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 379 "X data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H); 380 // 381 // ******** Calculate 0-order term ******** 382 // 383 // From (1) 384 (mySpline->spline[i])->coeff[0] = (y->data.F32[i] * x->data.F32[i+1]/H); 385 // From (2) 386 ((mySpline->spline[i])->coeff[0])-= ((y->data.F32[i+1] * x->data.F32[i])/H); 387 // From (3) 388 tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 389 tmp-= (x->data.F32[i+1] / H); 390 tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0; 391 ((mySpline->spline[i])->coeff[0])+= tmp; 392 // From (4) 393 tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H); 394 tmp+= (x->data.F32[i] / H); 395 tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0; 396 ((mySpline->spline[i])->coeff[0])+= tmp; 397 398 // 399 // ******** Calculate 1-order term ******** 400 // 401 // From (1) 402 (mySpline->spline[i])->coeff[1] = -(y->data.F32[i]) / H; 403 // From (2) 404 ((mySpline->spline[i])->coeff[1])+= (y->data.F32[i+1] / H); 405 // From (3) 406 tmp = -3.0 * (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 407 tmp+= (1.0 / H); 408 tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0; 409 ((mySpline->spline[i])->coeff[1])+= tmp; 410 // From (4) 411 tmp = 3.0 * (x->data.F32[i] * x->data.F32[i]) / (H * H * H); 412 tmp-= (1.0 / H); 413 tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0; 414 ((mySpline->spline[i])->coeff[1])+= tmp; 415 416 // 417 // ******** Calculate 2-order term ******** 418 // 419 // From (3) 420 (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / (6.0 * H); 421 // From (4) 422 ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / (6.0 * H)); 423 424 // 425 // ******** Calculate 3-order term ******** 426 // 427 // From (3) 428 (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H); 429 // From (4) 430 ((mySpline->spline[i])->coeff[3])+= ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H); 431 432 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 433 "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]); 434 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 435 "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]); 436 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 437 "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]); 438 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 439 "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]); 440 441 } 442 443 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 444 "---- psVectorFitSpline1D() end ----\n"); 445 return(mySpline); 446 } 447 389 448 /****************************************************************************** 390 449 psMinimizeLMChi2(): This routine will take an procedure which calculates an … … 398 457 399 458 A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i]; 459 460 XXX: This is very different from what is specified in the SDR. Must 461 coordinate with IfA on new SDR. 462 463 XXX: Do vector/image recycles. 464 465 XXX: probably yErr will be part of the SDR. 466 467 XXX: This must work for both F32 and F64. F32 is currently implemented. 468 Note: since the LUD routines are only implemented in F64, then we 469 will have to convert all F32 input vectors to F64 regardless. So, 470 the F64 port might be. 400 471 *****************************************************************************/ 401 472 bool psMinimizeLMChi2(psMinimization *min, … … 450 521 451 522 min->lastDelta = HUGE; 452 min->lastDelta = 12345.0;453 523 min->iter = 0; 454 524 … … 627 697 polynomial, as well as the error for each data point (yErr). 628 698 629 XXX: NOTE: yErr is currently ignored. 699 XXX: yErr is currently ignored. 700 701 XXX: must add type F32 (currently F64 only). 702 703 XXX: Must do: if x==NULL, use the index vector (???). 704 705 XXX: Must do: if yErr==NULL, set all errors equal. 630 706 *****************************************************************************/ 631 707 psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly, … … 726 802 } 727 803 804 805 /****************************************************************************** 806 *****************************************************************************/ 728 807 psMinimization *psMinimizationAlloc(int maxIter, 729 808 float tol) … … 747 826 f(param + c * line). 748 827 749 Algorithm: XXX completely ad hoc: start with the user-supplied starting 750 parameter and call that b. Calculate a/c as a fractional amount 751 smaller/larger than b. Repeat this process until a local minimum is 752 found. 753 754 828 Algorithm: XXX completely ad hoc: start with the user-supplied starting 829 parameter and call that b. Calculate a/c as a fractional amount 830 smaller/larger than b. Repeat this process until a local minimum is found. 831 832 XXX: new algorithm: start at x=0, expand in one direction until the function 833 decreases. Then you have two points in the bracket. Keep going until it 834 increases, or x is too large. If thst does not work, expand in the other 835 direction. 755 836 *****************************************************************************/ 756 837 psVector *p_psDetermineBracket(psVector *params, … … 926 1007 This routine must minimize a possibly multi-dimensional function 927 1008 along a vector defined by line. 1009 1010 XXX: Use a p_psName(). 928 1011 *****************************************************************************/ 929 1012 float psLineMin(psMinimization *min, … … 1113 1196 XXX: We do not use Brent's method. 1114 1197 1115 XXX: We do not use the 1198 XXX: The SDR is silent about data types. F32 is implemented here. 1199 1200 XXX: Define constants for default dummy number of iterations and tolerance. 1116 1201 *****************************************************************************/ 1117 1202 bool psMinimizePowell(psMinimization *min, -
trunk/psLib/src/math/psMinimize.c
r1859 r1860 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.4 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09-23 0 4:56:41$11 * @version $Revision: 1.46 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-23 05:43:25 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii 15 15 * 16 16 * XXX: must follow coding name standards on local functions. 17 * 18 * XXX: Section 4.5.1.1 (predefined functions for Gauss minimization via 19 * LMM) is not addressed here. We are waiting for subsequent SDRs 20 * which will redfeine the LMM functions. 17 21 * 18 22 */ … … 38 42 #include "psImage.h" 39 43 #include "psTrace.h" 44 #include "psLogMsg.h" 40 45 #include "psError.h" 41 46 #include "psAbort.h" … … 94 99 /*****************************************************************************/ 95 100 static psMinimizeChi2PowellFunc Chi2PowellFunc = NULL; 96 //static psMinimizePowellFunc PowellFunc = NULL;97 101 static psVector *myValue; 98 102 static psVector *myError; … … 121 125 int i = 0; 122 126 double xSum = 0.0; 127 if (sums == NULL) { 128 sums = psVectorAlloc(polyOrder, PS_TYPE_F64); 129 } 123 130 124 131 xSum = 1.0; … … 139 146 140 147 tmp = psVectorAlloc(x, PS_TYPE_F32); 141 142 148 for (i = 0; i < x; i++) { 143 149 tmp->data.F32[i] = (((float)2 * i) / ((float)x)) - 1.0; … … 224 230 } 225 231 226 227 /*****************************************************************************/228 /* FUNCTION IMPLEMENTATION - PUBLIC */229 /*****************************************************************************/230 231 /*****************************************************************************232 psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y233 vectors, this routine generates the cublic splines which satisfy those data234 points.235 236 The formula for calculating the spline polynomials is derived from Numerical237 Recipes in C. The basic idea is that the polynomial is238 (1) y = (A * y[0]) +239 (2) (B * y[1]) +240 (3) ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 +241 (4) ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0242 Where:243 H = x[1]-x[0]244 A = (x[1]-x)/H245 B = (x-x[0])/H246 The bulk of the code in this routine is the expansion of the above equation247 into a polynomial in terms of x, and then saving the coefficients of the248 powers of x in the spline polynomials. This gets pretty complicated.249 250 XXX: usage of yErr is not specified in IfA documentation.251 *****************************************************************************/252 253 psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline, ///< The spline which will be generated.254 const psVector* restrict x, ///< Ordinates (or NULL to just use the indices)255 const psVector* restrict y, ///< Coordinates256 const psVector* restrict yErr) ///< Errors in coordinates, or NULL257 {258 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,259 "---- psVectorFitSpline1D() begin ----\n");260 int numSplines = (y->n)-1;261 float tmp;262 float H;263 int i;264 265 if (mySpline == NULL) {266 //XXX psErrorMsg()267 }268 mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y);269 for (i=0;i<y->n;i++)270 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6,271 "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]);272 273 for (i=0;i<numSplines;i++) {274 H = x->data.F32[i+1] - x->data.F32[i];275 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,276 "X data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H);277 //278 // ******** Calulate 0-order term ********279 //280 // From (1)281 (mySpline->spline[i])->coeff[0] = (y->data.F32[i] * x->data.F32[i+1]/H);282 // From (2)283 ((mySpline->spline[i])->coeff[0])-= ((y->data.F32[i+1] * x->data.F32[i])/H);284 // From (3)285 tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);286 tmp-= (x->data.F32[i+1] / H);287 tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0;288 ((mySpline->spline[i])->coeff[0])+= tmp;289 // From (4)290 tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H);291 tmp+= (x->data.F32[i] / H);292 tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0;293 ((mySpline->spline[i])->coeff[0])+= tmp;294 295 //296 // ******** Calulate 1-order term ********297 //298 // From (1)299 (mySpline->spline[i])->coeff[1] = -(y->data.F32[i]) / H;300 // From (2)301 ((mySpline->spline[i])->coeff[1])+= (y->data.F32[i+1] / H);302 // From (3)303 tmp = -3.0 * (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H);304 tmp+= (1.0 / H);305 tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0;306 ((mySpline->spline[i])->coeff[1])+= tmp;307 // From (4)308 tmp = 3.0 * (x->data.F32[i] * x->data.F32[i]) / (H * H * H);309 tmp-= (1.0 / H);310 tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0;311 ((mySpline->spline[i])->coeff[1])+= tmp;312 313 //314 // ******** Calulate 2-order term ********315 //316 // From (3)317 (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / (6.0 * H);318 // From (4)319 ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / (6.0 * H));320 321 //322 // ******** Calulate 3-order term ********323 //324 // From (3)325 (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H);326 // From (4)327 ((mySpline->spline[i])->coeff[3])+= ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H);328 329 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,330 "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]);331 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,332 "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]);333 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,334 "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]);335 psTrace(".psLib.dataManip.psMinimizeLMChi2", 6,336 "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]);337 338 }339 340 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4,341 "---- psVectorFitSpline1D() end ----\n");342 return(mySpline);343 }344 232 345 233 /****************************************************************************** … … 387 275 388 276 277 /*****************************************************************************/ 278 /* FUNCTION IMPLEMENTATION - PUBLIC */ 279 /*****************************************************************************/ 280 281 /***************************************************************************** 282 psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y 283 vectors, this routine generates the linear or cublic splines which satisfy 284 those data points. 285 286 The formula for calculating the spline polynomials is derived from Numerical 287 Recipes in C. The basic idea is that the polynomial is 288 (1) y = (A * y[0]) + 289 (2) (B * y[1]) + 290 (3) ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 + 291 (4) ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0 292 Where: 293 H = x[1]-x[0] 294 A = (x[1]-x)/H 295 B = (x-x[0])/H 296 The bulk of the code in this routine is the expansion of the above equation 297 into a polynomial in terms of x, and then saving the coefficients of the 298 powers of x in the spline polynomials. This gets pretty complicated. 299 300 XXX: usage of yErr is not specified in IfA documentation. 301 XXX: Must do: if yErr==NULL, set all errors equal. 302 303 XXX: Is the x argument redundant? What do we do if the x argument is 304 supplied, but does not equal the domains specified in mySpline? 305 306 XXX: can psSpline be NULL? 307 308 XXX: Implemented in F32 only, must add F64. 309 *****************************************************************************/ 310 psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline, ///< The spline which will be generated. 311 const psVector* restrict x, ///< Ordinates (or NULL to just use the indices) 312 const psVector* restrict y, ///< Coordinates 313 const psVector* restrict yErr) ///< Errors in coordinates, or NULL 314 { 315 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 316 "---- psVectorFitSpline1D() begin ----\n"); 317 int numSplines = (y->n)-1; 318 float tmp; 319 float H; 320 int i; 321 float slope; 322 323 if (mySpline == NULL) { 324 //XXX psErrorMsg() 325 } 326 if (y == NULL) { 327 //XXX psErrorMsg() 328 } 329 330 if (y->n != (1 + mySpline->n)) { 331 psLogMsg(__func__, PS_LOG_WARN, 332 "data size / spline size mismatch (%d %d)\n", 333 y->n, mySpline->n); 334 // XXX: psErrorMsg() 335 } 336 337 // If these are linear splines, which means their polynomials will have 338 // two coefficients, then we do the simple calculation. 339 if (2 == (mySpline->spline[0])->n) { 340 for (i=0;i<mySpline->n;i++) { 341 slope = (y->data.F32[i+1] - y->data.F32[i]) / 342 (mySpline->domains[i+1] - mySpline->domains[i]); 343 (mySpline->spline[i])->coeff[0] = y->data.F32[i] - 344 (slope * mySpline->domains[i]); 345 346 (mySpline->spline[i])->coeff[1] = slope; 347 psTrace(".psLib.dataManip.psFunctions.psSpline1DGen", 4, 348 "---- mySpline %d coeffs are (%f, %f)\n", i, 349 (mySpline->spline[i])->coeff[0], 350 (mySpline->spline[i])->coeff[1]); 351 } 352 psTrace(".psLib.dataManip.psFunctions.psSpline1DGen", 4, 353 "---- Exiting psSpline1DGen()\n"); 354 return((psSpline1D *) mySpline); 355 } 356 357 // Check if these are cubic splines (n==4). If not, psError. 358 if (4 != (mySpline->spline[0])->n) { 359 psLogMsg(__func__, PS_LOG_WARN, 360 "Don't know how to generate %d-order splines.", 361 (mySpline->spline[0])->n-1); 362 // XXX: psErrorMsg() 363 return(NULL); 364 } 365 366 // If we get here, then we know these are cubic splines. We first 367 // generate the second derivatives at each data point. 368 mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y); 369 for (i=0;i<y->n;i++) 370 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 371 "Second deriv[%d] is %f\n", i, mySpline->p_psDeriv2[i]); 372 373 // We generate the coefficients of the spline polynomials. I can't 374 // concisely explain how this code works. See above function comments 375 // and Numerical Recipes in C. 376 for (i=0;i<numSplines;i++) { 377 H = x->data.F32[i+1] - x->data.F32[i]; 378 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 379 "X data (%f - %f) (%f)\n", x->data.F32[i], x->data.F32[i+1], H); 380 // 381 // ******** Calculate 0-order term ******** 382 // 383 // From (1) 384 (mySpline->spline[i])->coeff[0] = (y->data.F32[i] * x->data.F32[i+1]/H); 385 // From (2) 386 ((mySpline->spline[i])->coeff[0])-= ((y->data.F32[i+1] * x->data.F32[i])/H); 387 // From (3) 388 tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 389 tmp-= (x->data.F32[i+1] / H); 390 tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0; 391 ((mySpline->spline[i])->coeff[0])+= tmp; 392 // From (4) 393 tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H); 394 tmp+= (x->data.F32[i] / H); 395 tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0; 396 ((mySpline->spline[i])->coeff[0])+= tmp; 397 398 // 399 // ******** Calculate 1-order term ******** 400 // 401 // From (1) 402 (mySpline->spline[i])->coeff[1] = -(y->data.F32[i]) / H; 403 // From (2) 404 ((mySpline->spline[i])->coeff[1])+= (y->data.F32[i+1] / H); 405 // From (3) 406 tmp = -3.0 * (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 407 tmp+= (1.0 / H); 408 tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0; 409 ((mySpline->spline[i])->coeff[1])+= tmp; 410 // From (4) 411 tmp = 3.0 * (x->data.F32[i] * x->data.F32[i]) / (H * H * H); 412 tmp-= (1.0 / H); 413 tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0; 414 ((mySpline->spline[i])->coeff[1])+= tmp; 415 416 // 417 // ******** Calculate 2-order term ******** 418 // 419 // From (3) 420 (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / (6.0 * H); 421 // From (4) 422 ((mySpline->spline[i])->coeff[2])-= (((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / (6.0 * H)); 423 424 // 425 // ******** Calculate 3-order term ******** 426 // 427 // From (3) 428 (mySpline->spline[i])->coeff[3] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H); 429 // From (4) 430 ((mySpline->spline[i])->coeff[3])+= ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H); 431 432 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 433 "(mySpline->spline[%d])->coeff[0] is %f\n", i, (mySpline->spline[i])->coeff[0]); 434 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 435 "(mySpline->spline[%d])->coeff[1] is %f\n", i, (mySpline->spline[i])->coeff[1]); 436 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 437 "(mySpline->spline[%d])->coeff[2] is %f\n", i, (mySpline->spline[i])->coeff[2]); 438 psTrace(".psLib.dataManip.psVectorFitSpline1D", 6, 439 "(mySpline->spline[%d])->coeff[3] is %f\n", i, (mySpline->spline[i])->coeff[3]); 440 441 } 442 443 psTrace(".psLib.dataManip.psVectorFitSpline1D", 4, 444 "---- psVectorFitSpline1D() end ----\n"); 445 return(mySpline); 446 } 447 389 448 /****************************************************************************** 390 449 psMinimizeLMChi2(): This routine will take an procedure which calculates an … … 398 457 399 458 A[i][i] = (1 + lambda*paramask[i]) * alpha[i][i]; 459 460 XXX: This is very different from what is specified in the SDR. Must 461 coordinate with IfA on new SDR. 462 463 XXX: Do vector/image recycles. 464 465 XXX: probably yErr will be part of the SDR. 466 467 XXX: This must work for both F32 and F64. F32 is currently implemented. 468 Note: since the LUD routines are only implemented in F64, then we 469 will have to convert all F32 input vectors to F64 regardless. So, 470 the F64 port might be. 400 471 *****************************************************************************/ 401 472 bool psMinimizeLMChi2(psMinimization *min, … … 450 521 451 522 min->lastDelta = HUGE; 452 min->lastDelta = 12345.0;453 523 min->iter = 0; 454 524 … … 627 697 polynomial, as well as the error for each data point (yErr). 628 698 629 XXX: NOTE: yErr is currently ignored. 699 XXX: yErr is currently ignored. 700 701 XXX: must add type F32 (currently F64 only). 702 703 XXX: Must do: if x==NULL, use the index vector (???). 704 705 XXX: Must do: if yErr==NULL, set all errors equal. 630 706 *****************************************************************************/ 631 707 psPolynomial1D* psVectorFitPolynomial1D(psPolynomial1D* myPoly, … … 726 802 } 727 803 804 805 /****************************************************************************** 806 *****************************************************************************/ 728 807 psMinimization *psMinimizationAlloc(int maxIter, 729 808 float tol) … … 747 826 f(param + c * line). 748 827 749 Algorithm: XXX completely ad hoc: start with the user-supplied starting 750 parameter and call that b. Calculate a/c as a fractional amount 751 smaller/larger than b. Repeat this process until a local minimum is 752 found. 753 754 828 Algorithm: XXX completely ad hoc: start with the user-supplied starting 829 parameter and call that b. Calculate a/c as a fractional amount 830 smaller/larger than b. Repeat this process until a local minimum is found. 831 832 XXX: new algorithm: start at x=0, expand in one direction until the function 833 decreases. Then you have two points in the bracket. Keep going until it 834 increases, or x is too large. If thst does not work, expand in the other 835 direction. 755 836 *****************************************************************************/ 756 837 psVector *p_psDetermineBracket(psVector *params, … … 926 1007 This routine must minimize a possibly multi-dimensional function 927 1008 along a vector defined by line. 1009 1010 XXX: Use a p_psName(). 928 1011 *****************************************************************************/ 929 1012 float psLineMin(psMinimization *min, … … 1113 1196 XXX: We do not use Brent's method. 1114 1197 1115 XXX: We do not use the 1198 XXX: The SDR is silent about data types. F32 is implemented here. 1199 1200 XXX: Define constants for default dummy number of iterations and tolerance. 1116 1201 *****************************************************************************/ 1117 1202 bool psMinimizePowell(psMinimization *min,
Note:
See TracChangeset
for help on using the changeset viewer.
