Changeset 6574


Ignore:
Timestamp:
11/15/10 09:57:00 (14 years ago)
Author:
Mathieu Morlighem
Message:

Extended cm_jump so that whenever f(x)/f(0)<cm_jump, return

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/shared/Numerics/BrentSearch.cpp

    r6412 r6574  
    2020         * (Golden or parabolic procedure)*/
    2121
    22         /*optimization variable: */
    23         double si;
    24         double gold;
    25         double intervalgold;
    26         double oldintervalgold;
     22        /*Intermediary*/
     23        double si,gold,intervalgold,oldintervalgold;
    2724        double parab_num,parab_den;
    28         double distance;
    29 
    30         /*function values: */
     25        double distance,cm_jump;
    3126        double fxmax,fxmin,fxbest;
    3227        double fx,fx1,fx2;
    33 
    34         /*x : */
    3528        double xmax,xmin,xbest;
    3629        double x,x1,x2,xm;
    37 
    38         /*tolerances: */
    3930        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;
    4533
    4634        /*Recover parameters:*/
     
    5139        cm_jump=optpars->cm_jump;
    5240       
    53         //initialize counter and boundaries
     41        /*initialize counter and get response at the boundaries*/
    5442        iter=0;
    55 
    56         //get the value of the function at the first boundary
    5743        fxmin = (*f)(xmin,optargs);
    5844        if isnan(fxmin) _error_("Function evaluation returned NaN");
    59 
    60         //display result
    6145        _printf_(VerboseControl(),"\n        Iteration         x           f(x)       Tolerance         Procedure\n\n");
    6246        _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 result
    6547        fxmax = (*f)(xmax,optargs);
    6648        if isnan(fxmax) _error_("Function evaluation returned NaN");
    6749        _printf_(VerboseControl(),"        %s    %12.6g  %12.6g  %s","   N/A",xmax,fxmax,"         N/A         boundary\n");
    6850
    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;
    8056        }
    8157
    82         //initialize the other variables
     58        /*initialize optimization variables*/
    8359        seps=sqrt(DBL_EPSILON);    //precision of a double
    8460        distance=0.0;              //new_x=old_x + distance
     
    8662        intervalgold=0.0;          //distance used by Golden procedure
    8763
    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)*/
    9165        x1=xmin+gold*(xmax-xmin);
    9266        x2=x1;
     
    9468        x=xbest;
    9569
    96         //2: call the function to be evaluated
     70        /*2: call the function to be evaluated*/
    9771        fxbest = (*f)(x,optargs);
    98         if isnan(fxbest) _error_("Function evaluation returned NaN");
     72        if(isnan(fxbest)) _error_("Function evaluation returned NaN");
    9973        iter=iter+1;
    10074
    101         //3: update the other variables
     75        /*3: update the other variables*/
    10276        fx1=fxbest;
    10377        fx2=fxbest;
    104         //xm is always in the middle of a and b
     78        /*xm is always in the middle of a and b*/
    10579        xm=0.5*(xmin+xmax);                           
    106         //update tolerances
     80        /*update tolerances*/
    10781        tol1=seps*sqrt(pow(xbest,2))+tolerance/3.0;
    10882        tol2=2.0*tol1;
    10983
    110         //4: print result
     84        /*4: print result*/
    11185        _printf_(VerboseControl(),"         %5i    %12.6g  %12.6g  %12.6g  %s\n",iter,xbest,fxbest,pow(pow(xbest-xm,2),0.5),"       initial");
    11286
    113         //Main Loop
    114         loop=1;
     87        loop=true;
    11588        while(loop){
    11689
    117                 goldenflag=1;
     90                goldenflag=true;
    11891
    11992                // Is a parabolic fit possible ?
     
    12194
    12295                        // Yes, so fit parabola
    123                         goldenflag=0;
     96                        goldenflag=false;
    12497                        parab_num=(xbest-x1)*(xbest-x1)*(fxbest-fx2)-(xbest-x2)*(xbest-x2)*(fxbest-fx1);;
    12598                        parab_den=2.0*(xbest-x1)*(fxbest-fx2)-2.0*(xbest-x2)*(fxbest-fx1);
     
    145118                                // f must not be evaluated too close to min_x or max_x
    146119                                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;
    155122                                        //compute new distance
    156123                                        distance=tol1*si;
     
    158125                        }
    159126                        else{
    160 
    161127                                // Not acceptable, must do a golden section step
    162                                 goldenflag=1;
     128                                goldenflag=true;
    163129                        }
    164130                }
     
    166132                //Golden procedure
    167133                if(goldenflag){
    168 
    169134                        // compute the new distance d
    170135                        if(xbest>=xm){
     
    178143
    179144                // 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;
    192149
    193150                //evaluate function on x
    194151                fx = (*f)(x,optargs);
    195                 if isnan(fx) _error_("Function evaluation returned NaN");
     152                if(isnan(fx)) _error_("Function evaluation returned NaN");
    196153                iter=iter+1;
    197154
    198155                // Update a, b, xm, x1, x2, tol1, tol2
    199156                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;
    206159                        x1=x2;    fx1=fx2;
    207160                        x2=xbest; fx2=fxbest;
    208161                        xbest=x;  fxbest=fx;
    209162                }
    210 
    211163                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;
    218166                        if ((fx<=fx2) || (x2==xbest)){
    219167                                x1=x2; fx1=fx2;
     
    227175                tol1=seps*pow(pow(xbest,2),0.5)+tolerance/3.0;
    228176                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?*/
    239180                if (sqrt(pow(xbest-xm,2)) < (tol2-0.5*(xmax-xmin))){
    240181                        _printf_(VerboseControl(),"      %s%g\n","optimization terminated: the current x satisfies the termination criteria using 'tolx' of" ,tolerance);
    241                         loop=0;
     182                        loop=false;
    242183                }
    243184                else if (iter>=maxiter){
    244185                        _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;
    246191                }
    247192                else{
    248193                        //continue
    249                         loop=1;
     194                        loop=true;
    250195                }
    251196        }//end while
     
    253198        //Now, check that the value on the boundaries are not better than current fxbest
    254199        if (fxbest>fxmin){
    255                 xbest=optpars->xmin;;
    256                 fxbest=fxmin;
     200                xbest=optpars->xmin; fxbest=fxmin;
    257201        }
    258202        if (fxbest>fxmax){
    259                 xbest=optpars->xmax;;
    260                 fxbest=fxmax;
     203                xbest=optpars->xmax; fxbest=fxmax;
    261204        }
    262205
Note: See TracChangeset for help on using the changeset viewer.