Actual source code: taolinesearch.c

  1: #include <petsctaolinesearch.h>
  2: #include <petsc/private/taolinesearchimpl.h>

  4: PetscFunctionList TaoLineSearchList = NULL;

  6: PetscClassId TAOLINESEARCH_CLASSID = 0;

  8: PetscLogEvent TAOLINESEARCH_Apply;
  9: PetscLogEvent TAOLINESEARCH_Eval;

 11: const char *const TaoLineSearchConvergedReasons_Shifted[] = {"FAILED_ASCENT", "FAILED_BADPARAMETER", "FAILED_INFORNAN", "CONTINUE_ITERATING", "SUCCESS", "SUCCESS_USER", "HALTED_OTHER", "HALTED_MAXFCN", "HALTED_UPPERBOUND", "HALTED_LOWERBOUND", "HALTED_RTOL", "HALTED_USER", "TaoLineSearchConvergedReason", "TAOLINESEARCH_", NULL};
 12: const char *const *TaoLineSearchConvergedReasons = TaoLineSearchConvergedReasons_Shifted + 3;

 14: /*@
 15:   TaoLineSearchViewFromOptions - View a `TaoLineSearch` object based on values in the options database

 17:   Collective

 19:   Input Parameters:
 20: + A    - the `Tao` context
 21: . obj  - Optional object
 22: - name - command line option

 24:   Options Database Key:
 25: . -name [viewertype][:...] - option name and values. See `PetscObjectViewFromOptions()` for the possible arguments

 27:   Level: intermediate

 29: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchView()`, `PetscObjectViewFromOptions()`, `TaoLineSearchCreate()`
 30: @*/
 31: PetscErrorCode TaoLineSearchViewFromOptions(TaoLineSearch A, PetscObject obj, const char name[])
 32: {
 33:   PetscFunctionBegin;
 35:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
 36:   PetscFunctionReturn(PETSC_SUCCESS);
 37: }

 39: /*@
 40:   TaoLineSearchView - Prints information about the `TaoLineSearch`

 42:   Collective

 44:   Input Parameters:
 45: + ls     - the `TaoLineSearch` context
 46: - viewer - visualization context

 48:   Options Database Key:
 49: . -tao_ls_view - Calls `TaoLineSearchView()` at the end of each line search

 51:   Level: beginner

 53:   Notes:
 54:   The available visualization contexts include
 55: +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
 56: -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
 57:   output where only the first processor opens
 58:   the file.  All other processors send their
 59:   data to the first processor to print.

 61: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `PetscViewerASCIIOpen()`, `TaoLineSearchViewFromOptions()`
 62: @*/
 63: PetscErrorCode TaoLineSearchView(TaoLineSearch ls, PetscViewer viewer)
 64: {
 65:   PetscBool         isascii, isstring;
 66:   TaoLineSearchType type;

 68:   PetscFunctionBegin;
 70:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(((PetscObject)ls)->comm, &viewer));
 72:   PetscCheckSameComm(ls, 1, viewer, 2);

 74:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
 75:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
 76:   if (isascii) {
 77:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ls, viewer));
 78:     PetscCall(PetscViewerASCIIPushTab(viewer));
 79:     PetscTryTypeMethod(ls, view, viewer);
 80:     PetscCall(PetscViewerASCIIPopTab(viewer));
 81:     PetscCall(PetscViewerASCIIPushTab(viewer));
 82:     PetscCall(PetscViewerASCIIPrintf(viewer, "maximum function evaluations=%" PetscInt_FMT "\n", ls->max_funcs));
 83:     PetscCall(PetscViewerASCIIPrintf(viewer, "tolerances: ftol=%g, rtol=%g, gtol=%g\n", (double)ls->ftol, (double)ls->rtol, (double)ls->gtol));
 84:     PetscCall(PetscViewerASCIIPrintf(viewer, "total number of function evaluations=%" PetscInt_FMT "\n", ls->nfeval));
 85:     PetscCall(PetscViewerASCIIPrintf(viewer, "total number of gradient evaluations=%" PetscInt_FMT "\n", ls->ngeval));
 86:     PetscCall(PetscViewerASCIIPrintf(viewer, "total number of function/gradient evaluations=%" PetscInt_FMT "\n", ls->nfgeval));

 88:     if (ls->bounded) PetscCall(PetscViewerASCIIPrintf(viewer, "using variable bounds\n"));
 89:     PetscCall(PetscViewerASCIIPrintf(viewer, "Termination reason: %s\n", TaoLineSearchConvergedReasons[ls->reason]));
 90:     PetscCall(PetscViewerASCIIPopTab(viewer));
 91:   } else if (isstring) {
 92:     PetscCall(TaoLineSearchGetType(ls, &type));
 93:     PetscCall(PetscViewerStringSPrintf(viewer, " %-3.3s", type));
 94:   }
 95:   PetscFunctionReturn(PETSC_SUCCESS);
 96: }

 98: /*@
 99:   TaoLineSearchCreate - Creates a `TaoLineSearch` object.  Algorithms in `Tao` that use
100:   line-searches will automatically create one so this all is rarely needed

102:   Collective

104:   Input Parameter:
105: . comm - MPI communicator

107:   Output Parameter:
108: . newls - the new `TaoLineSearch` context

110:   Options Database Key:
111: . -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use

113:   Level: developer

115: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchType`, `TaoLineSearchSetType()`, `TaoLineSearchApply()`, `TaoLineSearchDestroy()`
116: @*/
117: PetscErrorCode TaoLineSearchCreate(MPI_Comm comm, TaoLineSearch *newls)
118: {
119:   TaoLineSearch ls;

121:   PetscFunctionBegin;
122:   PetscAssertPointer(newls, 2);
123:   PetscCall(TaoLineSearchInitializePackage());

125:   PetscCall(PetscHeaderCreate(ls, TAOLINESEARCH_CLASSID, "TaoLineSearch", "Linesearch", "Tao", comm, TaoLineSearchDestroy, TaoLineSearchView));
126:   ls->max_funcs = 30;
127:   ls->ftol      = 0.0001;
128:   ls->gtol      = 0.9;
129:   ls->rtol      = PetscDefined(USE_REAL_SINGLE) ? 1.0e-5 : 1.0e-10;
130:   ls->stepmin   = 1.0e-20;
131:   ls->stepmax   = 1.0e+20;
132:   ls->step      = 1.0;
133:   ls->initstep  = 1.0;
134:   *newls        = ls;
135:   PetscFunctionReturn(PETSC_SUCCESS);
136: }

138: /*@
139:   TaoLineSearchSetUp - Sets up the internal data structures for the later use
140:   of a `TaoLineSearch`

142:   Collective

144:   Input Parameter:
145: . ls - the `TaoLineSearch` context

147:   Level: developer

149:   Note:
150:   The user will not need to explicitly call `TaoLineSearchSetUp()`, as it will
151:   automatically be called in `TaoLineSearchSolve()`.  However, if the user
152:   desires to call it explicitly, it should come after `TaoLineSearchCreate()`
153:   but before `TaoLineSearchApply()`.

155: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApply()`
156: @*/
157: PetscErrorCode TaoLineSearchSetUp(TaoLineSearch ls)
158: {
159:   const char *default_type = TAOLINESEARCHMT;
160:   PetscBool   flg;

162:   PetscFunctionBegin;
164:   if (ls->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
165:   if (!((PetscObject)ls)->type_name) PetscCall(TaoLineSearchSetType(ls, default_type));
166:   PetscTryTypeMethod(ls, setup);
167:   if (ls->usetaoroutines) {
168:     PetscCall(TaoIsObjectiveDefined(ls->tao, &flg));
169:     ls->hasobjective = flg;
170:     PetscCall(TaoIsGradientDefined(ls->tao, &flg));
171:     ls->hasgradient = flg;
172:     PetscCall(TaoIsObjectiveAndGradientDefined(ls->tao, &flg));
173:     ls->hasobjectiveandgradient = flg;
174:   } else {
175:     if (ls->ops->computeobjective) {
176:       ls->hasobjective = PETSC_TRUE;
177:     } else {
178:       ls->hasobjective = PETSC_FALSE;
179:     }
180:     if (ls->ops->computegradient) {
181:       ls->hasgradient = PETSC_TRUE;
182:     } else {
183:       ls->hasgradient = PETSC_FALSE;
184:     }
185:     if (ls->ops->computeobjectiveandgradient) {
186:       ls->hasobjectiveandgradient = PETSC_TRUE;
187:     } else {
188:       ls->hasobjectiveandgradient = PETSC_FALSE;
189:     }
190:   }
191:   ls->setupcalled = PETSC_TRUE;
192:   PetscFunctionReturn(PETSC_SUCCESS);
193: }

195: /*@
196:   TaoLineSearchReset - Some line searches may carry state information
197:   from one `TaoLineSearchApply()` to the next.  This function resets this
198:   state information.

200:   Collective

202:   Input Parameter:
203: . ls - the `TaoLineSearch` context

205:   Level: developer

207: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApply()`
208: @*/
209: PetscErrorCode TaoLineSearchReset(TaoLineSearch ls)
210: {
211:   PetscFunctionBegin;
213:   PetscTryTypeMethod(ls, reset);
214:   PetscFunctionReturn(PETSC_SUCCESS);
215: }

217: /*@
218:   TaoLineSearchDestroy - Destroys the `TaoLineSearch` context that was created with
219:   `TaoLineSearchCreate()`

221:   Collective

223:   Input Parameter:
224: . ls - the `TaoLineSearch` context

226:   Level: developer

228: .seealso: `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApple()`
229: @*/
230: PetscErrorCode TaoLineSearchDestroy(TaoLineSearch *ls)
231: {
232:   PetscFunctionBegin;
233:   if (!*ls) PetscFunctionReturn(PETSC_SUCCESS);
235:   if (--((PetscObject)*ls)->refct > 0) {
236:     *ls = NULL;
237:     PetscFunctionReturn(PETSC_SUCCESS);
238:   }
239:   PetscCall(VecDestroy(&(*ls)->stepdirection));
240:   PetscCall(VecDestroy(&(*ls)->start_x));
241:   PetscCall(VecDestroy(&(*ls)->upper));
242:   PetscCall(VecDestroy(&(*ls)->lower));
243:   PetscTryTypeMethod(*ls, destroy);
244:   if ((*ls)->usemonitor) PetscCall(PetscViewerDestroy(&(*ls)->viewer));
245:   PetscCall(PetscHeaderDestroy(ls));
246:   PetscFunctionReturn(PETSC_SUCCESS);
247: }

249: /*@
250:   TaoLineSearchApply - Performs a line-search in a given step direction.
251:   Criteria for acceptable step length depends on the line-search algorithm chosen

253:   Collective

255:   Input Parameters:
256: + ls - the `TaoLineSearch` context
257: - s  - search direction

259:   Output Parameters:
260: + x          - On input the current solution, on output `x` contains the new solution determined by the line search
261: . f          - On input the objective function value at current solution, on output contains the objective function value at new solution
262: . g          - On input the gradient evaluated at `x`, on output contains the gradient at new solution
263: . steplength - scalar multiplier of `s` used ( $x = x_0 + steplength * x)
264: - reason     - `TaoLineSearchConvergedReason` reason why the line-search stopped

266:   Level: advanced

268:   Notes:
269:   The algorithm developer must set up the `TaoLineSearch` with calls to
270:   `TaoLineSearchSetObjectiveRoutine()` and `TaoLineSearchSetGradientRoutine()`,
271:   `TaoLineSearchSetObjectiveAndGradientRoutine()`, or `TaoLineSearchUseTaoRoutines()`.
272:   The latter is done automatically by default and thus requires no user input.

274:   You may or may not need to follow this with a call to
275:   `TaoAddLineSearchCounts()`, depending on whether you want these
276:   evaluations to count toward the total function/gradient evaluations.

278: .seealso: [](ch_tao), `Tao`, `TaoLineSearchConvergedReason`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetType()`,
279:           `TaoLineSearchSetInitialStepLength()`, `TaoAddLineSearchCounts()`
280: @*/
281: PetscErrorCode TaoLineSearchApply(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
282: {
283:   PetscInt low1, low2, low3, high1, high2, high3;

285:   PetscFunctionBegin;
288:   PetscAssertPointer(f, 3);
291:   PetscAssertPointer(reason, 7);
292:   PetscCheckSameComm(ls, 1, x, 2);
293:   PetscCheckSameTypeAndComm(x, 2, g, 4);
294:   PetscCheckSameTypeAndComm(x, 2, s, 5);
295:   PetscCall(VecGetOwnershipRange(x, &low1, &high1));
296:   PetscCall(VecGetOwnershipRange(g, &low2, &high2));
297:   PetscCall(VecGetOwnershipRange(s, &low3, &high3));
298:   PetscCheck(low1 == low2 && low1 == low3 && high1 == high2 && high1 == high3, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Incompatible vector local lengths");

300:   *reason = TAOLINESEARCH_CONTINUE_ITERATING;
301:   PetscCall(PetscObjectReference((PetscObject)s));
302:   PetscCall(VecDestroy(&ls->stepdirection));
303:   ls->stepdirection = s;

305:   PetscCall(TaoLineSearchSetUp(ls));
306:   ls->nfeval  = 0;
307:   ls->ngeval  = 0;
308:   ls->nfgeval = 0;
309:   /* Check parameter values */
310:   if (ls->ftol < 0.0) {
311:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: ftol (%g) < 0\n", (double)ls->ftol));
312:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
313:   }
314:   if (ls->rtol < 0.0) {
315:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: rtol (%g) < 0\n", (double)ls->rtol));
316:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
317:   }
318:   if (ls->gtol < 0.0) {
319:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: gtol (%g) < 0\n", (double)ls->gtol));
320:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
321:   }
322:   if (ls->stepmin < 0.0) {
323:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: stepmin (%g) < 0\n", (double)ls->stepmin));
324:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
325:   }
326:   if (ls->stepmax < ls->stepmin) {
327:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: stepmin (%g) > stepmax (%g)\n", (double)ls->stepmin, (double)ls->stepmax));
328:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
329:   }
330:   if (ls->max_funcs < 0) {
331:     PetscCall(PetscInfo(ls, "Bad Line Search Parameter: max_funcs (%" PetscInt_FMT ") < 0\n", ls->max_funcs));
332:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
333:   }
334:   if (PetscIsInfOrNanReal(*f)) {
335:     PetscCall(PetscInfo(ls, "Initial Line Search Function Value is infinity or NaN (%g)\n", (double)*f));
336:     *reason = TAOLINESEARCH_FAILED_INFORNAN;
337:   }

339:   PetscCall(PetscObjectReference((PetscObject)x));
340:   PetscCall(VecDestroy(&ls->start_x));
341:   ls->start_x = x;

343:   PetscCall(PetscLogEventBegin(TAOLINESEARCH_Apply, ls, 0, 0, 0));
344:   PetscUseTypeMethod(ls, apply, x, f, g, s);
345:   PetscCall(PetscLogEventEnd(TAOLINESEARCH_Apply, ls, 0, 0, 0));
346:   *reason   = ls->reason;
347:   ls->new_f = *f;

349:   if (steplength) *steplength = ls->step;

351:   PetscCall(TaoLineSearchViewFromOptions(ls, NULL, "-tao_ls_view"));
352:   PetscFunctionReturn(PETSC_SUCCESS);
353: }

355: /*@
356:   TaoLineSearchSetType - Sets the algorithm used in a line search

358:   Collective

360:   Input Parameters:
361: + ls   - the `TaoLineSearch` context
362: - type - the `TaoLineSearchType` selection

364:   Options Database Key:
365: . -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use

367:   Level: beginner

369: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchType`, `TaoLineSearchCreate()`, `TaoLineSearchGetType()`,
370:           `TaoLineSearchApply()`
371: @*/
372: PetscErrorCode TaoLineSearchSetType(TaoLineSearch ls, TaoLineSearchType type)
373: {
374:   PetscErrorCode (*r)(TaoLineSearch);
375:   PetscBool flg;

377:   PetscFunctionBegin;
379:   PetscAssertPointer(type, 2);
380:   PetscCall(PetscObjectTypeCompare((PetscObject)ls, type, &flg));
381:   if (flg) PetscFunctionReturn(PETSC_SUCCESS);

383:   PetscCall(PetscFunctionListFind(TaoLineSearchList, type, &r));
384:   PetscCheck(r, PetscObjectComm((PetscObject)ls), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested TaoLineSearch type %s", type);
385:   PetscTryTypeMethod(ls, destroy);
386:   ls->max_funcs = 30;
387:   ls->ftol      = 0.0001;
388:   ls->gtol      = 0.9;
389:   ls->rtol      = PetscDefined(USE_REAL_SINGLE) ? 1.0e-5 : 1.0e-10;
390:   ls->stepmin   = 1.0e-20;
391:   ls->stepmax   = 1.0e+20;

393:   ls->nfeval              = 0;
394:   ls->ngeval              = 0;
395:   ls->nfgeval             = 0;
396:   ls->ops->setup          = NULL;
397:   ls->ops->apply          = NULL;
398:   ls->ops->view           = NULL;
399:   ls->ops->setfromoptions = NULL;
400:   ls->ops->destroy        = NULL;
401:   ls->setupcalled         = PETSC_FALSE;
402:   PetscCall((*r)(ls));
403:   PetscCall(PetscObjectChangeTypeName((PetscObject)ls, type));
404:   PetscFunctionReturn(PETSC_SUCCESS);
405: }

407: /*@
408:   TaoLineSearchMonitor - Monitor the line search steps. This routine will output the
409:   iteration number, step length, and function value before calling the implementation
410:   specific monitor.

412:   Input Parameters:
413: + ls   - the `TaoLineSearch` context
414: . its  - the current iterate number (>=0)
415: . f    - the current objective function value
416: - step - the step length

418:   Options Database Key:
419: . -tao_ls_monitor - Use the default monitor, which prints statistics to standard output

421:   Level: developer

423: .seealso: `TaoLineSearch`
424: @*/
425: PetscErrorCode TaoLineSearchMonitor(TaoLineSearch ls, PetscInt its, PetscReal f, PetscReal step)
426: {
427:   PetscInt tabs;

429:   PetscFunctionBegin;
431:   if (ls->usemonitor) {
432:     PetscCall(PetscViewerASCIIGetTab(ls->viewer, &tabs));
433:     PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel));
434:     PetscCall(PetscViewerASCIIPrintf(ls->viewer, "%3" PetscInt_FMT " LS", its));
435:     PetscCall(PetscViewerASCIIPrintf(ls->viewer, "  Function value: %g,", (double)f));
436:     PetscCall(PetscViewerASCIIPrintf(ls->viewer, "  Step length: %g\n", (double)step));
437:     if (ls->ops->monitor && its > 0) {
438:       PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel + 3));
439:       PetscUseTypeMethod(ls, monitor);
440:     }
441:     PetscCall(PetscViewerASCIISetTab(ls->viewer, tabs));
442:   }
443:   PetscFunctionReturn(PETSC_SUCCESS);
444: }

446: /*@
447:   TaoLineSearchSetFromOptions - Sets various `TaoLineSearch` parameters from user
448:   options.

450:   Collective

452:   Input Parameter:
453: . ls - the `TaoLineSearch` context

455:   Options Database Keys:
456: + -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use
457: . -tao_ls_ftol tol                                          - tolerance for sufficient decrease
458: . -tao_ls_gtol tol                                          - tolerance for curvature condition
459: . -tao_ls_rtol tol                                          - relative tolerance for acceptable step
460: . -tao_ls_stepinit step                                     - initial steplength allowed
461: . -tao_ls_stepmin step                                      - minimum steplength allowed
462: . -tao_ls_stepmax step                                      - maximum steplength allowed
463: . -tao_ls_max_funcs n                                       - maximum number of function evaluations allowed
464: - -tao_ls_view                                              - display line-search results

466:   Level: beginner

468: .seealso: `Tao`, `TaoLineSearch`, `TaoGetLineSearch()`
469: @*/
470: PetscErrorCode TaoLineSearchSetFromOptions(TaoLineSearch ls)
471: {
472:   const char *default_type = TAOLINESEARCHMT;
473:   char        type[256], monfilename[PETSC_MAX_PATH_LEN];
474:   PetscViewer monviewer;
475:   PetscBool   flg;

477:   PetscFunctionBegin;
479:   PetscObjectOptionsBegin((PetscObject)ls);
480:   if (((PetscObject)ls)->type_name) default_type = ((PetscObject)ls)->type_name;
481:   /* Check for type from options */
482:   PetscCall(PetscOptionsFList("-tao_ls_type", "Tao Line Search type", "TaoLineSearchSetType", TaoLineSearchList, default_type, type, 256, &flg));
483:   if (flg) {
484:     PetscCall(TaoLineSearchSetType(ls, type));
485:   } else if (!((PetscObject)ls)->type_name) {
486:     PetscCall(TaoLineSearchSetType(ls, default_type));
487:   }

489:   PetscCall(PetscOptionsInt("-tao_ls_max_funcs", "max function evals in line search", "", ls->max_funcs, &ls->max_funcs, NULL));
490:   PetscCall(PetscOptionsReal("-tao_ls_ftol", "tol for sufficient decrease", "", ls->ftol, &ls->ftol, NULL));
491:   PetscCall(PetscOptionsReal("-tao_ls_gtol", "tol for curvature condition", "", ls->gtol, &ls->gtol, NULL));
492:   PetscCall(PetscOptionsReal("-tao_ls_rtol", "relative tol for acceptable step", "", ls->rtol, &ls->rtol, NULL));
493:   PetscCall(PetscOptionsReal("-tao_ls_stepmin", "lower bound for step", "", ls->stepmin, &ls->stepmin, NULL));
494:   PetscCall(PetscOptionsReal("-tao_ls_stepmax", "upper bound for step", "", ls->stepmax, &ls->stepmax, NULL));
495:   PetscCall(PetscOptionsReal("-tao_ls_stepinit", "initial step", "", ls->initstep, &ls->initstep, NULL));
496:   PetscCall(PetscOptionsString("-tao_ls_monitor", "enable the basic monitor", "TaoLineSearchSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg));
497:   if (flg) {
498:     PetscCall(PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ls), monfilename, &monviewer));
499:     ls->viewer     = monviewer;
500:     ls->usemonitor = PETSC_TRUE;
501:   }
502:   PetscTryTypeMethod(ls, setfromoptions, PetscOptionsObject);
503:   PetscOptionsEnd();
504:   PetscFunctionReturn(PETSC_SUCCESS);
505: }

507: /*@
508:   TaoLineSearchGetType - Gets the current line search algorithm

510:   Not Collective

512:   Input Parameter:
513: . ls - the `TaoLineSearch` context

515:   Output Parameter:
516: . type - the line search algorithm in effect

518:   Level: developer

520:   Note:
521:   `type` should not be retained for later use as it will be an invalid pointer if the `TaoLineSearchType` of `ls` is changed.

523: .seealso: `TaoLineSearch`, `TaoLineSearchSetType()`, `TaoLineSearchType`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`
524: @*/
525: PetscErrorCode TaoLineSearchGetType(TaoLineSearch ls, TaoLineSearchType *type)
526: {
527:   PetscFunctionBegin;
529:   PetscAssertPointer(type, 2);
530:   *type = ((PetscObject)ls)->type_name;
531:   PetscFunctionReturn(PETSC_SUCCESS);
532: }

534: /*@
535:   TaoLineSearchGetNumberFunctionEvaluations - Gets the number of function and gradient evaluation
536:   routines used by the line search in last application (not cumulative).

538:   Not Collective

540:   Input Parameter:
541: . ls - the `TaoLineSearch` context

543:   Output Parameters:
544: + nfeval  - number of function evaluations
545: . ngeval  - number of gradient evaluations
546: - nfgeval - number of function/gradient evaluations

548:   Level: intermediate

550:   Note:
551:   If the line search is using the `Tao` objective and gradient
552:   routines directly (see `TaoLineSearchUseTaoRoutines()`), then the `Tao`
553:   is already counting the number of evaluations.

555: .seealso: `TaoLineSearch`
556: @*/
557: PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval)
558: {
559:   PetscFunctionBegin;
561:   *nfeval  = ls->nfeval;
562:   *ngeval  = ls->ngeval;
563:   *nfgeval = ls->nfgeval;
564:   PetscFunctionReturn(PETSC_SUCCESS);
565: }

567: /*@
568:   TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using
569:   the standard `Tao` evaluation routines.

571:   Not Collective

573:   Input Parameter:
574: . ls - the `TaoLineSearch` context

576:   Output Parameter:
577: . flg - `PETSC_TRUE` if the line search is using `Tao` evaluation routines,
578:         otherwise `PETSC_FALSE`

580:   Level: developer

582: .seealso: `TaoLineSearch`
583: @*/
584: PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg)
585: {
586:   PetscFunctionBegin;
588:   *flg = ls->usetaoroutines;
589:   PetscFunctionReturn(PETSC_SUCCESS);
590: }

592: /*@
593:   TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search

595:   Logically Collective

597:   Input Parameters:
598: + ls   - the `TaoLineSearch` context
599: . func - the objective function evaluation routine
600: - ctx  - the (optional) user-defined context for private data

602:   Calling sequence of `func`:
603: + ls  - the line search context
604: . x   - input vector
605: . f   - function value
606: - ctx - (optional) user-defined context

608:   Level: advanced

610:   Notes:
611:   Use this routine only if you want the line search objective
612:   evaluation routine to be different from the `Tao`'s objective
613:   evaluation routine. If you use this routine you must also set
614:   the line search gradient and/or function/gradient routine.

616:   Some algorithms (lcl, gpcg) set their own objective routine for the
617:   line search, application programmers should be wary of overriding the
618:   default objective routine.

620: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
621: @*/
622: PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, PetscCtx ctx), PetscCtx ctx)
623: {
624:   PetscFunctionBegin;

627:   ls->ops->computeobjective = func;
628:   if (ctx) ls->userctx_func = ctx;
629:   ls->usetaoroutines = PETSC_FALSE;
630:   PetscFunctionReturn(PETSC_SUCCESS);
631: }

633: /*@
634:   TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search

636:   Logically Collective

638:   Input Parameters:
639: + ls   - the `TaoLineSearch` context
640: . func - the gradient evaluation routine
641: - ctx  - the (optional) user-defined context for private data

643:   Calling sequence of `func`:
644: + ls  - the linesearch object
645: . x   - input vector
646: . g   - gradient vector
647: - ctx - (optional) user-defined context

649:   Level: beginner

651:   Note:
652:   Use this routine only if you want the line search gradient
653:   evaluation routine to be different from the `Tao`'s gradient
654:   evaluation routine. If you use this routine you must also set
655:   the line search function and/or function/gradient routine.

657:   Some algorithms (lcl, gpcg) set their own gradient routine for the
658:   line search, application programmers should be wary of overriding the
659:   default gradient routine.

661: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
662: @*/
663: PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec g, PetscCtx ctx), PetscCtx ctx)
664: {
665:   PetscFunctionBegin;
667:   ls->ops->computegradient = func;
668:   if (ctx) ls->userctx_grad = ctx;
669:   ls->usetaoroutines = PETSC_FALSE;
670:   PetscFunctionReturn(PETSC_SUCCESS);
671: }

673: /*@
674:   TaoLineSearchSetObjectiveAndGradientRoutine - Sets the objective/gradient evaluation routine for the line search

676:   Logically Collective

678:   Input Parameters:
679: + ls   - the `TaoLineSearch` context
680: . func - the objective and gradient evaluation routine
681: - ctx  - the (optional) user-defined context for private data

683:   Calling sequence of `func`:
684: + ls  - the linesearch object
685: . x   - input vector
686: . f   - function value
687: . g   - gradient vector
688: - ctx - (optional) user-defined context

690:   Level: beginner

692:   Note:
693:   Use this routine only if you want the line search objective and gradient
694:   evaluation routines to be different from the `Tao`'s objective
695:   and gradient evaluation routines.

697:   Some algorithms (lcl, gpcg) set their own objective routine for the
698:   line search, application programmers should be wary of overriding the
699:   default objective routine.

701: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
702: @*/
703: PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscCtx ctx), PetscCtx ctx)
704: {
705:   PetscFunctionBegin;
707:   ls->ops->computeobjectiveandgradient = func;
708:   if (ctx) ls->userctx_funcgrad = ctx;
709:   ls->usetaoroutines = PETSC_FALSE;
710:   PetscFunctionReturn(PETSC_SUCCESS);
711: }

713: /*@
714:   TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and
715:   (gradient'*stepdirection) evaluation routine for the line search.

717:   Logically Collective

719:   Input Parameters:
720: + ls   - the `TaoLineSearch` context
721: . func - the objective and gradient evaluation routine
722: - ctx  - the (optional) user-defined context for private data

724:   Calling sequence of `func`:
725: + ls  - the linesearch context
726: . x   - input vector
727: . s   - step direction
728: . f   - function value
729: . gts - inner product of gradient and step direction vectors
730: - ctx - (optional) user-defined context

732:   Level: advanced

734:   Notes:
735:   Sometimes it is more efficient to compute the inner product of the gradient and the step
736:   direction than it is to compute the gradient, and this is all the line search typically needs
737:   of the gradient.

739:   The gradient will still need to be computed at the end of the line
740:   search, so you will still need to set a line search gradient evaluation
741:   routine

743:   Bounded line searches (those used in bounded optimization algorithms)
744:   don't use g's directly, but rather (g'x - g'x0)/steplength.  You can get the
745:   x0 and steplength with `TaoLineSearchGetStartingVector()` and `TaoLineSearchGetStepLength()`

747:   Some algorithms (lcl, gpcg) set their own objective routine for the
748:   line search, application programmers should be wary of overriding the
749:   default objective routine.

751: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjective()`, `TaoLineSearchSetGradient()`, `TaoLineSearchUseTaoRoutines()`
752: @*/
753: PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *f, PetscReal *gts, PetscCtx ctx), PetscCtx ctx)
754: {
755:   PetscFunctionBegin;
757:   ls->ops->computeobjectiveandgts = func;
758:   if (ctx) ls->userctx_funcgts = ctx;
759:   ls->usegts         = PETSC_TRUE;
760:   ls->usetaoroutines = PETSC_FALSE;
761:   PetscFunctionReturn(PETSC_SUCCESS);
762: }

764: /*@
765:   TaoLineSearchUseTaoRoutines - Informs the `TaoLineSearch` to use the
766:   objective and gradient evaluation routines from the given `Tao` object. The default.

768:   Logically Collective

770:   Input Parameters:
771: + ls - the `TaoLineSearch` context
772: - ts - the `Tao` context with defined objective/gradient evaluation routines

774:   Level: developer

776: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`
777: @*/
778: PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts)
779: {
780:   PetscFunctionBegin;
783:   ls->tao            = ts;
784:   ls->usetaoroutines = PETSC_TRUE;
785:   PetscFunctionReturn(PETSC_SUCCESS);
786: }

788: /*@
789:   TaoLineSearchComputeObjective - Computes the objective function value at a given point

791:   Collective

793:   Input Parameters:
794: + ls - the `TaoLineSearch` context
795: - x  - input vector

797:   Output Parameter:
798: . f - Objective value at `x`

800:   Level: developer

802:   Note:
803:   `TaoLineSearchComputeObjective()` is typically used within line searches
804:   so most users would not generally call this routine themselves.

806: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
807: @*/
808: PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f)
809: {
810:   Vec       gdummy;
811:   PetscReal gts;

813:   PetscFunctionBegin;
816:   PetscAssertPointer(f, 3);
817:   PetscCheckSameComm(ls, 1, x, 2);
818:   if (ls->usetaoroutines) {
819:     PetscCall(TaoComputeObjective(ls->tao, x, f));
820:   } else {
821:     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");
822:     PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
823:     if (ls->ops->computeobjective) PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
824:     else if (ls->ops->computeobjectiveandgradient) {
825:       PetscCall(VecDuplicate(x, &gdummy));
826:       PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgradient)(ls, x, f, gdummy, ls->userctx_funcgrad));
827:       PetscCall(VecDestroy(&gdummy));
828:     } else PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, &gts, ls->userctx_funcgts));
829:     PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
830:   }
831:   ls->nfeval++;
832:   PetscFunctionReturn(PETSC_SUCCESS);
833: }

835: /*@
836:   TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point

838:   Collective

840:   Input Parameters:
841: + ls - the `TaoLineSearch` context
842: - x  - input vector

844:   Output Parameters:
845: + f - Objective value at `x`
846: - g - Gradient vector at `x`

848:   Level: developer

850:   Note:
851:   `TaoLineSearchComputeObjectiveAndGradient()` is typically used within line searches
852:   so most users would not generally call this routine themselves.

854: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchSetObjectiveRoutine()`
855: @*/
856: PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g)
857: {
858:   PetscFunctionBegin;
861:   PetscAssertPointer(f, 3);
863:   PetscCheckSameComm(ls, 1, x, 2);
864:   PetscCheckSameComm(ls, 1, g, 4);
865:   if (ls->usetaoroutines) {
866:     PetscCall(TaoComputeObjectiveAndGradient(ls->tao, x, f, g));
867:   } else {
868:     PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
869:     if (ls->ops->computeobjectiveandgradient) PetscCallBack("TaoLineSearch callback objective/gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, f, g, ls->userctx_funcgrad));
870:     else {
871:       PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
872:       PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
873:     }
874:     PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
875:     PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
876:   }
877:   ls->nfgeval++;
878:   PetscFunctionReturn(PETSC_SUCCESS);
879: }

881: /*@
882:   TaoLineSearchComputeGradient - Computes the gradient of the objective function

884:   Collective

886:   Input Parameters:
887: + ls - the `TaoLineSearch` context
888: - x  - input vector

890:   Output Parameter:
891: . g - gradient vector

893:   Level: developer

895:   Note:
896:   `TaoComputeGradient()` is typically used within line searches
897:   so most users would not generally call this routine themselves.

899: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeObjective()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetGradient()`
900: @*/
901: PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g)
902: {
903:   PetscReal fdummy;

905:   PetscFunctionBegin;
909:   PetscCheckSameComm(ls, 1, x, 2);
910:   PetscCheckSameComm(ls, 1, g, 3);
911:   if (ls->usetaoroutines) {
912:     PetscCall(TaoComputeGradient(ls->tao, x, g));
913:   } else {
914:     PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
915:     if (ls->ops->computegradient) PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
916:     else PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, &fdummy, g, ls->userctx_funcgrad));
917:     PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
918:   }
919:   ls->ngeval++;
920:   PetscFunctionReturn(PETSC_SUCCESS);
921: }

923: /*@
924:   TaoLineSearchComputeObjectiveAndGTS - Computes the objective function value and inner product of gradient and
925:   step direction at a given point

927:   Collective

929:   Input Parameters:
930: + ls - the `TaoLineSearch` context
931: - x  - input vector

933:   Output Parameters:
934: + f   - Objective value at `x`
935: - gts - inner product of gradient and step direction at `x`

937:   Level: developer

939:   Note:
940:   `TaoLineSearchComputeObjectiveAndGTS()` is typically used within line searches
941:   so most users would not generally call this routine themselves.

943: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
944: @*/
945: PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts)
946: {
947:   PetscFunctionBegin;
950:   PetscAssertPointer(f, 3);
951:   PetscAssertPointer(gts, 4);
952:   PetscCheckSameComm(ls, 1, x, 2);
953:   PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
954:   PetscCallBack("TaoLineSearch callback objective/gts", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, gts, ls->userctx_funcgts));
955:   PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
956:   PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
957:   ls->nfeval++;
958:   PetscFunctionReturn(PETSC_SUCCESS);
959: }

961: /*@
962:   TaoLineSearchGetSolution - Returns the solution to the line search

964:   Collective

966:   Input Parameter:
967: . ls - the `TaoLineSearch` context

969:   Output Parameters:
970: + x          - the new solution
971: . f          - the objective function value at `x`
972: . g          - the gradient at `x`
973: . steplength - the multiple of the step direction taken by the line search
974: - reason     - the reason why the line search terminated

976:   Level: developer

978: .seealso: `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
979: @*/
980: PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
981: {
982:   PetscFunctionBegin;
985:   PetscAssertPointer(f, 3);
987:   PetscAssertPointer(reason, 6);
988:   if (ls->new_x) PetscCall(VecCopy(ls->new_x, x));
989:   *f = ls->new_f;
990:   if (ls->new_g) PetscCall(VecCopy(ls->new_g, g));
991:   if (steplength) *steplength = ls->step;
992:   *reason = ls->reason;
993:   PetscFunctionReturn(PETSC_SUCCESS);
994: }

996: /*@
997:   TaoLineSearchGetStartingVector - Gets a the initial point of the line
998:   search.

1000:   Not Collective

1002:   Input Parameter:
1003: . ls - the `TaoLineSearch` context

1005:   Output Parameter:
1006: . x - The initial point of the line search

1008:   Level: advanced

1010: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStepDirection()`
1011: @*/
1012: PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x)
1013: {
1014:   PetscFunctionBegin;
1016:   if (x) *x = ls->start_x;
1017:   PetscFunctionReturn(PETSC_SUCCESS);
1018: }

1020: /*@
1021:   TaoLineSearchGetStepDirection - Gets the step direction of the line
1022:   search.

1024:   Not Collective

1026:   Input Parameter:
1027: . ls - the `TaoLineSearch` context

1029:   Output Parameter:
1030: . s - the step direction of the line search

1032:   Level: advanced

1034: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`
1035: @*/
1036: PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s)
1037: {
1038:   PetscFunctionBegin;
1040:   if (s) *s = ls->stepdirection;
1041:   PetscFunctionReturn(PETSC_SUCCESS);
1042: }

1044: /*@
1045:   TaoLineSearchGetFullStepObjective - Returns the objective function value at the full step.  Useful for some minimization algorithms.

1047:   Not Collective

1049:   Input Parameter:
1050: . ls - the `TaoLineSearch` context

1052:   Output Parameter:
1053: . f_fullstep - the objective value at the full step length

1055:   Level: developer

1057: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
1058: @*/
1059: PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep)
1060: {
1061:   PetscFunctionBegin;
1063:   *f_fullstep = ls->f_fullstep;
1064:   PetscFunctionReturn(PETSC_SUCCESS);
1065: }

1067: /*@
1068:   TaoLineSearchSetVariableBounds - Sets the upper and lower bounds for a bounded line search

1070:   Logically Collective

1072:   Input Parameters:
1073: + ls - the `TaoLineSearch` context
1074: . xl - vector of lower bounds
1075: - xu - vector of upper bounds

1077:   Level: beginner

1079:   Note:
1080:   If the variable bounds are not set with this routine, then
1081:   `PETSC_NINFINITY` and `PETSC_INFINITY` are assumed

1083: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoSetVariableBounds()`, `TaoLineSearchCreate()`
1084: @*/
1085: PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls, Vec xl, Vec xu)
1086: {
1087:   PetscFunctionBegin;
1091:   PetscCall(PetscObjectReference((PetscObject)xl));
1092:   PetscCall(PetscObjectReference((PetscObject)xu));
1093:   PetscCall(VecDestroy(&ls->lower));
1094:   PetscCall(VecDestroy(&ls->upper));
1095:   ls->lower   = xl;
1096:   ls->upper   = xu;
1097:   ls->bounded = (PetscBool)(xl || xu);
1098:   PetscFunctionReturn(PETSC_SUCCESS);
1099: }

1101: /*@
1102:   TaoLineSearchSetInitialStepLength - Sets the initial step length of a line
1103:   search.  If this value is not set then 1.0 is assumed.

1105:   Logically Collective

1107:   Input Parameters:
1108: + ls - the `TaoLineSearch` context
1109: - s  - the initial step size

1111:   Level: intermediate

1113: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchGetStepLength()`, `TaoLineSearchApply()`
1114: @*/
1115: PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls, PetscReal s)
1116: {
1117:   PetscFunctionBegin;
1120:   ls->initstep = s;
1121:   PetscFunctionReturn(PETSC_SUCCESS);
1122: }

1124: /*@
1125:   TaoLineSearchGetStepLength - Get the current step length

1127:   Not Collective

1129:   Input Parameter:
1130: . ls - the `TaoLineSearch` context

1132:   Output Parameter:
1133: . s - the current step length

1135:   Level: intermediate

1137: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetInitialStepLength()`, `TaoLineSearchApply()`
1138: @*/
1139: PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls, PetscReal *s)
1140: {
1141:   PetscFunctionBegin;
1143:   *s = ls->step;
1144:   PetscFunctionReturn(PETSC_SUCCESS);
1145: }

1147: /*@
1148:   TaoLineSearchRegister - Adds a line-search algorithm to the registry

1150:   Not Collective, No Fortran Support

1152:   Input Parameters:
1153: + sname - name of a new user-defined solver
1154: - func  - routine to Create method context

1156:   Calling sequence of `func`:
1157: . ls - the `TaoLineSearch` object to set with the `TaoLineSearchType` specific structure

1159:   Example Usage:
1160: .vb
1161:    TaoLineSearchRegister("my_linesearch", MyLinesearchCreate);
1162: .ve

1164:   Then, your solver can be chosen with the procedural interface via
1165: .vb
1166:   TaoLineSearchSetType(ls, "my_linesearch")
1167: .ve
1168:   or at runtime via the option
1169: .vb
1170:   -tao_ls_type my_linesearch
1171: .ve

1173:   Level: developer

1175:   Note:
1176:   `TaoLineSearchRegister()` may be called multiple times to add several user-defined solvers.

1178: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`
1179: @*/
1180: PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch ls))
1181: {
1182:   PetscFunctionBegin;
1183:   PetscCall(TaoLineSearchInitializePackage());
1184:   PetscCall(PetscFunctionListAdd(&TaoLineSearchList, sname, func));
1185:   PetscFunctionReturn(PETSC_SUCCESS);
1186: }

1188: /*@
1189:   TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching
1190:   for all `TaoLineSearch` options in the database.

1192:   Collective

1194:   Input Parameters:
1195: + ls - the `TaoLineSearch` solver context
1196: - p  - the prefix string to prepend to all line search requests

1198:   Level: advanced

1200:   Notes:
1201:   A hyphen (-) must NOT be given at the beginning of the prefix name.
1202:   The first character of all runtime options is AUTOMATICALLY the hyphen.

1204:   This is inherited from the `Tao` object so rarely needs to be set

1206: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1207: @*/
1208: PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[])
1209: {
1210:   return PetscObjectAppendOptionsPrefix((PetscObject)ls, p);
1211: }

1213: /*@
1214:   TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1215:   `TaoLineSearch` options in the database

1217:   Not Collective

1219:   Input Parameter:
1220: . ls - the `TaoLineSearch` context

1222:   Output Parameter:
1223: . p - pointer to the prefix string used is returned

1225:   Level: advanced

1227: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchAppendOptionsPrefix()`
1228: @*/
1229: PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[])
1230: {
1231:   return PetscObjectGetOptionsPrefix((PetscObject)ls, p);
1232: }

1234: /*@
1235:   TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all
1236:   `TaoLineSearch` options in the database.

1238:   Logically Collective

1240:   Input Parameters:
1241: + ls - the `TaoLineSearch` context
1242: - p  - the prefix string to prepend to all `ls` option requests

1244:   Level: advanced

1246:   Notes:
1247:   A hyphen (-) must NOT be given at the beginning of the prefix name.
1248:   The first character of all runtime options is AUTOMATICALLY the hyphen.

1250:   This is inherited from the `Tao` object so rarely needs to be set

1252:   For example, to distinguish between the runtime options for two
1253:   different line searches, one could call
1254: .vb
1255:       TaoLineSearchSetOptionsPrefix(ls1,"sys1_")
1256:       TaoLineSearchSetOptionsPrefix(ls2,"sys2_")
1257: .ve

1259:   This would enable use of different options for each system, such as
1260: .vb
1261:       -sys1_tao_ls_type mt
1262:       -sys2_tao_ls_type armijo
1263: .ve

1265: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchAppendOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1266: @*/
1267: PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[])
1268: {
1269:   return PetscObjectSetOptionsPrefix((PetscObject)ls, p);
1270: }