![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
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, >d ); 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
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).