1 #include <petsctaolinesearch.h> /*I "petsctaolinesearch.h" I*/ 2 #include <petsc/private/taolinesearchimpl.h> 3 4 PetscFunctionList TaoLineSearchList = NULL; 5 6 PetscClassId TAOLINESEARCH_CLASSID=0; 7 8 PetscLogEvent TAOLINESEARCH_Apply; 9 PetscLogEvent TAOLINESEARCH_Eval; 10 11 /*@C 12 TaoLineSearchViewFromOptions - View from Options 13 14 Collective on TaoLineSearch 15 16 Input Parameters: 17 + A - the Tao context 18 . obj - Optional object 19 - name - command line option 20 21 Level: intermediate 22 .seealso: TaoLineSearch, TaoLineSearchView, PetscObjectViewFromOptions(), TaoLineSearchCreate() 23 @*/ 24 PetscErrorCode TaoLineSearchViewFromOptions(TaoLineSearch A,PetscObject obj,const char name[]) 25 { 26 PetscErrorCode ierr; 27 28 PetscFunctionBegin; 29 PetscValidHeaderSpecific(A,TAOLINESEARCH_CLASSID,1); 30 ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 31 PetscFunctionReturn(0); 32 } 33 34 /*@C 35 TaoLineSearchView - Prints information about the TaoLineSearch 36 37 Collective on TaoLineSearch 38 39 InputParameters: 40 + ls - the Tao context 41 - viewer - visualization context 42 43 Options Database Key: 44 . -tao_ls_view - Calls TaoLineSearchView() at the end of each line search 45 46 Notes: 47 The available visualization contexts include 48 + PETSC_VIEWER_STDOUT_SELF - standard output (default) 49 - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 50 output where only the first processor opens 51 the file. All other processors send their 52 data to the first processor to print. 53 54 Level: beginner 55 56 .seealso: PetscViewerASCIIOpen() 57 @*/ 58 59 PetscErrorCode TaoLineSearchView(TaoLineSearch ls, PetscViewer viewer) 60 { 61 PetscErrorCode ierr; 62 PetscBool isascii, isstring; 63 TaoLineSearchType type; 64 65 PetscFunctionBegin; 66 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 67 if (!viewer) { 68 ierr = PetscViewerASCIIGetStdout(((PetscObject)ls)->comm, &viewer);CHKERRQ(ierr); 69 } 70 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 71 PetscCheckSameComm(ls,1,viewer,2); 72 73 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 74 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 75 if (isascii) { 76 ierr = PetscObjectPrintClassNamePrefixType((PetscObject)ls, viewer);CHKERRQ(ierr); 77 if (ls->ops->view) { 78 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 79 ierr = (*ls->ops->view)(ls,viewer);CHKERRQ(ierr); 80 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 81 } 82 ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 83 ierr = PetscViewerASCIIPrintf(viewer,"maximum function evaluations=%D\n",ls->max_funcs);CHKERRQ(ierr); 84 ierr = PetscViewerASCIIPrintf(viewer,"tolerances: ftol=%g, rtol=%g, gtol=%g\n",(double)ls->ftol,(double)ls->rtol,(double)ls->gtol);CHKERRQ(ierr); 85 ierr = PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D\n",ls->nfeval);CHKERRQ(ierr); 86 ierr = PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D\n",ls->ngeval);CHKERRQ(ierr); 87 ierr = PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D\n",ls->nfgeval);CHKERRQ(ierr); 88 89 if (ls->bounded) { 90 ierr = PetscViewerASCIIPrintf(viewer,"using variable bounds\n");CHKERRQ(ierr); 91 } 92 ierr = PetscViewerASCIIPrintf(viewer,"Termination reason: %d\n",(int)ls->reason);CHKERRQ(ierr); 93 ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 94 } else if (isstring) { 95 ierr = TaoLineSearchGetType(ls,&type);CHKERRQ(ierr); 96 ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr); 97 } 98 PetscFunctionReturn(0); 99 } 100 101 /*@C 102 TaoLineSearchCreate - Creates a TAO Line Search object. Algorithms in TAO that use 103 line-searches will automatically create one. 104 105 Collective 106 107 Input Parameter: 108 . comm - MPI communicator 109 110 Output Parameter: 111 . newls - the new TaoLineSearch context 112 113 Available methods include: 114 + more-thuente 115 . gpcg 116 - unit - Do not perform any line search 117 118 Options Database Keys: 119 . -tao_ls_type - select which method TAO should use 120 121 Level: beginner 122 123 .seealso: TaoLineSearchSetType(), TaoLineSearchApply(), TaoLineSearchDestroy() 124 @*/ 125 126 PetscErrorCode TaoLineSearchCreate(MPI_Comm comm, TaoLineSearch *newls) 127 { 128 PetscErrorCode ierr; 129 TaoLineSearch ls; 130 131 PetscFunctionBegin; 132 PetscValidPointer(newls,2); 133 *newls = NULL; 134 135 ierr = TaoLineSearchInitializePackage();CHKERRQ(ierr); 136 137 ierr = PetscHeaderCreate(ls,TAOLINESEARCH_CLASSID,"TaoLineSearch","Linesearch","Tao",comm,TaoLineSearchDestroy,TaoLineSearchView);CHKERRQ(ierr); 138 ls->bounded = 0; 139 ls->max_funcs=30; 140 ls->ftol = 0.0001; 141 ls->gtol = 0.9; 142 #if defined(PETSC_USE_REAL_SINGLE) 143 ls->rtol = 1.0e-5; 144 #else 145 ls->rtol = 1.0e-10; 146 #endif 147 ls->stepmin=1.0e-20; 148 ls->stepmax=1.0e+20; 149 ls->step=1.0; 150 ls->nfeval=0; 151 ls->ngeval=0; 152 ls->nfgeval=0; 153 154 ls->ops->computeobjective = NULL; 155 ls->ops->computegradient = NULL; 156 ls->ops->computeobjectiveandgradient = NULL; 157 ls->ops->computeobjectiveandgts = NULL; 158 ls->ops->setup = NULL; 159 ls->ops->apply = NULL; 160 ls->ops->view = NULL; 161 ls->ops->setfromoptions = NULL; 162 ls->ops->reset = NULL; 163 ls->ops->destroy = NULL; 164 ls->ops->monitor = NULL; 165 ls->usemonitor=PETSC_FALSE; 166 ls->setupcalled=PETSC_FALSE; 167 ls->usetaoroutines=PETSC_FALSE; 168 *newls = ls; 169 PetscFunctionReturn(0); 170 } 171 172 /*@ 173 TaoLineSearchSetUp - Sets up the internal data structures for the later use 174 of a Tao solver 175 176 Collective on ls 177 178 Input Parameters: 179 . ls - the TaoLineSearch context 180 181 Notes: 182 The user will not need to explicitly call TaoLineSearchSetUp(), as it will 183 automatically be called in TaoLineSearchSolve(). However, if the user 184 desires to call it explicitly, it should come after TaoLineSearchCreate() 185 but before TaoLineSearchApply(). 186 187 Level: developer 188 189 .seealso: TaoLineSearchCreate(), TaoLineSearchApply() 190 @*/ 191 192 PetscErrorCode TaoLineSearchSetUp(TaoLineSearch ls) 193 { 194 PetscErrorCode ierr; 195 const char *default_type=TAOLINESEARCHMT; 196 PetscBool flg; 197 198 PetscFunctionBegin; 199 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 200 if (ls->setupcalled) PetscFunctionReturn(0); 201 if (!((PetscObject)ls)->type_name) { 202 ierr = TaoLineSearchSetType(ls,default_type);CHKERRQ(ierr); 203 } 204 if (ls->ops->setup) { 205 ierr = (*ls->ops->setup)(ls);CHKERRQ(ierr); 206 } 207 if (ls->usetaoroutines) { 208 ierr = TaoIsObjectiveDefined(ls->tao,&flg);CHKERRQ(ierr); 209 ls->hasobjective = flg; 210 ierr = TaoIsGradientDefined(ls->tao,&flg);CHKERRQ(ierr); 211 ls->hasgradient = flg; 212 ierr = TaoIsObjectiveAndGradientDefined(ls->tao,&flg);CHKERRQ(ierr); 213 ls->hasobjectiveandgradient = flg; 214 } else { 215 if (ls->ops->computeobjective) { 216 ls->hasobjective = PETSC_TRUE; 217 } else { 218 ls->hasobjective = PETSC_FALSE; 219 } 220 if (ls->ops->computegradient) { 221 ls->hasgradient = PETSC_TRUE; 222 } else { 223 ls->hasgradient = PETSC_FALSE; 224 } 225 if (ls->ops->computeobjectiveandgradient) { 226 ls->hasobjectiveandgradient = PETSC_TRUE; 227 } else { 228 ls->hasobjectiveandgradient = PETSC_FALSE; 229 } 230 } 231 ls->setupcalled = PETSC_TRUE; 232 PetscFunctionReturn(0); 233 } 234 235 /*@ 236 TaoLineSearchReset - Some line searches may carry state information 237 from one TaoLineSearchApply() to the next. This function resets this 238 state information. 239 240 Collective on TaoLineSearch 241 242 Input Parameter: 243 . ls - the TaoLineSearch context 244 245 Level: developer 246 247 .seealso: TaoLineSearchCreate(), TaoLineSearchApply() 248 @*/ 249 PetscErrorCode TaoLineSearchReset(TaoLineSearch ls) 250 { 251 PetscErrorCode ierr; 252 253 PetscFunctionBegin; 254 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 255 if (ls->ops->reset) { 256 ierr = (*ls->ops->reset)(ls);CHKERRQ(ierr); 257 } 258 PetscFunctionReturn(0); 259 } 260 261 /*@ 262 TaoLineSearchDestroy - Destroys the TAO context that was created with 263 TaoLineSearchCreate() 264 265 Collective on TaoLineSearch 266 267 Input Parameter: 268 . ls - the TaoLineSearch context 269 270 Level: beginner 271 272 .seealse: TaoLineSearchCreate(), TaoLineSearchSolve() 273 @*/ 274 PetscErrorCode TaoLineSearchDestroy(TaoLineSearch *ls) 275 { 276 PetscErrorCode ierr; 277 278 PetscFunctionBegin; 279 if (!*ls) PetscFunctionReturn(0); 280 PetscValidHeaderSpecific(*ls,TAOLINESEARCH_CLASSID,1); 281 if (--((PetscObject)*ls)->refct > 0) {*ls = NULL; PetscFunctionReturn(0);} 282 ierr = VecDestroy(&(*ls)->stepdirection);CHKERRQ(ierr); 283 ierr = VecDestroy(&(*ls)->start_x);CHKERRQ(ierr); 284 if ((*ls)->ops->destroy) { 285 ierr = (*(*ls)->ops->destroy)(*ls);CHKERRQ(ierr); 286 } 287 if ((*ls)->usemonitor) { 288 ierr = PetscViewerDestroy(&(*ls)->viewer);CHKERRQ(ierr); 289 } 290 ierr = PetscHeaderDestroy(ls);CHKERRQ(ierr); 291 PetscFunctionReturn(0); 292 } 293 294 /*@ 295 TaoLineSearchApply - Performs a line-search in a given step direction. Criteria for acceptable step length depends on the line-search algorithm chosen 296 297 Collective on TaoLineSearch 298 299 Input Parameters: 300 + ls - the Tao context 301 . x - The current solution (on output x contains the new solution determined by the line search) 302 . f - objective function value at current solution (on output contains the objective function value at new solution) 303 . g - gradient evaluated at x (on output contains the gradient at new solution) 304 - s - search direction 305 306 Output Parameters: 307 + x - new solution 308 . f - objective function value at x 309 . g - gradient vector at x 310 . steplength - scalar multiplier of s used ( x = x0 + steplength * x) 311 - reason - reason why the line-search stopped 312 313 reason will be set to one of: 314 315 + TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction 316 . TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value 317 . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter 318 . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached 319 . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound 320 . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound 321 . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance 322 . TAOLINESEARCH_HALTED_USER - user can set this reason to stop line search 323 . TAOLINESEARCH_HALTED_OTHER - any other reason 324 - TAOLINESEARCH_SUCCESS - successful line search 325 326 Note: 327 The algorithm developer must set up the TaoLineSearch with calls to 328 TaoLineSearchSetObjectiveRoutine() and TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), or TaoLineSearchUseTaoRoutines() 329 330 Note: 331 You may or may not need to follow this with a call to 332 TaoAddLineSearchCounts(), depending on whether you want these 333 evaluations to count toward the total function/gradient evaluations. 334 335 Level: beginner 336 337 .seealso: TaoLineSearchCreate(), TaoLineSearchSetType(), TaoLineSearchSetInitialStepLength(), TaoAddLineSearchCounts() 338 @*/ 339 340 PetscErrorCode TaoLineSearchApply(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s, PetscReal *steplength, TaoLineSearchConvergedReason *reason) 341 { 342 PetscErrorCode ierr; 343 PetscInt low1,low2,low3,high1,high2,high3; 344 345 PetscFunctionBegin; 346 *reason = TAOLINESEARCH_CONTINUE_ITERATING; 347 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 348 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 349 PetscValidRealPointer(f,3); 350 PetscValidHeaderSpecific(g,VEC_CLASSID,4); 351 PetscValidHeaderSpecific(s,VEC_CLASSID,5); 352 PetscValidPointer(reason,7); 353 PetscCheckSameComm(ls,1,x,2); 354 PetscCheckSameTypeAndComm(x,2,g,4); 355 PetscCheckSameTypeAndComm(x,2,s,5); 356 ierr = VecGetOwnershipRange(x, &low1, &high1);CHKERRQ(ierr); 357 ierr = VecGetOwnershipRange(g, &low2, &high2);CHKERRQ(ierr); 358 ierr = VecGetOwnershipRange(s, &low3, &high3);CHKERRQ(ierr); 359 if (low1!= low2 || low1!= low3 || high1!= high2 || high1!= high3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Incompatible vector local lengths"); 360 361 ierr = PetscObjectReference((PetscObject)s);CHKERRQ(ierr); 362 ierr = VecDestroy(&ls->stepdirection);CHKERRQ(ierr); 363 ls->stepdirection = s; 364 365 ierr = TaoLineSearchSetUp(ls);CHKERRQ(ierr); 366 if (!ls->ops->apply) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search Object does not have 'apply' routine"); 367 ls->nfeval=0; 368 ls->ngeval=0; 369 ls->nfgeval=0; 370 /* Check parameter values */ 371 if (ls->ftol < 0.0) { 372 ierr = PetscInfo1(ls,"Bad Line Search Parameter: ftol (%g) < 0\n",(double)ls->ftol);CHKERRQ(ierr); 373 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 374 } 375 if (ls->rtol < 0.0) { 376 ierr = PetscInfo1(ls,"Bad Line Search Parameter: rtol (%g) < 0\n",(double)ls->rtol);CHKERRQ(ierr); 377 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 378 } 379 if (ls->gtol < 0.0) { 380 ierr = PetscInfo1(ls,"Bad Line Search Parameter: gtol (%g) < 0\n",(double)ls->gtol);CHKERRQ(ierr); 381 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 382 } 383 if (ls->stepmin < 0.0) { 384 ierr = PetscInfo1(ls,"Bad Line Search Parameter: stepmin (%g) < 0\n",(double)ls->stepmin);CHKERRQ(ierr); 385 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 386 } 387 if (ls->stepmax < ls->stepmin) { 388 ierr = PetscInfo2(ls,"Bad Line Search Parameter: stepmin (%g) > stepmax (%g)\n",(double)ls->stepmin,(double)ls->stepmax);CHKERRQ(ierr); 389 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 390 } 391 if (ls->max_funcs < 0) { 392 ierr = PetscInfo1(ls,"Bad Line Search Parameter: max_funcs (%D) < 0\n",ls->max_funcs);CHKERRQ(ierr); 393 *reason=TAOLINESEARCH_FAILED_BADPARAMETER; 394 } 395 if (PetscIsInfOrNanReal(*f)) { 396 ierr = PetscInfo1(ls,"Initial Line Search Function Value is Inf or Nan (%g)\n",(double)*f);CHKERRQ(ierr); 397 *reason=TAOLINESEARCH_FAILED_INFORNAN; 398 } 399 400 ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr); 401 ierr = VecDestroy(&ls->start_x);CHKERRQ(ierr); 402 ls->start_x = x; 403 404 ierr = PetscLogEventBegin(TAOLINESEARCH_Apply,ls,0,0,0);CHKERRQ(ierr); 405 ierr = (*ls->ops->apply)(ls,x,f,g,s);CHKERRQ(ierr); 406 ierr = PetscLogEventEnd(TAOLINESEARCH_Apply, ls, 0,0,0);CHKERRQ(ierr); 407 *reason=ls->reason; 408 ls->new_f = *f; 409 410 if (steplength) { 411 *steplength=ls->step; 412 } 413 414 ierr = TaoLineSearchViewFromOptions(ls,NULL,"-tao_ls_view");CHKERRQ(ierr); 415 PetscFunctionReturn(0); 416 } 417 418 /*@C 419 TaoLineSearchSetType - Sets the algorithm used in a line search 420 421 Collective on TaoLineSearch 422 423 Input Parameters: 424 + ls - the TaoLineSearch context 425 - type - the TaoLineSearchType selection 426 427 Available methods include: 428 + more-thuente - line search with a cubic model enforcing the strong Wolfe/curvature condition 429 . armijo - simple backtracking line search enforcing only the sufficient decrease condition 430 - unit - do not perform a line search and always accept unit step length 431 432 Options Database Keys: 433 . -tao_ls_type <more-thuente, armijo, unit> - select which method TAO should use at runtime 434 435 Level: beginner 436 437 .seealso: TaoLineSearchCreate(), TaoLineSearchGetType(), TaoLineSearchApply() 438 439 @*/ 440 441 PetscErrorCode TaoLineSearchSetType(TaoLineSearch ls, TaoLineSearchType type) 442 { 443 PetscErrorCode ierr; 444 PetscErrorCode (*r)(TaoLineSearch); 445 PetscBool flg; 446 447 PetscFunctionBegin; 448 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 449 PetscValidCharPointer(type,2); 450 ierr = PetscObjectTypeCompare((PetscObject)ls, type, &flg);CHKERRQ(ierr); 451 if (flg) PetscFunctionReturn(0); 452 453 ierr = PetscFunctionListFind(TaoLineSearchList,type, (void (**)(void)) &r);CHKERRQ(ierr); 454 if (!r) SETERRQ1(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested TaoLineSearch type %s",type); 455 if (ls->ops->destroy) { 456 ierr = (*(ls)->ops->destroy)(ls);CHKERRQ(ierr); 457 } 458 ls->max_funcs=30; 459 ls->ftol = 0.0001; 460 ls->gtol = 0.9; 461 #if defined(PETSC_USE_REAL_SINGLE) 462 ls->rtol = 1.0e-5; 463 #else 464 ls->rtol = 1.0e-10; 465 #endif 466 ls->stepmin=1.0e-20; 467 ls->stepmax=1.0e+20; 468 469 ls->nfeval=0; 470 ls->ngeval=0; 471 ls->nfgeval=0; 472 ls->ops->setup = NULL; 473 ls->ops->apply = NULL; 474 ls->ops->view = NULL; 475 ls->ops->setfromoptions = NULL; 476 ls->ops->destroy = NULL; 477 ls->setupcalled = PETSC_FALSE; 478 ierr = (*r)(ls);CHKERRQ(ierr); 479 ierr = PetscObjectChangeTypeName((PetscObject)ls, type);CHKERRQ(ierr); 480 PetscFunctionReturn(0); 481 } 482 483 /*@C 484 TaoLineSearchMonitor - Monitor the line search steps. This routine will otuput the 485 iteration number, step length, and function value before calling the implementation 486 specific monitor. 487 488 Input Parameters: 489 + ls - the TaoLineSearch context 490 . its - the current iterate number (>=0) 491 . f - the current objective function value 492 - step - the step length 493 494 Options Database Key: 495 . -tao_ls_monitor - Use the default monitor, which prints statistics to standard output 496 497 Level: developer 498 499 @*/ 500 PetscErrorCode TaoLineSearchMonitor(TaoLineSearch ls, PetscInt its, PetscReal f, PetscReal step) 501 { 502 PetscErrorCode ierr; 503 PetscInt tabs; 504 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 507 if (ls->usemonitor) { 508 ierr = PetscViewerASCIIGetTab(ls->viewer, &tabs);CHKERRQ(ierr); 509 ierr = PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel);CHKERRQ(ierr); 510 ierr = PetscViewerASCIIPrintf(ls->viewer, "%3D LS", its);CHKERRQ(ierr); 511 ierr = PetscViewerASCIIPrintf(ls->viewer, " Function value: %g,", (double)f);CHKERRQ(ierr); 512 ierr = PetscViewerASCIIPrintf(ls->viewer, " Step length: %g\n", (double)step);CHKERRQ(ierr); 513 if (ls->ops->monitor && its > 0) { 514 ierr = PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel + 3);CHKERRQ(ierr); 515 ierr = (*ls->ops->monitor)(ls);CHKERRQ(ierr); 516 } 517 ierr = PetscViewerASCIISetTab(ls->viewer, tabs);CHKERRQ(ierr); 518 } 519 PetscFunctionReturn(0); 520 } 521 522 /*@ 523 TaoLineSearchSetFromOptions - Sets various TaoLineSearch parameters from user 524 options. 525 526 Collective on TaoLineSearch 527 528 Input Paremeter: 529 . ls - the TaoLineSearch context 530 531 Options Database Keys: 532 + -tao_ls_type <type> - The algorithm that TAO uses (more-thuente, gpcg, unit) 533 . -tao_ls_ftol <tol> - tolerance for sufficient decrease 534 . -tao_ls_gtol <tol> - tolerance for curvature condition 535 . -tao_ls_rtol <tol> - relative tolerance for acceptable step 536 . -tao_ls_stepmin <step> - minimum steplength allowed 537 . -tao_ls_stepmax <step> - maximum steplength allowed 538 . -tao_ls_max_funcs <n> - maximum number of function evaluations allowed 539 - -tao_ls_view - display line-search results to standard output 540 541 Level: beginner 542 @*/ 543 PetscErrorCode TaoLineSearchSetFromOptions(TaoLineSearch ls) 544 { 545 PetscErrorCode ierr; 546 const char *default_type=TAOLINESEARCHMT; 547 char type[256],monfilename[PETSC_MAX_PATH_LEN]; 548 PetscViewer monviewer; 549 PetscBool flg; 550 551 PetscFunctionBegin; 552 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 553 ierr = PetscObjectOptionsBegin((PetscObject)ls);CHKERRQ(ierr); 554 if (((PetscObject)ls)->type_name) { 555 default_type = ((PetscObject)ls)->type_name; 556 } 557 /* Check for type from options */ 558 ierr = PetscOptionsFList("-tao_ls_type","Tao Line Search type","TaoLineSearchSetType",TaoLineSearchList,default_type,type,256,&flg);CHKERRQ(ierr); 559 if (flg) { 560 ierr = TaoLineSearchSetType(ls,type);CHKERRQ(ierr); 561 } else if (!((PetscObject)ls)->type_name) { 562 ierr = TaoLineSearchSetType(ls,default_type);CHKERRQ(ierr); 563 } 564 565 ierr = PetscOptionsInt("-tao_ls_max_funcs","max function evals in line search","",ls->max_funcs,&ls->max_funcs,NULL);CHKERRQ(ierr); 566 ierr = PetscOptionsReal("-tao_ls_ftol","tol for sufficient decrease","",ls->ftol,&ls->ftol,NULL);CHKERRQ(ierr); 567 ierr = PetscOptionsReal("-tao_ls_gtol","tol for curvature condition","",ls->gtol,&ls->gtol,NULL);CHKERRQ(ierr); 568 ierr = PetscOptionsReal("-tao_ls_rtol","relative tol for acceptable step","",ls->rtol,&ls->rtol,NULL);CHKERRQ(ierr); 569 ierr = PetscOptionsReal("-tao_ls_stepmin","lower bound for step","",ls->stepmin,&ls->stepmin,NULL);CHKERRQ(ierr); 570 ierr = PetscOptionsReal("-tao_ls_stepmax","upper bound for step","",ls->stepmax,&ls->stepmax,NULL);CHKERRQ(ierr); 571 ierr = PetscOptionsString("-tao_ls_monitor","enable the basic monitor","TaoLineSearchSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr); 572 if (flg) { 573 ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ls),monfilename,&monviewer);CHKERRQ(ierr); 574 ls->viewer = monviewer; 575 ls->usemonitor = PETSC_TRUE; 576 } 577 if (ls->ops->setfromoptions) { 578 ierr = (*ls->ops->setfromoptions)(PetscOptionsObject,ls);CHKERRQ(ierr); 579 } 580 ierr = PetscOptionsEnd();CHKERRQ(ierr); 581 PetscFunctionReturn(0); 582 } 583 584 /*@C 585 TaoLineSearchGetType - Gets the current line search algorithm 586 587 Not Collective 588 589 Input Parameter: 590 . ls - the TaoLineSearch context 591 592 Output Parameter: 593 . type - the line search algorithm in effect 594 595 Level: developer 596 597 @*/ 598 PetscErrorCode TaoLineSearchGetType(TaoLineSearch ls, TaoLineSearchType *type) 599 { 600 PetscFunctionBegin; 601 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 602 PetscValidPointer(type,2); 603 *type = ((PetscObject)ls)->type_name; 604 PetscFunctionReturn(0); 605 } 606 607 /*@ 608 TaoLineSearchGetNumberFunctionEvaluations - Gets the number of function and gradient evaluation 609 routines used by the line search in last application (not cumulative). 610 611 Not Collective 612 613 Input Parameter: 614 . ls - the TaoLineSearch context 615 616 Output Parameters: 617 + nfeval - number of function evaluations 618 . ngeval - number of gradient evaluations 619 - nfgeval - number of function/gradient evaluations 620 621 Level: intermediate 622 623 Note: 624 If the line search is using the Tao objective and gradient 625 routines directly (see TaoLineSearchUseTaoRoutines()), then TAO 626 is already counting the number of evaluations. 627 628 @*/ 629 PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval) 630 { 631 PetscFunctionBegin; 632 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 633 *nfeval = ls->nfeval; 634 *ngeval = ls->ngeval; 635 *nfgeval = ls->nfgeval; 636 PetscFunctionReturn(0); 637 } 638 639 /*@ 640 TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using 641 Tao evaluation routines. 642 643 Not Collective 644 645 Input Parameter: 646 . ls - the TaoLineSearch context 647 648 Output Parameter: 649 . flg - PETSC_TRUE if the line search is using Tao evaluation routines, 650 otherwise PETSC_FALSE 651 652 Level: developer 653 @*/ 654 PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg) 655 { 656 PetscFunctionBegin; 657 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 658 *flg = ls->usetaoroutines; 659 PetscFunctionReturn(0); 660 } 661 662 /*@C 663 TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search 664 665 Logically Collective on TaoLineSearch 666 667 Input Parameter: 668 + ls - the TaoLineSearch context 669 . func - the objective function evaluation routine 670 - ctx - the (optional) user-defined context for private data 671 672 Calling sequence of func: 673 $ func (TaoLinesearch ls, Vec x, PetscReal *f, void *ctx); 674 675 + x - input vector 676 . f - function value 677 - ctx (optional) user-defined context 678 679 Level: beginner 680 681 Note: 682 Use this routine only if you want the line search objective 683 evaluation routine to be different from the Tao's objective 684 evaluation routine. If you use this routine you must also set 685 the line search gradient and/or function/gradient routine. 686 687 Note: 688 Some algorithms (lcl, gpcg) set their own objective routine for the 689 line search, application programmers should be wary of overriding the 690 default objective routine. 691 692 .seealso: TaoLineSearchCreate(), TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines() 693 @*/ 694 PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal*, void*), void *ctx) 695 { 696 PetscFunctionBegin; 697 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 698 699 ls->ops->computeobjective=func; 700 if (ctx) ls->userctx_func=ctx; 701 ls->usetaoroutines=PETSC_FALSE; 702 PetscFunctionReturn(0); 703 } 704 705 /*@C 706 TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search 707 708 Logically Collective on TaoLineSearch 709 710 Input Parameter: 711 + ls - the TaoLineSearch context 712 . func - the gradient evaluation routine 713 - ctx - the (optional) user-defined context for private data 714 715 Calling sequence of func: 716 $ func (TaoLinesearch ls, Vec x, Vec g, void *ctx); 717 718 + x - input vector 719 . g - gradient vector 720 - ctx (optional) user-defined context 721 722 Level: beginner 723 724 Note: 725 Use this routine only if you want the line search gradient 726 evaluation routine to be different from the Tao's gradient 727 evaluation routine. If you use this routine you must also set 728 the line search function and/or function/gradient routine. 729 730 Note: 731 Some algorithms (lcl, gpcg) set their own gradient routine for the 732 line search, application programmers should be wary of overriding the 733 default gradient routine. 734 735 .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines() 736 @*/ 737 PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec g, void*), void *ctx) 738 { 739 PetscFunctionBegin; 740 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 741 ls->ops->computegradient=func; 742 if (ctx) ls->userctx_grad=ctx; 743 ls->usetaoroutines=PETSC_FALSE; 744 PetscFunctionReturn(0); 745 } 746 747 /*@C 748 TaoLineSearchSetObjectiveAndGradientRoutine - Sets the objective/gradient evaluation routine for the line search 749 750 Logically Collective on TaoLineSearch 751 752 Input Parameter: 753 + ls - the TaoLineSearch context 754 . func - the objective and gradient evaluation routine 755 - ctx - the (optional) user-defined context for private data 756 757 Calling sequence of func: 758 $ func (TaoLinesearch ls, Vec x, PetscReal *f, Vec g, void *ctx); 759 760 + x - input vector 761 . f - function value 762 . g - gradient vector 763 - ctx (optional) user-defined context 764 765 Level: beginner 766 767 Note: 768 Use this routine only if you want the line search objective and gradient 769 evaluation routines to be different from the Tao's objective 770 and gradient evaluation routines. 771 772 Note: 773 Some algorithms (lcl, gpcg) set their own objective routine for the 774 line search, application programmers should be wary of overriding the 775 default objective routine. 776 777 .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetGradientRoutine(), TaoLineSearchUseTaoRoutines() 778 @*/ 779 PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal *, Vec g, void*), void *ctx) 780 { 781 PetscFunctionBegin; 782 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 783 ls->ops->computeobjectiveandgradient=func; 784 if (ctx) ls->userctx_funcgrad=ctx; 785 ls->usetaoroutines = PETSC_FALSE; 786 PetscFunctionReturn(0); 787 } 788 789 /*@C 790 TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and 791 (gradient'*stepdirection) evaluation routine for the line search. 792 Sometimes it is more efficient to compute the inner product of the gradient 793 and the step direction than it is to compute the gradient, and this is all 794 the line search typically needs of the gradient. 795 796 Logically Collective on TaoLineSearch 797 798 Input Parameter: 799 + ls - the TaoLineSearch context 800 . func - the objective and gradient evaluation routine 801 - ctx - the (optional) user-defined context for private data 802 803 Calling sequence of func: 804 $ func (TaoLinesearch ls, Vec x, PetscReal *f, PetscReal *gts, void *ctx); 805 806 + x - input vector 807 . s - step direction 808 . f - function value 809 . gts - inner product of gradient and step direction vectors 810 - ctx (optional) user-defined context 811 812 Note: The gradient will still need to be computed at the end of the line 813 search, so you will still need to set a line search gradient evaluation 814 routine 815 816 Note: Bounded line searches (those used in bounded optimization algorithms) 817 don't use g's directly, but rather (g'x - g'x0)/steplength. You can get the 818 x0 and steplength with TaoLineSearchGetStartingVector() and TaoLineSearchGetStepLength() 819 820 Level: advanced 821 822 Note: 823 Some algorithms (lcl, gpcg) set their own objective routine for the 824 line search, application programmers should be wary of overriding the 825 default objective routine. 826 827 .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjective(), TaoLineSearchSetGradient(), TaoLineSearchUseTaoRoutines() 828 @*/ 829 PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *, PetscReal *, void*), void *ctx) 830 { 831 PetscFunctionBegin; 832 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 833 ls->ops->computeobjectiveandgts=func; 834 if (ctx) ls->userctx_funcgts=ctx; 835 ls->usegts = PETSC_TRUE; 836 ls->usetaoroutines=PETSC_FALSE; 837 PetscFunctionReturn(0); 838 } 839 840 /*@C 841 TaoLineSearchUseTaoRoutines - Informs the TaoLineSearch to use the 842 objective and gradient evaluation routines from the given Tao object. 843 844 Logically Collective on TaoLineSearch 845 846 Input Parameter: 847 + ls - the TaoLineSearch context 848 - ts - the Tao context with defined objective/gradient evaluation routines 849 850 Level: developer 851 852 .seealso: TaoLineSearchCreate() 853 @*/ 854 PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts) 855 { 856 PetscFunctionBegin; 857 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 858 PetscValidHeaderSpecific(ts,TAO_CLASSID,2); 859 ls->tao = ts; 860 ls->usetaoroutines=PETSC_TRUE; 861 PetscFunctionReturn(0); 862 } 863 864 /*@ 865 TaoLineSearchComputeObjective - Computes the objective function value at a given point 866 867 Collective on TaoLineSearch 868 869 Input Parameters: 870 + ls - the TaoLineSearch context 871 - x - input vector 872 873 Output Parameter: 874 . f - Objective value at X 875 876 Notes: 877 TaoLineSearchComputeObjective() is typically used within line searches 878 so most users would not generally call this routine themselves. 879 880 Level: developer 881 882 .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine() 883 @*/ 884 PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f) 885 { 886 PetscErrorCode ierr; 887 Vec gdummy; 888 PetscReal gts; 889 890 PetscFunctionBegin; 891 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 892 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 893 PetscValidPointer(f,3); 894 PetscCheckSameComm(ls,1,x,2); 895 if (ls->usetaoroutines) { 896 ierr = TaoComputeObjective(ls->tao,x,f);CHKERRQ(ierr); 897 } else { 898 if (!ls->ops->computeobjective && !ls->ops->computeobjectiveandgradient && !ls->ops->computeobjectiveandgts) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective function set"); 899 ierr = PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 900 PetscStackPush("TaoLineSearch user objective routine"); 901 if (ls->ops->computeobjective) { 902 ierr = (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);CHKERRQ(ierr); 903 } else if (ls->ops->computeobjectiveandgradient) { 904 ierr = VecDuplicate(x,&gdummy);CHKERRQ(ierr); 905 ierr = (*ls->ops->computeobjectiveandgradient)(ls,x,f,gdummy,ls->userctx_funcgrad);CHKERRQ(ierr); 906 ierr = VecDestroy(&gdummy);CHKERRQ(ierr); 907 } else { 908 ierr = (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,>s,ls->userctx_funcgts);CHKERRQ(ierr); 909 } 910 PetscStackPop; 911 ierr = PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 912 } 913 ls->nfeval++; 914 PetscFunctionReturn(0); 915 } 916 917 /*@ 918 TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point 919 920 Collective on Tao 921 922 Input Parameters: 923 + ls - the TaoLineSearch context 924 - x - input vector 925 926 Output Parameter: 927 + f - Objective value at X 928 - g - Gradient vector at X 929 930 Notes: 931 TaoLineSearchComputeObjectiveAndGradient() is typically used within line searches 932 so most users would not generally call this routine themselves. 933 934 Level: developer 935 936 .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine() 937 @*/ 938 PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g) 939 { 940 PetscErrorCode ierr; 941 942 PetscFunctionBegin; 943 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 944 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 945 PetscValidPointer(f,3); 946 PetscValidHeaderSpecific(g,VEC_CLASSID,4); 947 PetscCheckSameComm(ls,1,x,2); 948 PetscCheckSameComm(ls,1,g,4); 949 if (ls->usetaoroutines) { 950 ierr = TaoComputeObjectiveAndGradient(ls->tao,x,f,g);CHKERRQ(ierr); 951 } else { 952 if (!ls->ops->computeobjective && !ls->ops->computeobjectiveandgradient) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective function set"); 953 if (!ls->ops->computegradient && !ls->ops->computeobjectiveandgradient) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have gradient function set"); 954 ierr = PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 955 if (ls->ops->computeobjectiveandgradient) { 956 PetscStackPush("TaoLineSearch user objective/gradient routine"); 957 ierr = (*ls->ops->computeobjectiveandgradient)(ls,x,f,g,ls->userctx_funcgrad);CHKERRQ(ierr); 958 PetscStackPop; 959 } else { 960 PetscStackPush("TaoLineSearch user objective routine"); 961 ierr = (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);CHKERRQ(ierr); 962 PetscStackPop; 963 PetscStackPush("TaoLineSearch user gradient routine"); 964 ierr = (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);CHKERRQ(ierr); 965 PetscStackPop; 966 } 967 ierr = PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 968 ierr = PetscInfo1(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));CHKERRQ(ierr); 969 } 970 ls->nfgeval++; 971 PetscFunctionReturn(0); 972 } 973 974 /*@ 975 TaoLineSearchComputeGradient - Computes the gradient of the objective function 976 977 Collective on TaoLineSearch 978 979 Input Parameters: 980 + ls - the TaoLineSearch context 981 - x - input vector 982 983 Output Parameter: 984 . g - gradient vector 985 986 Notes: 987 TaoComputeGradient() is typically used within line searches 988 so most users would not generally call this routine themselves. 989 990 Level: developer 991 992 .seealso: TaoLineSearchComputeObjective(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetGradient() 993 @*/ 994 PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g) 995 { 996 PetscErrorCode ierr; 997 PetscReal fdummy; 998 999 PetscFunctionBegin; 1000 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1001 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1002 PetscValidHeaderSpecific(g,VEC_CLASSID,3); 1003 PetscCheckSameComm(ls,1,x,2); 1004 PetscCheckSameComm(ls,1,g,3); 1005 if (ls->usetaoroutines) { 1006 ierr = TaoComputeGradient(ls->tao,x,g);CHKERRQ(ierr); 1007 } else { 1008 if (!ls->ops->computegradient && !ls->ops->computeobjectiveandgradient) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have gradient functions set"); 1009 ierr = PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 1010 PetscStackPush("TaoLineSearch user gradient routine"); 1011 if (ls->ops->computegradient) { 1012 ierr = (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);CHKERRQ(ierr); 1013 } else { 1014 ierr = (*ls->ops->computeobjectiveandgradient)(ls,x,&fdummy,g,ls->userctx_funcgrad);CHKERRQ(ierr); 1015 } 1016 PetscStackPop; 1017 ierr = PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 1018 } 1019 ls->ngeval++; 1020 PetscFunctionReturn(0); 1021 } 1022 1023 /*@ 1024 TaoLineSearchComputeObjectiveAndGTS - Computes the objective function value and inner product of gradient and step direction at a given point 1025 1026 Collective on Tao 1027 1028 Input Parameters: 1029 + ls - the TaoLineSearch context 1030 - x - input vector 1031 1032 Output Parameter: 1033 + f - Objective value at X 1034 - gts - inner product of gradient and step direction at X 1035 1036 Notes: 1037 TaoLineSearchComputeObjectiveAndGTS() is typically used within line searches 1038 so most users would not generally call this routine themselves. 1039 1040 Level: developer 1041 1042 .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine() 1043 @*/ 1044 PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts) 1045 { 1046 PetscErrorCode ierr; 1047 PetscFunctionBegin; 1048 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1049 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1050 PetscValidPointer(f,3); 1051 PetscValidPointer(gts,4); 1052 PetscCheckSameComm(ls,1,x,2); 1053 if (!ls->ops->computeobjectiveandgts) SETERRQ(PetscObjectComm((PetscObject)ls),PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective and gts function set"); 1054 ierr = PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 1055 PetscStackPush("TaoLineSearch user objective/gts routine"); 1056 ierr = (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,gts,ls->userctx_funcgts);CHKERRQ(ierr); 1057 PetscStackPop; 1058 ierr = PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);CHKERRQ(ierr); 1059 ierr = PetscInfo1(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));CHKERRQ(ierr); 1060 ls->nfeval++; 1061 PetscFunctionReturn(0); 1062 } 1063 1064 /*@ 1065 TaoLineSearchGetSolution - Returns the solution to the line search 1066 1067 Collective on TaoLineSearch 1068 1069 Input Parameter: 1070 . ls - the TaoLineSearch context 1071 1072 Output Parameter: 1073 + x - the new solution 1074 . f - the objective function value at x 1075 . g - the gradient at x 1076 . steplength - the multiple of the step direction taken by the line search 1077 - reason - the reason why the line search terminated 1078 1079 reason will be set to one of: 1080 1081 + TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value 1082 . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter 1083 . TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction 1084 . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached 1085 . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound 1086 . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound 1087 . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance 1088 1089 . TAOLINESEARCH_HALTED_USER - user can set this reason to stop line search 1090 . TAOLINESEARCH_HALTED_OTHER - any other reason 1091 1092 - TAOLINESEARCH_SUCCESS - successful line search 1093 1094 Level: developer 1095 1096 @*/ 1097 PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchConvergedReason *reason) 1098 { 1099 PetscErrorCode ierr; 1100 1101 PetscFunctionBegin; 1102 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1103 PetscValidHeaderSpecific(x,VEC_CLASSID,2); 1104 PetscValidPointer(f,3); 1105 PetscValidHeaderSpecific(g,VEC_CLASSID,4); 1106 PetscValidIntPointer(reason,6); 1107 if (ls->new_x) { 1108 ierr = VecCopy(ls->new_x,x);CHKERRQ(ierr); 1109 } 1110 *f = ls->new_f; 1111 if (ls->new_g) { 1112 ierr = VecCopy(ls->new_g,g);CHKERRQ(ierr); 1113 } 1114 if (steplength) { 1115 *steplength=ls->step; 1116 } 1117 *reason = ls->reason; 1118 PetscFunctionReturn(0); 1119 } 1120 1121 /*@ 1122 TaoLineSearchGetStartingVector - Gets a the initial point of the line 1123 search. 1124 1125 Not Collective 1126 1127 Input Parameter: 1128 . ls - the TaoLineSearch context 1129 1130 Output Parameter: 1131 . x - The initial point of the line search 1132 1133 Level: intermediate 1134 @*/ 1135 PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x) 1136 { 1137 PetscFunctionBegin; 1138 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1139 if (x) { 1140 *x = ls->start_x; 1141 } 1142 PetscFunctionReturn(0); 1143 } 1144 1145 /*@ 1146 TaoLineSearchGetStepDirection - Gets the step direction of the line 1147 search. 1148 1149 Not Collective 1150 1151 Input Parameter: 1152 . ls - the TaoLineSearch context 1153 1154 Output Parameter: 1155 . s - the step direction of the line search 1156 1157 Level: advanced 1158 @*/ 1159 PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s) 1160 { 1161 PetscFunctionBegin; 1162 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1163 if (s) { 1164 *s = ls->stepdirection; 1165 } 1166 PetscFunctionReturn(0); 1167 1168 } 1169 1170 /*@ 1171 TaoLineSearchGetFullStepObjective - Returns the objective function value at the full step. Useful for some minimization algorithms. 1172 1173 Not Collective 1174 1175 Input Parameter: 1176 . ls - the TaoLineSearch context 1177 1178 Output Parameter: 1179 . f - the objective value at the full step length 1180 1181 Level: developer 1182 @*/ 1183 1184 PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep) 1185 { 1186 PetscFunctionBegin; 1187 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1188 *f_fullstep = ls->f_fullstep; 1189 PetscFunctionReturn(0); 1190 } 1191 1192 /*@ 1193 TaoLineSearchSetVariableBounds - Sets the upper and lower bounds. 1194 1195 Logically Collective on Tao 1196 1197 Input Parameters: 1198 + ls - the TaoLineSearch context 1199 . xl - vector of lower bounds 1200 - xu - vector of upper bounds 1201 1202 Note: If the variable bounds are not set with this routine, then 1203 PETSC_NINFINITY and PETSC_INFINITY are assumed 1204 1205 Level: beginner 1206 1207 .seealso: TaoSetVariableBounds(), TaoLineSearchCreate() 1208 @*/ 1209 PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls,Vec xl, Vec xu) 1210 { 1211 PetscFunctionBegin; 1212 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1213 PetscValidHeaderSpecific(xl,VEC_CLASSID,2); 1214 PetscValidHeaderSpecific(xu,VEC_CLASSID,3); 1215 ls->lower = xl; 1216 ls->upper = xu; 1217 ls->bounded = 1; 1218 PetscFunctionReturn(0); 1219 } 1220 1221 /*@ 1222 TaoLineSearchSetInitialStepLength - Sets the initial step length of a line 1223 search. If this value is not set then 1.0 is assumed. 1224 1225 Logically Collective on TaoLineSearch 1226 1227 Input Parameters: 1228 + ls - the TaoLineSearch context 1229 - s - the initial step size 1230 1231 Level: intermediate 1232 1233 .seealso: TaoLineSearchGetStepLength(), TaoLineSearchApply() 1234 @*/ 1235 PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls,PetscReal s) 1236 { 1237 PetscFunctionBegin; 1238 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1239 ls->initstep = s; 1240 PetscFunctionReturn(0); 1241 } 1242 1243 /*@ 1244 TaoLineSearchGetStepLength - Get the current step length 1245 1246 Not Collective 1247 1248 Input Parameters: 1249 . ls - the TaoLineSearch context 1250 1251 Output Parameters: 1252 . s - the current step length 1253 1254 Level: beginner 1255 1256 .seealso: TaoLineSearchSetInitialStepLength(), TaoLineSearchApply() 1257 @*/ 1258 PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls,PetscReal *s) 1259 { 1260 PetscFunctionBegin; 1261 PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); 1262 *s = ls->step; 1263 PetscFunctionReturn(0); 1264 } 1265 1266 /*@C 1267 TaoLineSearchRegister - Adds a line-search algorithm to the registry 1268 1269 Not collective 1270 1271 Input Parameters: 1272 + sname - name of a new user-defined solver 1273 - func - routine to Create method context 1274 1275 Notes: 1276 TaoLineSearchRegister() may be called multiple times to add several user-defined solvers. 1277 1278 Sample usage: 1279 .vb 1280 TaoLineSearchRegister("my_linesearch",MyLinesearchCreate); 1281 .ve 1282 1283 Then, your solver can be chosen with the procedural interface via 1284 $ TaoLineSearchSetType(ls,"my_linesearch") 1285 or at runtime via the option 1286 $ -tao_ls_type my_linesearch 1287 1288 Level: developer 1289 1290 @*/ 1291 PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch)) 1292 { 1293 PetscErrorCode ierr; 1294 PetscFunctionBegin; 1295 ierr = TaoLineSearchInitializePackage();CHKERRQ(ierr); 1296 ierr = PetscFunctionListAdd(&TaoLineSearchList, sname, (void (*)(void))func);CHKERRQ(ierr); 1297 PetscFunctionReturn(0); 1298 } 1299 1300 /*@C 1301 TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching 1302 for all TaoLineSearch options in the database. 1303 1304 Collective on TaoLineSearch 1305 1306 Input Parameters: 1307 + ls - the TaoLineSearch solver context 1308 - prefix - the prefix string to prepend to all line search requests 1309 1310 Notes: 1311 A hyphen (-) must NOT be given at the beginning of the prefix name. 1312 The first character of all runtime options is AUTOMATICALLY the hyphen. 1313 1314 Level: advanced 1315 1316 .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchGetOptionsPrefix() 1317 @*/ 1318 PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[]) 1319 { 1320 return PetscObjectAppendOptionsPrefix((PetscObject)ls,p); 1321 } 1322 1323 /*@C 1324 TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all 1325 TaoLineSearch options in the database 1326 1327 Not Collective 1328 1329 Input Parameters: 1330 . ls - the TaoLineSearch context 1331 1332 Output Parameters: 1333 . prefix - pointer to the prefix string used is returned 1334 1335 Notes: 1336 On the fortran side, the user should pass in a string 'prefix' of 1337 sufficient length to hold the prefix. 1338 1339 Level: advanced 1340 1341 .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchAppendOptionsPrefix() 1342 @*/ 1343 PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[]) 1344 { 1345 return PetscObjectGetOptionsPrefix((PetscObject)ls,p); 1346 } 1347 1348 /*@C 1349 TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all 1350 TaoLineSearch options in the database. 1351 1352 Logically Collective on TaoLineSearch 1353 1354 Input Parameters: 1355 + ls - the TaoLineSearch context 1356 - prefix - the prefix string to prepend to all TAO option requests 1357 1358 Notes: 1359 A hyphen (-) must NOT be given at the beginning of the prefix name. 1360 The first character of all runtime options is AUTOMATICALLY the hyphen. 1361 1362 For example, to distinguish between the runtime options for two 1363 different line searches, one could call 1364 .vb 1365 TaoLineSearchSetOptionsPrefix(ls1,"sys1_") 1366 TaoLineSearchSetOptionsPrefix(ls2,"sys2_") 1367 .ve 1368 1369 This would enable use of different options for each system, such as 1370 .vb 1371 -sys1_tao_ls_type mt 1372 -sys2_tao_ls_type armijo 1373 .ve 1374 1375 Level: advanced 1376 1377 .seealso: TaoLineSearchAppendOptionsPrefix(), TaoLineSearchGetOptionsPrefix() 1378 @*/ 1379 1380 PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[]) 1381 { 1382 return PetscObjectSetOptionsPrefix((PetscObject)ls,p); 1383 } 1384