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