Object-oriented Scientific Computing Library: Version 0.910
ool_mmin_gencan.h
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 /*----------------------------------------------------------------------------*
00024  * Open Optimization Library - Constrained Minimization
00025  * 
00026  * gencan/gencan.c
00027  *
00028  * This program is free software; you can redistribute it and/or modify
00029  * it under the terms of the GNU General Public License as published by
00030  * the Free Software Foundation; either version 2 of the License, or (at
00031  * your option) any later version.
00032  * 
00033  * This program is distributed in the hope that it will be useful, but
00034  * WITHOUT ANY WARRANTY; without even the implied warranty of
00035  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00036  * General Public License for more details.
00037  * 
00038  * You should have received a copy of the GNU General Public License
00039  * along with this program; if not, write to the Free Software
00040  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00041  *
00042  * Sergio Drumond Ventura
00043  * Luis Alberto D'Afonseca
00044  * Ricardo Biloti
00045  * since: Feb 16th, 2004
00046  *
00047  * $Id: gencan.c,v 1.16 2005/05/17 19:08:18 biloti Exp $
00048  *----------------------------------------------------------------------------*/
00049 #ifndef O2SCL_OOL_MMIN_GENCAN_H
00050 #define O2SCL_OOL_MMIN_GENCAN_H
00051 
00052 #include <o2scl/text_file.h>
00053 #include <o2scl/ovector_tlate.h>
00054 #include <o2scl/multi_funct.h>
00055 #include <o2scl/ool_constr_min.h>
00056 #include <gsl/gsl_math.h>
00057 
00058 #ifndef DOXYGENP
00059 namespace o2scl {
00060 #endif
00061 
00062   /** \brief Constrained minimization by the "GENCAN" method (OOL)
00063       
00064       \note Not working yet
00065   */
00066   template<class param_t, class func_t, class dfunc_t=func_t, 
00067     class hfunc_t=func_t, class vec_t=ovector_base, class alloc_vec_t=ovector,
00068     class alloc_t=ovector_alloc> class ool_mmin_gencan : 
00069   public ool_constr_min<param_t,func_t,dfunc_t,hfunc_t,vec_t,
00070     alloc_vec_t,alloc_t> {
00071 
00072 #ifndef DOXYGEN_INTERNAL
00073 
00074     protected:
00075 
00076     /// Desc (default 1.0)
00077     double cg_src;
00078 
00079     /// Temporary vector
00080     alloc_vec_t S;
00081     /// Temporary vector
00082     alloc_vec_t Y;
00083     /// Temporary vector
00084     alloc_vec_t D;
00085     /// Temporary vector
00086     alloc_vec_t cg_W;
00087     /// Temporary vector
00088     alloc_vec_t cg_R;
00089     /// Temporary vector
00090     alloc_vec_t cg_D;
00091     /// Temporary vector
00092     alloc_vec_t cg_Sprev;
00093     /// Temporary vector
00094     alloc_vec_t Xtrial;
00095     /// Temporary vector
00096     alloc_vec_t tnls_Xtemp;
00097     /// Temporary vector
00098     alloc_vec_t near_l;
00099     /// Temporary vector
00100     alloc_vec_t near_u;
00101     
00102     /// Desc
00103     int *Ind;
00104 
00105 #ifdef NEVER_DEFINED
00106 
00107     /// Desc
00108     int spgls() {
00109 
00110       gsl_vector *X        = M->x;
00111       gsl_vector *gradient = M->gradient;
00112 
00113       size_t nn = X->size;
00114 
00115       /* Direct access to vector data */
00116       double *l = st->L->data;
00117       double *u = st->U->data;
00118       double *d = st->D->data;
00119       double *x = X->data;
00120 
00121       double *xtrial = st->Xtrial->data;
00122 
00123       /* Internal variables */
00124       size_t interp;
00125       size_t imax;
00126 
00127       double alpha;
00128       double dinfn;
00129       double gtd;
00130       double ftrial;
00131 
00132       /* Compute first trial point, spectral projected gradient direction,
00133        * and directional derivative <g,d> */
00134       alpha = 1;
00135 
00136       /* Xtrial = min{ U, max[ L, ( X-lambda G ) ] } */
00137       gsl_vector_memcpy( st->Xtrial, X );
00138       gsl_blas_daxpy( -(st->lambda), gradient, st->Xtrial );
00139       conmin_vector_minofmax( st->n, xtrial, u, l, xtrial );
00140 
00141       /* D = Xtrial - X */
00142       gsl_vector_memcpy( st->D, st->Xtrial );
00143       gsl_vector_sub( st->D, X );
00144 
00145       /* Inifite norm of D and < G, D > */
00146       imax  = gsl_blas_idamax( st->D );
00147       dinfn = fabs( gsl_vector_get( st->D, imax ) );
00148       gsl_blas_ddot( gradient, st->D, &gtd );
00149 
00150       /* Evaluate objective function */
00151       OOL_CONMIN_EVAL_F( M, st->Xtrial, ftrial );
00152 
00153       interp = 0;
00154 
00155       /* While Armijo isn't satisfied repeat */
00156       while (ftrial > M->f + P->gamma*alpha*gtd ) {
00157 
00158         /* Test if the trial point has a function value lower than fmin */
00159         if (ftrial < M->f ) {
00160 
00161           M->f = ftrial;
00162           gsl_vector_memcpy( X, st->Xtrial );
00163 
00164           return OOL_UNBOUNDEDF;
00165         }
00166 
00167         interp++;
00168 
00169         if (alpha < P->sigma1 ) {
00170           alpha /= P->nint;
00171         } else {
00172           /* quadratic model */
00173           double atemp = ( -gtd*alpha*alpha )/
00174             ( 2.0*(ftrial-M->f-alpha*gtd) );
00175 
00176           if (atemp < P->sigma1 || atemp > P->sigma2*alpha ) {
00177             alpha /= P->nint;
00178           } else {
00179             alpha  = atemp;
00180           }
00181         }
00182 
00183         /* Compute new trial point
00184          * Xtrial = X + alpha D */
00185         gsl_vector_memcpy( st->Xtrial, X );
00186         gsl_blas_daxpy( alpha, st->D, st->Xtrial );
00187 
00188         /* Evaluate objective function */
00189         OOL_CONMIN_EVAL_F( M, st->Xtrial, ftrial );
00190 
00191         /* Test whether at least mininterp interpolations were made
00192          * and two consecutive iterates are close enough */
00193         if( interp > P->mininterp &&
00194             are_close( nn, alpha, d, x, P->epsrel, P->epsabs )) {
00195 
00196           M->f = ftrial;
00197           gsl_vector_memcpy( X, st->Xtrial );
00198             
00199           return OOL_FLSEARCH;
00200         }
00201       }
00202       
00203       /* Set new values of f and X */
00204       M->f = ftrial;
00205       gsl_vector_memcpy( X, st->Xtrial );
00206 
00207       return OOL_SUCCESS;
00208     }
00209 
00210     /// Desc
00211     int tnls() {
00212 
00213       gsl_vector *X        = M->x;
00214       gsl_vector *gradient = M->gradient;
00215       gsl_vector *Xplus    = st->Xtrial;
00216 
00217       /* Direct access to vector data */
00218       double *x = X->data;
00219       double *g = gradient->data;
00220       double *d = st->D->data;
00221       double *xplus = Xplus->data;
00222 
00223       /* Constant values */
00224       const size_t nind = st->nind;
00225 
00226       /* Internal variables */
00227       double fplus;
00228       double gtd;
00229       double alpha;
00230       double gptd;
00231 
00232       /* Compute directional derivative */
00233       gtd = cblas_ddot( (int)nind, g, 1, d, 1 );
00234 
00235       /* Compute first trial */
00236       alpha = GSL_MIN( 1.0, st->tnls_amax );
00237 
00238       /* Xplus = X + alpha D */
00239       conmin_vector_memcpy( nind, xplus, x );
00240       cblas_daxpy( alpha,  (int)nind,d, 1, xplus, 1 );
00241 
00242       /* Evaluate objective function */
00243       fplus = conmin_calc_f( M, nind, st->Ind, Xplus, X );
00244 
00245       /* Test Armijo and beta-condition and decide for:
00246        * 1 - accepting the trial point,
00247        * 2 - interpolate or
00248        * 3 - extrapolate. */
00249       if( st->tnls_amax > 1.0 ) {
00250 
00251         /* X+D belongs to the interior of the feasible set (amax > 1) */
00252 
00253         /* Verify Armijo */
00254         if( fplus <= M->f + P->gamma * alpha * gtd ) {
00255 
00256           /* Armijo condition holds */
00257 
00258           /* Evaluate the gradient of objective function */
00259           conmin_calc_g( M, nind, st->Ind, Xplus, X, gradient );
00260           /* Eval gptd = < g, d > */
00261           gptd = cblas_ddot( (int)nind, g, 1, d, 1 );
00262 
00263           /* Verify directional derivative (beta condition) */
00264           if ( gptd >= P->beta * gtd ) {
00265 
00266             /* Step = 1 was ok, finish the line search */
00267 
00268             M->f = fplus;
00269             conmin_vector_memcpy( nind, x, xplus );
00270 
00271             return OOL_SUCCESS;
00272           } else {
00273             return tnls_extrapolation( M, st, P, alpha, fplus );
00274           }
00275         } else {
00276           return tnls_interpolation(M, st, P, alpha, fplus, gtd);
00277         }
00278       } else {
00279         /* x + d does not belong to the feasible set (amax <= 1) */
00280         if( fplus < M->f ) {
00281           return tnls_extrapolation( M, st, P, alpha, fplus );
00282         } else {
00283           return tnls_interpolation(M, st, P, alpha, fplus, gtd);
00284         }
00285       }
00286     }
00287 
00288     /// Desc
00289     int tnls_extrapolation(double alpha, double fplus) {
00290 
00291       gsl_vector *X        = M->x;
00292       gsl_vector *gradient = M->gradient;
00293       gsl_vector *Xplus    = st->Xtrial;
00294 
00295       /* Direct access to vector data */
00296       double *x = X->data;
00297       double *d = st->D->data;
00298       double *l = st->L->data;
00299       double *u = st->U->data;
00300 
00301       double *xplus = Xplus->data;
00302       double *xtemp = st->tnls_Xtemp->data;
00303 
00304       /* Constant values */
00305       const size_t nind = st->nind;
00306 
00307       /* Internal variables */
00308       double atemp;
00309       double ftemp;
00310 
00311       size_t ii, extrap;
00312       short same;
00313 
00314       /* Iterations */
00315       extrap = 0;
00316       do {
00317 
00318         extrap++;
00319 
00320         /* Test if maximum number of extrapolation was exceeded */
00321         if ( extrap > P->maxextrap ) {
00322 
00323           M->f = fplus;
00324           conmin_vector_memcpy( nind, x, xplus );
00325 
00326           if (extrap > 0 || st->tnls_amax < 1){
00327             conmin_calc_g( M, nind, st->Ind, Xplus, X, gradient );
00328           }
00329           return TNLS_MAXEXTRAP;
00330         }
00331 
00332         /* Chose new step */
00333         if (alpha < st->tnls_amax && st->tnls_amax < P->next*alpha ) {
00334           atemp = st->tnls_amax;
00335         } else {
00336           atemp = P->next * alpha;
00337         }
00338 
00339         /* Compute new trial point. Xtemp = X + atemp*D */
00340         conmin_vector_memcpy( nind, xtemp, x );
00341         cblas_daxpy( atemp, (int)nind, d, 1, xtemp, 1 );
00342 
00343         /* Project */
00344         if (atemp > st->tnls_amax ) {
00345           conmin_vector_maxofmin( nind, xtemp, l, xtemp, u );
00346         }
00347 
00348         /* Test if this is not the same point as the previous one.
00349          * This test is performed only when alpha >= amax. */
00350         if( alpha > st->tnls_amax ) {
00351 
00352           same = 1;
00353           for (ii = 0; ii<nind && same; ii++) {
00354 
00355             double aux;
00356 
00357             aux = P->epsrel * fabs( xplus[ii] );
00358             
00359             if ( fabs(xtemp[ii]-xplus[ii]) > GSL_MAX(aux,P->epsabs)) {
00360               same = 0;
00361             }
00362           }
00363 
00364           if (same) {
00365 
00366             /* Finish the extrapolation with the current point */
00367             M->f = fplus;
00368 
00369             conmin_vector_memcpy( nind, x, xplus );
00370 
00371             if (extrap > 0 || st->tnls_amax < 1){
00372               conmin_calc_g( M, nind, st->Ind, Xplus, X, gradient );
00373             }
00374             return OOL_SUCCESS;
00375           }
00376         }
00377 
00378         ftemp = conmin_calc_f( M, nind, st->Ind, st->tnls_Xtemp, X );
00379 
00380         if (ftemp < fplus) {
00381           
00382           /* If the functional value decreases then set the current
00383            * point and continue the extrapolation */
00384           
00385           alpha = atemp;
00386           fplus = ftemp;
00387           conmin_vector_memcpy( nind, xplus, xtemp );
00388 
00389           continue;
00390 
00391         } else {
00392 
00393           /* If the functional value does not decrease then discard the
00394            * last trial and finish the extrapolation with the previous
00395            * point */
00396 
00397           M->f = fplus;
00398 
00399           conmin_vector_memcpy( nind, x, xplus );
00400           if (extrap > 0 || st->tnls_amax < 1) {
00401             conmin_calc_g( M, nind, st->Ind, X, X, gradient );
00402           }
00403 
00404           return OOL_SUCCESS;
00405         }
00406 
00407       } while (1);
00408 
00409       /* Just to make gcc happy */
00410       return OOL_SUCCESS;
00411     }
00412 
00413     /// Desc
00414     int tnls_interpolation(double alpha, double fplus, double gtd) {
00415 
00416       gsl_vector *X        = M->x;
00417       gsl_vector *gradient = M->gradient;
00418       gsl_vector *Xplus    = st->Xtrial;
00419 
00420       /* Direct access to vector data */
00421       double *x = X->data;
00422       double *d = st->D->data;
00423       double *xplus = Xplus->data;
00424 
00425       /* Constant values */
00426       const size_t nind = st->nind;
00427 
00428       /* Internal variables */
00429       size_t interp;
00430       double atemp;
00431 
00432       /* Initialization */
00433       interp = 0;
00434 
00435       /* Iterations */
00436       do {
00437         interp++;
00438         
00439         /* Test Armijo condition */
00440         if (fplus <= M->f + P->gamma * alpha * gtd ) {
00441 
00442           /* Finish the line search */
00443           M->f = fplus;
00444 
00445           /* X = Xplus */
00446           conmin_vector_memcpy( nind, x, xplus );
00447 
00448           /* Evaluate objective function gradient */
00449           conmin_calc_g( M, nind, st->Ind, X, X, gradient );
00450 
00451           return OOL_SUCCESS;
00452         }
00453         /* Compute new step */
00454         if (alpha < P->sigma1 ) {
00455           alpha= alpha / P->nint;
00456         } else {
00457           /* quadratic model */
00458           atemp = -gtd * alpha*alpha /
00459             (2 * (fplus - M->f - alpha * gtd));
00460 
00461           if( atemp < P->sigma1       ||
00462               atemp > P->sigma2*alpha  ) {
00463             alpha = alpha / P->nint;
00464           } else {
00465             alpha = atemp;
00466           }
00467         }
00468 
00469         /* Compute new trial point: xplus = x + alpha d */
00470         conmin_vector_memcpy( nind, xplus, x );
00471         cblas_daxpy( alpha, (int)nind, d, 1, xplus, 1 );
00472 
00473         /* Evaluate objective function */
00474         fplus = conmin_calc_f( M, nind, st->Ind, Xplus, X );
00475 
00476         /* Test whether at least mininterp interpolations were made
00477          * and the steplength is soo small */
00478         if ( are_close( nind, alpha, d, x,  P->epsrel, P->epsabs ) &&
00479              interp > P->mininterp ){
00480           return OOL_FLSEARCH;
00481         }
00482       }
00483       while( 1 );
00484 
00485       /* Just to make gcc happy */
00486       return OOL_SUCCESS;
00487     }
00488 
00489     /** Truncated Newton maximum step*/
00490     double tnls_maximum_step() {
00491 
00492       /* Direct access to vector data */
00493       double *x =  M->x->data;
00494       double *l = st->L->data;
00495       double *u = st->U->data;
00496       double *d = st->D->data;
00497 
00498       double step = P->infabs;
00499       size_t ii;
00500       
00501       for( ii = 0; ii < st->nind; ii++ ) {
00502 
00503         if( *d > 0 ) {
00504               double aux = ( *u - *x ) / *d;
00505               step = GSL_MIN( step, aux );
00506             } else if( *d < 0 ) {
00507               double aux = ( *l - *x ) / *d;
00508               step = GSL_MIN( step, aux );
00509             }
00510 
00511           x++;
00512           l++;
00513           u++;
00514           d++;
00515         }
00516 
00517       return step;
00518     }
00519 
00520     /** Spectral step length */
00521     void spg_steplength() {
00522       
00523       if (st->sty <= 0.0) {
00524         st->lambda = GSL_MAX( 1.0, st->xeucn ) / sqrt( st->gpeucn2 );
00525       } else {
00526         double aux;
00527         double ss   = st->sts / st->sty;
00528         
00529         aux = GSL_MAX( P->lspgmi, ss );
00530         st->lambda = GSL_MIN( P->lspgma, aux );
00531       }
00532     }
00533 
00534     /** Iterate */
00535     int actual_iterate() {
00536       
00537       /* Direct access to vector data */
00538       double *x =  M->x->data;
00539       double *l = st->L->data;
00540       double *u = st->U->data;
00541       /*  double *d = st->D->data; */
00542 
00543       /* Status of internal iterations */
00544       int lsflag;
00545       int cgflag;
00546 
00547       /* Internal variables */
00548       size_t ii, imax;
00549 
00550       /* Saving previous values */
00551       gsl_vector_memcpy( st->S, M->x        );
00552       gsl_vector_memcpy( st->Y, M->gradient );
00553 
00554       /* The actual iteration */
00555       if ( st->gieucn2 <= st->ometa2 * st->gpeucn2 ) {
00556         /* Compute the new iterate using an SPG iteration */
00557 
00558         /* Perform a line search with spectral continuous 
00559            projected gradient */
00560         lsflag = spgls( M, st, P );
00561 
00562         /* Compute the gradient for the new iterate */
00563         OOL_CONMIN_EVAL_DF( M, M->x, M->gradient );
00564 
00565       } else {
00566 
00567         /* The new iterate will belong to the closure of the actual face */
00568 
00569         /* Shrink the point, its gradient and the bounds */
00570         conmin_shrink( st->nind, st->Ind, M->x        );
00571         conmin_shrink( st->nind, st->Ind, M->gradient );
00572         conmin_shrink( st->nind, st->Ind, st->L       );
00573         conmin_shrink( st->nind, st->Ind, st->U       );
00574     
00575         /* Compute the descent direction solving the newtonian system */
00576         cgflag = cg( M, st, P );
00577 
00578         /* Compute maximum step for truncated newton line search */
00579         if ( cgflag == CG_BOUNDARY ) {
00580           st->tnls_amax = 1.0;
00581         } else {
00582           st->tnls_amax = tnls_maximum_step( M, st, P );
00583         }
00584 
00585         /* Perform the line search */
00586         lsflag = tnls( M, st, P );
00587 
00588         /* Expand the point, its gradient and the bounds */
00589         conmin_expand( st->nind, st->Ind, M->x        );
00590         conmin_expand( st->nind, st->Ind, M->gradient );
00591         conmin_expand( st->nind, st->Ind, st->L       );
00592         conmin_expand( st->nind, st->Ind, st->U       );
00593 
00594         /* If the line search in the Truncated Newton direction
00595            stopped due to a very small step discard this iteration
00596            and force a SPG iteration */
00597         if ( lsflag == OOL_FLSEARCH ) {
00598 
00599           /* Perform a line search with spectral projected gradient */
00600           lsflag = spgls( M, st, P );
00601 
00602           /* Compute the gradient for the new iterate */
00603           OOL_CONMIN_EVAL_DF( M, M->x, M->gradient );
00604         }
00605       }
00606 
00607       /* Prepare for the next iteration */
00608       /* Adjustment */
00609       for( ii = 0; ii < st->n; ii++ ) {
00610         /* In principle, the current point could be slightly changed
00611          * here, requiring a new function and gradient
00612          * evaluation. But, according to the algorithms authors, this
00613          * is done just to account for points that are "numerically¨
00614          * at faces already. Thus, no additional evaluations are
00615          * performed. (May 11th, 2005).
00616          */
00617         if     ( x[ii] <= st->near_l[ii] ) x[ii] = l[ii];
00618         else if( x[ii] >= st->near_u[ii] ) x[ii] = u[ii];
00619       }
00620 
00621       /* Compute infinite and Euclidian-norm of X */
00622       imax      = gsl_blas_idamax( M->x );
00623       st->xsupn = fabs( gsl_vector_get( M->x, imax ) );
00624       st->xeucn = gsl_blas_dnrm2 ( M->x ); 
00625 
00626       /* Until now S = X_prev, now S = X - X_prev 
00627        * Compute s = x_{k+1} - x_k = X - S
00628        * and     y = g_{k+1} - g_k = G - Y  */
00629       gsl_vector_sub  ( st->S, M->x        ); /* S = S - X */
00630       gsl_vector_scale( st->S, -1.0        ); /* S = -S = X - S_prev */
00631       gsl_vector_sub  ( st->Y, M->gradient ); /* Y = Y - G */
00632       gsl_vector_scale( st->Y, -1.0        ); /* Y = -Y = G - Y_prev */
00633 
00634       /* Compute sts = s dot s 
00635        *         sty = s dot y
00636        * and     sinf = |s|_inf */
00637       gsl_blas_ddot( st->S, st->S, &(st->sts) );    
00638       gsl_blas_ddot( st->S, st->Y, &(st->sty) );
00639       imax      = gsl_blas_idamax( st->S );
00640       st->sinf  = fabs( gsl_vector_get( st->S, imax ) );
00641 
00642       /* Compute continuous project gradient */
00643       projected_gradient( st, M->x, M->gradient );
00644 
00645       /* Update spectral steplength */
00646       spg_steplength( st, P );
00647 
00648       /* Update trust-region radius */
00649       if ( P->trtype ) st->cg_delta = GSL_MAX( P->delmin, 10*sqrt( st->sts ) );
00650       else             st->cg_delta = GSL_MAX( P->delmin, 10*    ( st->sinf) );
00651 
00652       return lsflag;
00653     }
00654 
00655 #endif
00656 
00657 #endif
00658 
00659     public:
00660 
00661     ool_mmin_gencan() {
00662       epsgpen=1.0e-5;
00663       epsgpsn=1.0e-5;
00664       fmin=-1.0e99;
00665       udelta0=-1.0;
00666       ucgmia=-1.0;
00667       ucgmib=-1.0;
00668       cg_src=1.0;
00669       cg_scre=1.0;
00670       cg_gpnf=1.0e-5;
00671       cg_epsi=1.0e-1;
00672       cg_epsf=1.0e-5;
00673       cg_epsnqmp=1.0e-4;
00674       cg_maxitnqmp=5;
00675       nearlyq=0;
00676       nint=2.0;
00677       next=2.0;
00678       mininterp=4;
00679       maxextrap=100;
00680       trtype=0;
00681       eta=0.9;
00682       delmin=0.1;
00683       lspgmi=1.0e-10;
00684       lspgma=1.0e10;
00685       theta=1.0e-6;
00686       gamma=1.0e-4;
00687       beta=0.5;
00688       sigma1=0.1;
00689       sigma2=0.9;
00690       epsrel=1.0e-7;
00691       epsabs=1.0e-10;
00692       infrel=1.0e20;
00693       infabs=1.0e99;
00694     }
00695 
00696     /// Tolerance on Euclidean norm of projected gradient (default 1.0e-5)
00697     double epsgpen;
00698     /// Tolerance on infinite norm of projected gradient (default 1.0e-5)
00699     double epsgpsn;
00700     /** \brief Minimum function value (default \f$ 10^{-99} \f$)
00701         
00702         If the function value is below this value, then the algorithm
00703         assumes that the function is not bounded and exits.
00704     */
00705     double fmin;
00706     /// Trust-region radius (default -1.0)
00707     double udelta0;
00708     /// Maximum interations per variable (default -1.0)
00709     double ucgmia;
00710     /// Extra maximum iterations (default -1.0)
00711     double ucgmib;
00712     /// Conjugate gradient condition type (default 1)
00713     int cg_scre;
00714     /// Projected gradient norm (default 1.0e-5)
00715     double cg_gpnf;
00716     /// Desc (default 1.0e-1)
00717     double cg_epsi;
00718     /// Desc (default 1.0e-5)
00719     double cg_epsf;
00720     /// Stopping fractional tolerance for conjugate gradient (default 1.0e-4)
00721     double cg_epsnqmp;
00722     /// Maximum iterations for conjugate gradient (default 5)
00723     int cg_maxitnqmp;
00724     /// Set to 1 if the function is nearly quadratic (default 0)
00725     int nearlyq;
00726     /// Interpolation constant (default 2.0)
00727     double nint;
00728     /// Extrapolation constant (default 2.0)
00729     double next;
00730     /// Minimum interpolation size (default 4)
00731     int mininterp;
00732     /// Maximum extrapolations in truncated Newton direction (default 100)
00733     int maxextrap;
00734     /// Type of trust region (default 0)
00735     int trtype;
00736     /// Threshold for abandoning current face (default 0.9)
00737     double eta;
00738     /// Minimum trust region for truncated Newton direction (default 0.1)
00739     double delmin;
00740     /// Minimum spectral steplength (default 1.0e-10)
00741     double lspgmi;
00742     /// Maximum spectral steplength (default 1.0e10)
00743     double lspgma;
00744     /// Constant for the angle condition (default 1.0e-6)
00745     double theta;
00746     /// Constant for Armijo condition (default 1.0e-4)
00747     double gamma;
00748     /// Constant for beta condition (default 0.5)
00749     double beta;
00750     /// Lower bound to the step length reduction (default 0.1)
00751     double sigma1;
00752     /// Upper bound to the step length reduction (default 0.9)
00753     double sigma2;
00754     /// Relative small number (default 1.0e-7)
00755     double epsrel;
00756     /// Absolute small number (default 1.0e-10)
00757     double epsabs;
00758     /// Relative infinite number (default 1.0e20)
00759     double infrel;
00760     /// Absolute infinite number (default 1.0e99)
00761     double infabs;
00762     
00763     /// Allocate memory
00764     virtual int alloc(const size_t n) {
00765       if (this->dim>0) free();
00766       this->ao.allocate(xx,n);
00767       this->ao.allocate(d,n);
00768       this->ao.allocate(s,n);
00769       this->ao.allocate(y,n);
00770       return ool_constr_min<param_t,func_t,dfunc_t,hfunc_t,vec_t,alloc_vec_t,
00771         alloc_t>::alloc(n);
00772     }
00773     
00774     /// Free previously allocated memory
00775     virtual int free() {
00776       if (this->dim>0) this->ao.free(xx);
00777       return ool_constr_min<param_t,func_t,dfunc_t,hfunc_t,vec_t,alloc_vec_t,
00778       alloc_t>::free();
00779     }
00780     
00781     /// Set the function, the initial guess, and the parameters
00782     virtual int set(func_t &fn, dfunc_t &dfn, hfunc_t &hfn,
00783                     vec_t &init, param_t &par) {
00784       
00785       int ret=ool_constr_min<param_t,func_t,dfunc_t,hfunc_t,vec_t,alloc_vec_t,
00786       alloc_t>::set(fn,dfn,hfn,init,par);
00787 
00788 #ifdef NEVER_DEFINED
00789       // Internal variables 
00790       size_t nn = M->x->size;
00791       
00792       // Checking dimensions 
00793       if( nn != st->n || nn != M->fdf->n || nn != M->con->n  )
00794         {
00795           return OOL_EINVAL;
00796         }
00797       
00798       // Copy boundary vectors 
00799       gsl_vector_memcpy( st->L, M->con->L );
00800       gsl_vector_memcpy( st->U, M->con->U );
00801       
00802 #endif
00803 
00804       prepare_iteration();
00805 
00806       return 0;
00807     }
00808 
00809 #ifdef NEVER_DEFINED
00810 
00811     int prepare_iteration {
00812 
00813       /* Direct access to vector data */
00814       double *x =  M->x->data;
00815       double *l = st->L->data;
00816       double *u = st->U->data;
00817 
00818       /* Internal variables */
00819       size_t nn = M->x->size;
00820       size_t ii, imax;
00821 
00822       /* Impose factibility */
00823       conmin_vector_maxofmin( nn, x, l, u, x );
00824 
00825       /* Eval Euclidean and infinity norms of X */
00826       st->xeucn = gsl_blas_dnrm2 ( M->x );
00827       imax      = gsl_blas_idamax( M->x );
00828       st->xsupn = fabs( gsl_vector_get( M->x, imax ) );
00829 
00830       /* Evaluate objective function and its gradient */
00831       OOL_CONMIN_EVAL_FDF( M, M->x, &(M->f), M->gradient );
00832 
00833       /* Define near_l and near_u vector */
00834       for (ii=0; ii < nn; ii++){
00835         st->near_l[ii] = l[ii] + GSL_MAX( P->epsrel*fabs( l[ii] ), P->epsabs );
00836         st->near_u[ii] = u[ii] - GSL_MAX( P->epsrel*fabs( u[ii] ), P->epsabs );
00837       }
00838 
00839       /* Setting constant parameters */
00840       st->ometa2 = gsl_pow_2( 1.0 - P->eta );
00841       st->epsgpen2 = gsl_pow_2( P->epsgpen );
00842 
00843       /* Compute continuous project gradient */
00844       projected_gradient( st, M->x, M->gradient );
00845 
00846       /* Compute a linear relation between gpeucn2 and cgeps2, i.e.,
00847        * scalars a and b such that
00848        *
00849        *     a * log10(||g_P(x_0)||_2^2) + b = log10(cgeps_0^2) and
00850        *
00851        *     a * log10(||g_P(x_f)||_2^2) + b = log10(cgeps_f^2),
00852        *
00853        *  where cgeps_0 and cgeps_f are provided. Note that if
00854        *  cgeps_0 is equal to cgeps_f then cgeps will be always
00855        *  equal to cgeps_0 and cgeps_f.
00856        *
00857        *  We introduce now a linear relation between gpsupn and cgeps also.
00858        */
00859       if (P->cg_scre == 1 ) {
00860         st->acgeps = 2 *( log10( P->cg_epsf / P->cg_epsi ) /
00861                           log10( P->cg_gpnf * P->cg_gpnf / st->gpeucn2 ));
00862 
00863         st->bcgeps = 2 * log10( P->cg_epsi ) -
00864           st->acgeps * log10( st->gpeucn2 );
00865       } else {
00866         st->acgeps = ( log10( P->cg_epsf / P->cg_epsi ) /
00867                        log10( P->cg_gpnf / st->gpsupn ) );
00868         st->bcgeps = log10( P->cg_epsi ) - st->acgeps * log10( st->gpsupn );
00869       }
00870 
00871       /*     And it will be used for the linear relation of cgmaxit */
00872       st->gpsupn0  = st->gpsupn;
00873       st->gpeucn20 = st->gpeucn2;
00874 
00875       /* Initialize the spectral steplength */
00876       if ( st->gpeucn2 != 0.0 ) {
00877         st->lambda = GSL_MAX( 1.0, st->xeucn ) / sqrt( st->gpeucn2 );
00878       }
00879 
00880       /* Initialize the trust-region radius */
00881       if (P->udelta0 < 0.0 ) {
00882 
00883         double aux;
00884         if ( P->trtype ) {
00885           aux = 0.1 * GSL_MAX( 1.0, st->xeucn );
00886         } else  {
00887           aux = 0.1 * GSL_MAX( 1.0, st->xsupn );
00888         }
00889         
00890         st->cg_delta = GSL_MAX( P->delmin, aux );
00891         
00892       } else {
00893         st->cg_delta = GSL_MAX( P->delmin, P->udelta0 );
00894       }
00895 
00896       /* Export size */
00897       M->size = st->gpsupn;
00898 
00899       return OOL_SUCCESS;
00900     }
00901 
00902 #endif
00903 
00904     /// Restart the minimizer
00905     virtual int restart() {
00906 
00907       /*
00908       // Restarting dx 
00909       gsl_vector_set_zero( M->dx );
00910       
00911       return prepare_iteration( M );
00912       */
00913 
00914       return 0;
00915     }
00916 
00917     /// Perform an iteration
00918     virtual int iterate() {
00919 
00920 #ifdef NEVER_DEFINED
00921 
00922       int status;
00923 
00924       status = actual_iterate( M, st, P );
00925 
00926       /* Export size and dx variables */
00927       M->size = st->gpsupn;
00928 
00929       /* In the next version does dx replace st->S ? */
00930       gsl_vector_memcpy( M->dx, st->S );
00931 
00932       return status;
00933 
00934 #endif
00935 
00936       return 0;
00937     }
00938 
00939     /// See if we're finished
00940     virtual int is_optimal() {
00941 
00942       //return (( st->gpeucn2 <= st->epsgpen2 ||
00943       //st->gpsupn  <= P->epsgpsn   ||
00944       //M->f        <= P->fmin      )? OOL_SUCCESS : OOL_CONTINUE );
00945 
00946     }
00947 
00948     /// Return string denoting type ("ool_mmin_gencan")
00949     const char *type() { return "ool_mmin_gencan"; }
00950       
00951   };
00952   
00953 #ifndef DOXYGENP
00954 }
00955 #endif
00956 
00957 #endif
00958 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.