Changeset 6574
- Timestamp:
- 11/15/10 09:57:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/c/shared/Numerics/BrentSearch.cpp
r6412 r6574 20 20 * (Golden or parabolic procedure)*/ 21 21 22 /*optimization variable: */ 23 double si; 24 double gold; 25 double intervalgold; 26 double oldintervalgold; 22 /*Intermediary*/ 23 double si,gold,intervalgold,oldintervalgold; 27 24 double parab_num,parab_den; 28 double distance; 29 30 /*function values: */ 25 double distance,cm_jump; 31 26 double fxmax,fxmin,fxbest; 32 27 double fx,fx1,fx2; 33 34 /*x : */35 28 double xmax,xmin,xbest; 36 29 double x,x1,x2,xm; 37 38 /*tolerances: */39 30 double tol1,tol2,seps,tolerance; 40 int maxiter; 41 double cm_jump; 42 43 /*counters: */ 44 int iter,goldenflag,loop; 31 int maxiter,iter; 32 bool loop,goldenflag; 45 33 46 34 /*Recover parameters:*/ … … 51 39 cm_jump=optpars->cm_jump; 52 40 53 / /initialize counter and boundaries41 /*initialize counter and get response at the boundaries*/ 54 42 iter=0; 55 56 //get the value of the function at the first boundary57 43 fxmin = (*f)(xmin,optargs); 58 44 if isnan(fxmin) _error_("Function evaluation returned NaN"); 59 60 //display result61 45 _printf_(VerboseControl(),"\n Iteration x f(x) Tolerance Procedure\n\n"); 62 46 _printf_(VerboseControl()," %s %12.6g %12.6g %s"," N/A",xmin,fxmin," N/A boundary\n"); 63 64 //get the value of the function at the first boundary xmax and display result65 47 fxmax = (*f)(xmax,optargs); 66 48 if isnan(fxmax) _error_("Function evaluation returned NaN"); 67 49 _printf_(VerboseControl()," %s %12.6g %12.6g %s"," N/A",xmax,fxmax," N/A boundary\n"); 68 50 69 //test if jump option activated and xmin==0 70 if (!isnan(cm_jump) && (xmin==0)){ 71 72 //test ration between fxmin and fxmax. if < criterion, return 73 if((fxmax/fxmin)<cm_jump){ 74 75 /*Assign output pointers: */ 76 *psearch_scalar=xmax; 77 *pJ=fxmax; 78 return; 79 } 51 /*test if jump option activated and xmin==0*/ 52 if (!isnan(cm_jump) && (xmin==0) && (fxmax/fxmin)<cm_jump){ 53 *psearch_scalar=xmax; 54 *pJ=fxmax; 55 return; 80 56 } 81 57 82 / /initialize the other variables58 /*initialize optimization variables*/ 83 59 seps=sqrt(DBL_EPSILON); //precision of a double 84 60 distance=0.0; //new_x=old_x + distance … … 86 62 intervalgold=0.0; //distance used by Golden procedure 87 63 88 //Compute initial point 89 90 //1: initialize the value of the 4 x needed (x1,x2,x,xbest) 64 /*1: initialize the values of the 4 x needed (x1,x2,x,xbest)*/ 91 65 x1=xmin+gold*(xmax-xmin); 92 66 x2=x1; … … 94 68 x=xbest; 95 69 96 / /2: call the function to be evaluated70 /*2: call the function to be evaluated*/ 97 71 fxbest = (*f)(x,optargs); 98 if isnan(fxbest) _error_("Function evaluation returned NaN");72 if(isnan(fxbest)) _error_("Function evaluation returned NaN"); 99 73 iter=iter+1; 100 74 101 / /3: update the other variables75 /*3: update the other variables*/ 102 76 fx1=fxbest; 103 77 fx2=fxbest; 104 / /xm is always in the middle of a and b78 /*xm is always in the middle of a and b*/ 105 79 xm=0.5*(xmin+xmax); 106 / /update tolerances80 /*update tolerances*/ 107 81 tol1=seps*sqrt(pow(xbest,2))+tolerance/3.0; 108 82 tol2=2.0*tol1; 109 83 110 / /4: print result84 /*4: print result*/ 111 85 _printf_(VerboseControl()," %5i %12.6g %12.6g %12.6g %s\n",iter,xbest,fxbest,pow(pow(xbest-xm,2),0.5)," initial"); 112 86 113 //Main Loop 114 loop=1; 87 loop=true; 115 88 while(loop){ 116 89 117 goldenflag= 1;90 goldenflag=true; 118 91 119 92 // Is a parabolic fit possible ? … … 121 94 122 95 // Yes, so fit parabola 123 goldenflag= 0;96 goldenflag=false; 124 97 parab_num=(xbest-x1)*(xbest-x1)*(fxbest-fx2)-(xbest-x2)*(xbest-x2)*(fxbest-fx1);; 125 98 parab_den=2.0*(xbest-x1)*(fxbest-fx2)-2.0*(xbest-x2)*(fxbest-fx1); … … 145 118 // f must not be evaluated too close to min_x or max_x 146 119 if (((x-xmin)<tol2) || ((xmax-x)<tol2)){ 147 148 if ((xm-xbest)<0.0){ 149 si=-1; 150 } 151 else{ 152 si=1; 153 } 154 120 if ((xm-xbest)<0.0) si=-1; 121 else si=1; 155 122 //compute new distance 156 123 distance=tol1*si; … … 158 125 } 159 126 else{ 160 161 127 // Not acceptable, must do a golden section step 162 goldenflag= 1;128 goldenflag=true; 163 129 } 164 130 } … … 166 132 //Golden procedure 167 133 if(goldenflag){ 168 169 134 // compute the new distance d 170 135 if(xbest>=xm){ … … 178 143 179 144 // The function must not be evaluated too close to xbest 180 if(distance<0){ 181 si=-1; 182 } 183 else{ 184 si=1; 185 } 186 if (sqrt(pow(distance,2))>tol1){ 187 x=xbest+si*sqrt(pow(distance,2)); 188 } 189 else{ 190 x=xbest+si*tol1; 191 } 145 if(distance<0) si=-1; 146 else si=1; 147 if(sqrt(pow(distance,2))>tol1) x=xbest+si*sqrt(pow(distance,2)); 148 else x=xbest+si*tol1; 192 149 193 150 //evaluate function on x 194 151 fx = (*f)(x,optargs); 195 if isnan(fx) _error_("Function evaluation returned NaN");152 if(isnan(fx)) _error_("Function evaluation returned NaN"); 196 153 iter=iter+1; 197 154 198 155 // Update a, b, xm, x1, x2, tol1, tol2 199 156 if (fx<=fxbest){ 200 if (x>=xbest){ 201 xmin=xbest; 202 } 203 else{ 204 xmax=xbest; 205 } 157 if (x>=xbest) xmin=xbest; 158 else xmax=xbest; 206 159 x1=x2; fx1=fx2; 207 160 x2=xbest; fx2=fxbest; 208 161 xbest=x; fxbest=fx; 209 162 } 210 211 163 else{ // fx > fxbest 212 if (x < xbest){ 213 xmin=x; 214 } 215 else{ 216 xmax=x; 217 } 164 if (x<xbest) xmin=x; 165 else xmax=x; 218 166 if ((fx<=fx2) || (x2==xbest)){ 219 167 x1=x2; fx1=fx2; … … 227 175 tol1=seps*pow(pow(xbest,2),0.5)+tolerance/3.0; 228 176 tol2=2.0*tol1; 229 230 //print result 231 if (goldenflag){ 232 _printf_(VerboseControl()," %5i %12.6g %12.6g %12.6g %s\n",iter,x,fx,pow(pow(xbest-xm,2),0.5)," golden"); 233 } 234 else{ 235 _printf_(VerboseControl()," %5i %12.6g %12.6g %12.6g %s\n",iter,x,fx,pow(pow(xbest-xm,2),0.5)," parabolic"); 236 } 237 238 //Stop the optimization? 177 _printf_(VerboseControl()," %5i %12.6g %12.6g %12.6g %s\n",iter,x,fx,pow(pow(xbest-xm,2),0.5),goldenflag?" golden":" parabolic"); 178 179 /*Stop the optimization?*/ 239 180 if (sqrt(pow(xbest-xm,2)) < (tol2-0.5*(xmax-xmin))){ 240 181 _printf_(VerboseControl()," %s%g\n","optimization terminated: the current x satisfies the termination criteria using 'tolx' of" ,tolerance); 241 loop= 0;182 loop=false; 242 183 } 243 184 else if (iter>=maxiter){ 244 185 _printf_(VerboseControl()," %s\n","exiting: Maximum number of iterations has been exceeded - increase 'maxiter'\n"); 245 loop=0; 186 loop=false; 187 } 188 else if (!isnan(cm_jump) && (xmin==0) && ((fxbest/fxmin)<cm_jump)){ 189 _printf_(VerboseControl()," %s%g\n","optimization terminated: the current x satisfies the termination criteria using 'cm_jump' of" ,cm_jump); 190 loop=false; 246 191 } 247 192 else{ 248 193 //continue 249 loop= 1;194 loop=true; 250 195 } 251 196 }//end while … … 253 198 //Now, check that the value on the boundaries are not better than current fxbest 254 199 if (fxbest>fxmin){ 255 xbest=optpars->xmin;; 256 fxbest=fxmin; 200 xbest=optpars->xmin; fxbest=fxmin; 257 201 } 258 202 if (fxbest>fxmax){ 259 xbest=optpars->xmax;; 260 fxbest=fxmax; 203 xbest=optpars->xmax; fxbest=fxmax; 261 204 } 262 205
Note:
See TracChangeset
for help on using the changeset viewer.