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