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, >s, 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: }