Changeset 1846 for trunk/psLib/src/math/psMinimize.c
- Timestamp:
- Sep 21, 2004, 3:30:21 PM (22 years ago)
- File:
-
- 1 edited
-
trunk/psLib/src/math/psMinimize.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/math/psMinimize.c
r1836 r1846 1 /** @file psMinimize.c1 M/** @file psMinimize.c 2 2 * \brief basic minimization functions 3 3 * @ingroup Math … … 9 9 * @author George Gusciora, MHPCC 10 10 * 11 * @version $Revision: 1.4 1$ $Name: not supported by cvs2svn $12 * @date $Date: 2004-09-2 0 23:16:10$11 * @version $Revision: 1.42 $ $Name: not supported by cvs2svn $ 12 * @date $Date: 2004-09-22 01:30:21 $ 13 13 * 14 14 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 148 148 } 149 149 150 /***************************************************************************** 151 152 CalculateSecondDerivs(): Given a set of x/y vectors corresponding to a 153 tabulated function at n points, this routine calcualtes the second 154 derivatives of the interpolating cubic splines at those n points. 155 156 The first and second derivatives at the endpoints, undefined in the SDR, are 157 here defined to be 0.0. 158 159 XXX: This algorithm is very similar to that in Numerical Recipes. 160 *****************************************************************************/ 161 float *CalculateSecondDerivs(const psVector* restrict x, ///< Ordinates (or NULL to just use the indices) 162 const psVector* restrict y) ///< Coordinates 163 { 164 int i; 165 int k; 166 bool mustFreeX = false; 167 float sig; 168 float p; 169 int n = y->n; 170 float *u = (float *) psAlloc(n * sizeof(float)); 171 float *derivs2 = (float *) psAlloc(n * sizeof(float)); 172 float *X = (float *) & (x->data.F32[0]); 173 float *Y = (float *) & (y->data.F32[0]); 174 175 if (x == NULL) { 176 X = (float *) psAlloc(n * sizeof(float)); 177 for(i=0;i<n;i++) { 178 X[i] = (float) i; 179 } 180 mustFreeX = true; 181 } 182 183 // XXX: The first and second derivatives at the endpoints, undefined in 184 // the SDR, are here defined to be 0.0. 185 u[0]= 0.0; 186 u[n-1]= 0.0; 187 derivs2[0] = 0.0; 188 derivs2[n-1] = 0.0; 189 190 for (i=1;i<=(n-2);i++) { 191 sig = (X[i] - X[i-1]) / (X[i+1] - X[i-1]); 192 p = sig * derivs2[i-1] + 2.0; 193 derivs2[i] = (sig - 1.0) / p; 194 u[i] = (Y[i+1] - Y[i])/(X[i+1]-X[i]) - (Y[i]-Y[i-1])/(X[i]-X[i-1]); 195 u[i] = (6.0 * u[i] / (X[i+1] - X[i-1]) - sig * u[i-1]) / p; 196 } 197 198 for (k=(n-2);k>=0;k--) { 199 derivs2[k] = derivs2[k] * derivs2[k+1] + u[k]; 200 } 201 202 203 204 205 206 207 208 209 210 /* 211 if (mustFreeX == true) { 212 psFree(X); 213 } 214 */ 215 psFree(u); 216 217 return(derivs2); 218 } 219 220 150 221 /*****************************************************************************/ 151 222 /* FUNCTION IMPLEMENTATION - PUBLIC */ 152 223 /*****************************************************************************/ 224 225 226 227 /***************************************************************************** 228 psVectorFitSpline1D(): given a psSpline1D data structure and a set of x/y 229 vectors, this routine generates the cublic splines which satisfy those data 230 points. 231 232 The formula for calculating the spline polynomials is derived from Numerical 233 Recipes in C. The basic idea is that the polynomial is 234 (1) y = (A * y[0]) + 235 (2) (B * y[1]) + 236 (3) ((((A*A*A)-A) * mySpline->p_psDeriv2[0]) * H^2)/6.0 + 237 (4) ((((B*B*B)-B) * mySpline->p_psDeriv2[1]) * H^2)/6.0 238 Where 239 H = x[1]-x[0], A = (x[1]-x)/H, B = (x-x[0])/H 240 The bulk of the code in this routine is the expansion of the above equation 241 into a polynomial in terms of x. This gets pretty complicated. 242 243 XXX: usage of yErr is not specified in IfA documentation. 244 *****************************************************************************/ 245 246 psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline, ///< The spline which will be generated. 247 const psVector* restrict x, ///< Ordinates (or NULL to just use the indices) 248 const psVector* restrict y, ///< Coordinates 249 const psVector* restrict yErr) ///< Errors in coordinates, or NULL 250 { 251 int numSplines = (y->n)-1; 252 float tmp; 253 float H; 254 int i; 255 256 if (mySpline == NULL) { 257 //XXX psErrorMsg() 258 } 259 mySpline->p_psDeriv2 = CalculateSecondDerivs(x, y); 260 261 for (i=0;i<numSplines;i++) { 262 H = x->data.F32[i+1] - x->data.F32[i]; 263 // 264 // ******** Calulate 0-order term ******** 265 // 266 // From (1) 267 (mySpline->spline[i])->coeff[0] = y->data.F32[i] * (x->data.F32[i+1]/H); 268 // From (2) 269 ((mySpline->spline[i])->coeff[0])-= (y->data.F32[i+1] * x->data.F32[i]/H); 270 // From (3) 271 tmp = (x->data.F32[i+1] * x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 272 tmp-= (x->data.F32[i+1] / H); 273 tmp*= (mySpline->p_psDeriv2)[i] * H * H / 6.0; 274 ((mySpline->spline[i])->coeff[0])+= tmp; 275 // From (4) 276 tmp = -(x->data.F32[i] * x->data.F32[i] * x->data.F32[i]) / (H * H * H); 277 tmp+= (x->data.F32[i] / H); 278 tmp*= (mySpline->p_psDeriv2)[i+1] * H * H / 6.0; 279 ((mySpline->spline[i])->coeff[0])+= tmp; 280 281 // 282 // ******** Calulate 1-order term ******** 283 // 284 // From (1) 285 (mySpline->spline[i])->coeff[1] = - ((mySpline->p_psDeriv2)[i]) / H; 286 // From (2) 287 (mySpline->spline[i])->coeff[1]-= ((mySpline->p_psDeriv2)[i+1]) / H; 288 // From (3) 289 tmp = - (x->data.F32[i+1] * x->data.F32[i+1]) / (H * H * H); 290 tmp+= (1.0 / H); 291 tmp*= ((mySpline->p_psDeriv2)[i]) * H * H / 6.0; 292 (mySpline->spline[i])->coeff[1]+= tmp; 293 // From (4) 294 tmp = (x->data.F32[i] + x->data.F32[i]) / (H * H * H); 295 tmp-= (1.0 / H); 296 tmp*= ((mySpline->p_psDeriv2)[i+1]) * H * H / 6.0; 297 (mySpline->spline[i])->coeff[1]+= tmp; 298 299 // 300 // ******** Calulate 2-order term ******** 301 // 302 // From (3) 303 (mySpline->spline[i])->coeff[2] = ((mySpline->p_psDeriv2)[i]) * 3.0 * x->data.F32[i+1] / 6.0; 304 // From (4) 305 (mySpline->spline[i])->coeff[2]-= ((mySpline->p_psDeriv2)[i+1]) * 3.0 * x->data.F32[i] / 6.0; 306 307 // 308 // ******** Calulate 3-order term ******** 309 // 310 // From (3) 311 (mySpline->spline[i])->coeff[2] = -((mySpline->p_psDeriv2)[i]) / (6.0 * H); 312 // From (4) 313 (mySpline->spline[i])->coeff[2]+= ((mySpline->p_psDeriv2)[i+1]) / (6.0 * H); 314 } 315 316 317 318 319 320 321 322 323 324 return(mySpline); 325 } 153 326 154 327 /****************************************************************************** … … 388 561 389 562 563 564 565 566 567 568 569 570 571 572 573 390 574 /****************************************************************************** 391 575 psVectorFitPolynomial1D(): This routine must fit a polynomial of degree … … 504 688 return(min); 505 689 } 690 506 691 507 692 #define STEP_SIZE 0.10 … … 551 736 } 552 737 } 738 553 739 if (null == 0) { 554 740 psTrace(".psLib.dataManip.p_psDetermineBracket", 2, … … 685 871 return(NULL); 686 872 } 873 874 875 876 877 878 879 880 881 882 687 883 688 884 … … 865 1061 return(0.0); 866 1062 } 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 867 1076 868 1077
Note:
See TracChangeset
for help on using the changeset viewer.
