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