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: /*@C
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: #if defined(PETSC_USE_REAL_SINGLE)
130: ls->rtol = 1.0e-5;
131: #else
132: ls->rtol = 1.0e-10;
133: #endif
134: ls->stepmin = 1.0e-20;
135: ls->stepmax = 1.0e+20;
136: ls->step = 1.0;
137: ls->initstep = 1.0;
138: *newls = ls;
139: PetscFunctionReturn(PETSC_SUCCESS);
140: }
142: /*@
143: TaoLineSearchSetUp - Sets up the internal data structures for the later use
144: of a `TaoLineSearch`
146: Collective
148: Input Parameter:
149: . ls - the `TaoLineSearch` context
151: Level: developer
153: Note:
154: The user will not need to explicitly call `TaoLineSearchSetUp()`, as it will
155: automatically be called in `TaoLineSearchSolve()`. However, if the user
156: desires to call it explicitly, it should come after `TaoLineSearchCreate()`
157: but before `TaoLineSearchApply()`.
159: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApply()`
160: @*/
161: PetscErrorCode TaoLineSearchSetUp(TaoLineSearch ls)
162: {
163: const char *default_type = TAOLINESEARCHMT;
164: PetscBool flg;
166: PetscFunctionBegin;
168: if (ls->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
169: if (!((PetscObject)ls)->type_name) PetscCall(TaoLineSearchSetType(ls, default_type));
170: PetscTryTypeMethod(ls, setup);
171: if (ls->usetaoroutines) {
172: PetscCall(TaoIsObjectiveDefined(ls->tao, &flg));
173: ls->hasobjective = flg;
174: PetscCall(TaoIsGradientDefined(ls->tao, &flg));
175: ls->hasgradient = flg;
176: PetscCall(TaoIsObjectiveAndGradientDefined(ls->tao, &flg));
177: ls->hasobjectiveandgradient = flg;
178: } else {
179: if (ls->ops->computeobjective) {
180: ls->hasobjective = PETSC_TRUE;
181: } else {
182: ls->hasobjective = PETSC_FALSE;
183: }
184: if (ls->ops->computegradient) {
185: ls->hasgradient = PETSC_TRUE;
186: } else {
187: ls->hasgradient = PETSC_FALSE;
188: }
189: if (ls->ops->computeobjectiveandgradient) {
190: ls->hasobjectiveandgradient = PETSC_TRUE;
191: } else {
192: ls->hasobjectiveandgradient = PETSC_FALSE;
193: }
194: }
195: ls->setupcalled = PETSC_TRUE;
196: PetscFunctionReturn(PETSC_SUCCESS);
197: }
199: /*@
200: TaoLineSearchReset - Some line searches may carry state information
201: from one `TaoLineSearchApply()` to the next. This function resets this
202: state information.
204: Collective
206: Input Parameter:
207: . ls - the `TaoLineSearch` context
209: Level: developer
211: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApply()`
212: @*/
213: PetscErrorCode TaoLineSearchReset(TaoLineSearch ls)
214: {
215: PetscFunctionBegin;
217: PetscTryTypeMethod(ls, reset);
218: PetscFunctionReturn(PETSC_SUCCESS);
219: }
221: /*@
222: TaoLineSearchDestroy - Destroys the `TaoLineSearch` context that was created with
223: `TaoLineSearchCreate()`
225: Collective
227: Input Parameter:
228: . ls - the `TaoLineSearch` context
230: Level: developer
232: .seealso: `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchApple()`
233: @*/
234: PetscErrorCode TaoLineSearchDestroy(TaoLineSearch *ls)
235: {
236: PetscFunctionBegin;
237: if (!*ls) PetscFunctionReturn(PETSC_SUCCESS);
239: if (--((PetscObject)*ls)->refct > 0) {
240: *ls = NULL;
241: PetscFunctionReturn(PETSC_SUCCESS);
242: }
243: PetscCall(VecDestroy(&(*ls)->stepdirection));
244: PetscCall(VecDestroy(&(*ls)->start_x));
245: PetscCall(VecDestroy(&(*ls)->upper));
246: PetscCall(VecDestroy(&(*ls)->lower));
247: PetscTryTypeMethod(*ls, destroy);
248: if ((*ls)->usemonitor) PetscCall(PetscViewerDestroy(&(*ls)->viewer));
249: PetscCall(PetscHeaderDestroy(ls));
250: PetscFunctionReturn(PETSC_SUCCESS);
251: }
253: /*@
254: TaoLineSearchApply - Performs a line-search in a given step direction.
255: Criteria for acceptable step length depends on the line-search algorithm chosen
257: Collective
259: Input Parameters:
260: + ls - the `TaoLineSearch` context
261: - s - search direction
263: Output Parameters:
264: + x - On input the current solution, on output `x` contains the new solution determined by the line search
265: . f - On input the objective function value at current solution, on output contains the objective function value at new solution
266: . g - On input the gradient evaluated at `x`, on output contains the gradient at new solution
267: . steplength - scalar multiplier of `s` used ( $x = x_0 + steplength * x)
268: - reason - `TaoLineSearchConvergedReason` reason why the line-search stopped
270: Level: advanced
272: Notes:
273: The algorithm developer must set up the `TaoLineSearch` with calls to
274: `TaoLineSearchSetObjectiveRoutine()` and `TaoLineSearchSetGradientRoutine()`,
275: `TaoLineSearchSetObjectiveAndGradientRoutine()`, or `TaoLineSearchUseTaoRoutines()`.
276: The latter is done automatically by default and thus requires no user input.
278: You may or may not need to follow this with a call to
279: `TaoAddLineSearchCounts()`, depending on whether you want these
280: evaluations to count toward the total function/gradient evaluations.
282: .seealso: [](ch_tao), `Tao`, `TaoLineSearchConvergedReason`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetType()`,
283: `TaoLineSearchSetInitialStepLength()`, `TaoAddLineSearchCounts()`
284: @*/
285: PetscErrorCode TaoLineSearchApply(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
286: {
287: PetscInt low1, low2, low3, high1, high2, high3;
289: PetscFunctionBegin;
292: PetscAssertPointer(f, 3);
295: PetscAssertPointer(reason, 7);
296: PetscCheckSameComm(ls, 1, x, 2);
297: PetscCheckSameTypeAndComm(x, 2, g, 4);
298: PetscCheckSameTypeAndComm(x, 2, s, 5);
299: PetscCall(VecGetOwnershipRange(x, &low1, &high1));
300: PetscCall(VecGetOwnershipRange(g, &low2, &high2));
301: PetscCall(VecGetOwnershipRange(s, &low3, &high3));
302: PetscCheck(low1 == low2 && low1 == low3 && high1 == high2 && high1 == high3, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Incompatible vector local lengths");
304: *reason = TAOLINESEARCH_CONTINUE_ITERATING;
305: PetscCall(PetscObjectReference((PetscObject)s));
306: PetscCall(VecDestroy(&ls->stepdirection));
307: ls->stepdirection = s;
309: PetscCall(TaoLineSearchSetUp(ls));
310: ls->nfeval = 0;
311: ls->ngeval = 0;
312: ls->nfgeval = 0;
313: /* Check parameter values */
314: if (ls->ftol < 0.0) {
315: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: ftol (%g) < 0\n", (double)ls->ftol));
316: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
317: }
318: if (ls->rtol < 0.0) {
319: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: rtol (%g) < 0\n", (double)ls->rtol));
320: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
321: }
322: if (ls->gtol < 0.0) {
323: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: gtol (%g) < 0\n", (double)ls->gtol));
324: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
325: }
326: if (ls->stepmin < 0.0) {
327: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: stepmin (%g) < 0\n", (double)ls->stepmin));
328: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
329: }
330: if (ls->stepmax < ls->stepmin) {
331: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: stepmin (%g) > stepmax (%g)\n", (double)ls->stepmin, (double)ls->stepmax));
332: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
333: }
334: if (ls->max_funcs < 0) {
335: PetscCall(PetscInfo(ls, "Bad Line Search Parameter: max_funcs (%" PetscInt_FMT ") < 0\n", ls->max_funcs));
336: *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
337: }
338: if (PetscIsInfOrNanReal(*f)) {
339: PetscCall(PetscInfo(ls, "Initial Line Search Function Value is infinity or NaN (%g)\n", (double)*f));
340: *reason = TAOLINESEARCH_FAILED_INFORNAN;
341: }
343: PetscCall(PetscObjectReference((PetscObject)x));
344: PetscCall(VecDestroy(&ls->start_x));
345: ls->start_x = x;
347: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Apply, ls, 0, 0, 0));
348: PetscUseTypeMethod(ls, apply, x, f, g, s);
349: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Apply, ls, 0, 0, 0));
350: *reason = ls->reason;
351: ls->new_f = *f;
353: if (steplength) *steplength = ls->step;
355: PetscCall(TaoLineSearchViewFromOptions(ls, NULL, "-tao_ls_view"));
356: PetscFunctionReturn(PETSC_SUCCESS);
357: }
359: /*@
360: TaoLineSearchSetType - Sets the algorithm used in a line search
362: Collective
364: Input Parameters:
365: + ls - the `TaoLineSearch` context
366: - type - the `TaoLineSearchType` selection
368: Options Database Key:
369: . -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use
371: Level: beginner
373: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchType`, `TaoLineSearchCreate()`, `TaoLineSearchGetType()`,
374: `TaoLineSearchApply()`
375: @*/
376: PetscErrorCode TaoLineSearchSetType(TaoLineSearch ls, TaoLineSearchType type)
377: {
378: PetscErrorCode (*r)(TaoLineSearch);
379: PetscBool flg;
381: PetscFunctionBegin;
383: PetscAssertPointer(type, 2);
384: PetscCall(PetscObjectTypeCompare((PetscObject)ls, type, &flg));
385: if (flg) PetscFunctionReturn(PETSC_SUCCESS);
387: PetscCall(PetscFunctionListFind(TaoLineSearchList, type, &r));
388: PetscCheck(r, PetscObjectComm((PetscObject)ls), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested TaoLineSearch type %s", type);
389: PetscTryTypeMethod(ls, destroy);
390: ls->max_funcs = 30;
391: ls->ftol = 0.0001;
392: ls->gtol = 0.9;
393: #if defined(PETSC_USE_REAL_SINGLE)
394: ls->rtol = 1.0e-5;
395: #else
396: ls->rtol = 1.0e-10;
397: #endif
398: ls->stepmin = 1.0e-20;
399: ls->stepmax = 1.0e+20;
401: ls->nfeval = 0;
402: ls->ngeval = 0;
403: ls->nfgeval = 0;
404: ls->ops->setup = NULL;
405: ls->ops->apply = NULL;
406: ls->ops->view = NULL;
407: ls->ops->setfromoptions = NULL;
408: ls->ops->destroy = NULL;
409: ls->setupcalled = PETSC_FALSE;
410: PetscCall((*r)(ls));
411: PetscCall(PetscObjectChangeTypeName((PetscObject)ls, type));
412: PetscFunctionReturn(PETSC_SUCCESS);
413: }
415: /*@C
416: TaoLineSearchMonitor - Monitor the line search steps. This routine will output the
417: iteration number, step length, and function value before calling the implementation
418: specific monitor.
420: Input Parameters:
421: + ls - the `TaoLineSearch` context
422: . its - the current iterate number (>=0)
423: . f - the current objective function value
424: - step - the step length
426: Options Database Key:
427: . -tao_ls_monitor - Use the default monitor, which prints statistics to standard output
429: Level: developer
431: .seealso: `TaoLineSearch`
432: @*/
433: PetscErrorCode TaoLineSearchMonitor(TaoLineSearch ls, PetscInt its, PetscReal f, PetscReal step)
434: {
435: PetscInt tabs;
437: PetscFunctionBegin;
439: if (ls->usemonitor) {
440: PetscCall(PetscViewerASCIIGetTab(ls->viewer, &tabs));
441: PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel));
442: PetscCall(PetscViewerASCIIPrintf(ls->viewer, "%3" PetscInt_FMT " LS", its));
443: PetscCall(PetscViewerASCIIPrintf(ls->viewer, " Function value: %g,", (double)f));
444: PetscCall(PetscViewerASCIIPrintf(ls->viewer, " Step length: %g\n", (double)step));
445: if (ls->ops->monitor && its > 0) {
446: PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel + 3));
447: PetscUseTypeMethod(ls, monitor);
448: }
449: PetscCall(PetscViewerASCIISetTab(ls->viewer, tabs));
450: }
451: PetscFunctionReturn(PETSC_SUCCESS);
452: }
454: /*@
455: TaoLineSearchSetFromOptions - Sets various `TaoLineSearch` parameters from user
456: options.
458: Collective
460: Input Parameter:
461: . ls - the `TaoLineSearch` context
463: Options Database Keys:
464: + -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use
465: . -tao_ls_ftol tol - tolerance for sufficient decrease
466: . -tao_ls_gtol tol - tolerance for curvature condition
467: . -tao_ls_rtol tol - relative tolerance for acceptable step
468: . -tao_ls_stepinit step - initial steplength allowed
469: . -tao_ls_stepmin step - minimum steplength allowed
470: . -tao_ls_stepmax step - maximum steplength allowed
471: . -tao_ls_max_funcs n - maximum number of function evaluations allowed
472: - -tao_ls_view - display line-search results
474: Level: beginner
476: .seealso: `Tao`, `TaoLineSearch`, `TaoGetLineSearch()`
477: @*/
478: PetscErrorCode TaoLineSearchSetFromOptions(TaoLineSearch ls)
479: {
480: const char *default_type = TAOLINESEARCHMT;
481: char type[256], monfilename[PETSC_MAX_PATH_LEN];
482: PetscViewer monviewer;
483: PetscBool flg;
485: PetscFunctionBegin;
487: PetscObjectOptionsBegin((PetscObject)ls);
488: if (((PetscObject)ls)->type_name) default_type = ((PetscObject)ls)->type_name;
489: /* Check for type from options */
490: PetscCall(PetscOptionsFList("-tao_ls_type", "Tao Line Search type", "TaoLineSearchSetType", TaoLineSearchList, default_type, type, 256, &flg));
491: if (flg) {
492: PetscCall(TaoLineSearchSetType(ls, type));
493: } else if (!((PetscObject)ls)->type_name) {
494: PetscCall(TaoLineSearchSetType(ls, default_type));
495: }
497: PetscCall(PetscOptionsInt("-tao_ls_max_funcs", "max function evals in line search", "", ls->max_funcs, &ls->max_funcs, NULL));
498: PetscCall(PetscOptionsReal("-tao_ls_ftol", "tol for sufficient decrease", "", ls->ftol, &ls->ftol, NULL));
499: PetscCall(PetscOptionsReal("-tao_ls_gtol", "tol for curvature condition", "", ls->gtol, &ls->gtol, NULL));
500: PetscCall(PetscOptionsReal("-tao_ls_rtol", "relative tol for acceptable step", "", ls->rtol, &ls->rtol, NULL));
501: PetscCall(PetscOptionsReal("-tao_ls_stepmin", "lower bound for step", "", ls->stepmin, &ls->stepmin, NULL));
502: PetscCall(PetscOptionsReal("-tao_ls_stepmax", "upper bound for step", "", ls->stepmax, &ls->stepmax, NULL));
503: PetscCall(PetscOptionsReal("-tao_ls_stepinit", "initial step", "", ls->initstep, &ls->initstep, NULL));
504: PetscCall(PetscOptionsString("-tao_ls_monitor", "enable the basic monitor", "TaoLineSearchSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg));
505: if (flg) {
506: PetscCall(PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ls), monfilename, &monviewer));
507: ls->viewer = monviewer;
508: ls->usemonitor = PETSC_TRUE;
509: }
510: PetscTryTypeMethod(ls, setfromoptions, PetscOptionsObject);
511: PetscOptionsEnd();
512: PetscFunctionReturn(PETSC_SUCCESS);
513: }
515: /*@
516: TaoLineSearchGetType - Gets the current line search algorithm
518: Not Collective
520: Input Parameter:
521: . ls - the `TaoLineSearch` context
523: Output Parameter:
524: . type - the line search algorithm in effect
526: Level: developer
528: Note:
529: `type` should not be retained for later use as it will be an invalid pointer if the `TaoLineSearchType` of `ls` is changed.
531: .seealso: `TaoLineSearch`, `TaoLineSearchSetType()`, `TaoLineSearchType`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`
532: @*/
533: PetscErrorCode TaoLineSearchGetType(TaoLineSearch ls, TaoLineSearchType *type)
534: {
535: PetscFunctionBegin;
537: PetscAssertPointer(type, 2);
538: *type = ((PetscObject)ls)->type_name;
539: PetscFunctionReturn(PETSC_SUCCESS);
540: }
542: /*@
543: TaoLineSearchGetNumberFunctionEvaluations - Gets the number of function and gradient evaluation
544: routines used by the line search in last application (not cumulative).
546: Not Collective
548: Input Parameter:
549: . ls - the `TaoLineSearch` context
551: Output Parameters:
552: + nfeval - number of function evaluations
553: . ngeval - number of gradient evaluations
554: - nfgeval - number of function/gradient evaluations
556: Level: intermediate
558: Note:
559: If the line search is using the `Tao` objective and gradient
560: routines directly (see `TaoLineSearchUseTaoRoutines()`), then the `Tao`
561: is already counting the number of evaluations.
563: .seealso: `TaoLineSearch`
564: @*/
565: PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval)
566: {
567: PetscFunctionBegin;
569: *nfeval = ls->nfeval;
570: *ngeval = ls->ngeval;
571: *nfgeval = ls->nfgeval;
572: PetscFunctionReturn(PETSC_SUCCESS);
573: }
575: /*@
576: TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using
577: the standard `Tao` evaluation routines.
579: Not Collective
581: Input Parameter:
582: . ls - the `TaoLineSearch` context
584: Output Parameter:
585: . flg - `PETSC_TRUE` if the line search is using `Tao` evaluation routines,
586: otherwise `PETSC_FALSE`
588: Level: developer
590: .seealso: `TaoLineSearch`
591: @*/
592: PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg)
593: {
594: PetscFunctionBegin;
596: *flg = ls->usetaoroutines;
597: PetscFunctionReturn(PETSC_SUCCESS);
598: }
600: /*@C
601: TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search
603: Logically Collective
605: Input Parameters:
606: + ls - the `TaoLineSearch` context
607: . func - the objective function evaluation routine
608: - ctx - the (optional) user-defined context for private data
610: Calling sequence of `func`:
611: + ls - the line search context
612: . x - input vector
613: . f - function value
614: - ctx - (optional) user-defined context
616: Level: advanced
618: Notes:
619: Use this routine only if you want the line search objective
620: evaluation routine to be different from the `Tao`'s objective
621: evaluation routine. If you use this routine you must also set
622: the line search gradient and/or function/gradient routine.
624: Some algorithms (lcl, gpcg) set their own objective routine for the
625: line search, application programmers should be wary of overriding the
626: default objective routine.
628: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
629: @*/
630: PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, PetscCtx ctx), PetscCtx ctx)
631: {
632: PetscFunctionBegin;
635: ls->ops->computeobjective = func;
636: if (ctx) ls->userctx_func = ctx;
637: ls->usetaoroutines = PETSC_FALSE;
638: PetscFunctionReturn(PETSC_SUCCESS);
639: }
641: /*@C
642: TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search
644: Logically Collective
646: Input Parameters:
647: + ls - the `TaoLineSearch` context
648: . func - the gradient evaluation routine
649: - ctx - the (optional) user-defined context for private data
651: Calling sequence of `func`:
652: + ls - the linesearch object
653: . x - input vector
654: . g - gradient vector
655: - ctx - (optional) user-defined context
657: Level: beginner
659: Note:
660: Use this routine only if you want the line search gradient
661: evaluation routine to be different from the `Tao`'s gradient
662: evaluation routine. If you use this routine you must also set
663: the line search function and/or function/gradient routine.
665: Some algorithms (lcl, gpcg) set their own gradient routine for the
666: line search, application programmers should be wary of overriding the
667: default gradient routine.
669: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
670: @*/
671: PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec g, PetscCtx ctx), PetscCtx ctx)
672: {
673: PetscFunctionBegin;
675: ls->ops->computegradient = func;
676: if (ctx) ls->userctx_grad = ctx;
677: ls->usetaoroutines = PETSC_FALSE;
678: PetscFunctionReturn(PETSC_SUCCESS);
679: }
681: /*@C
682: TaoLineSearchSetObjectiveAndGradientRoutine - Sets the objective/gradient evaluation routine for the line search
684: Logically Collective
686: Input Parameters:
687: + ls - the `TaoLineSearch` context
688: . func - the objective and gradient evaluation routine
689: - ctx - the (optional) user-defined context for private data
691: Calling sequence of `func`:
692: + ls - the linesearch object
693: . x - input vector
694: . f - function value
695: . g - gradient vector
696: - ctx - (optional) user-defined context
698: Level: beginner
700: Note:
701: Use this routine only if you want the line search objective and gradient
702: evaluation routines to be different from the `Tao`'s objective
703: and gradient evaluation routines.
705: Some algorithms (lcl, gpcg) set their own objective routine for the
706: line search, application programmers should be wary of overriding the
707: default objective routine.
709: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
710: @*/
711: PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscCtx ctx), PetscCtx ctx)
712: {
713: PetscFunctionBegin;
715: ls->ops->computeobjectiveandgradient = func;
716: if (ctx) ls->userctx_funcgrad = ctx;
717: ls->usetaoroutines = PETSC_FALSE;
718: PetscFunctionReturn(PETSC_SUCCESS);
719: }
721: /*@C
722: TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and
723: (gradient'*stepdirection) evaluation routine for the line search.
725: Logically Collective
727: Input Parameters:
728: + ls - the `TaoLineSearch` context
729: . func - the objective and gradient evaluation routine
730: - ctx - the (optional) user-defined context for private data
732: Calling sequence of `func`:
733: + ls - the linesearch context
734: . x - input vector
735: . s - step direction
736: . f - function value
737: . gts - inner product of gradient and step direction vectors
738: - ctx - (optional) user-defined context
740: Level: advanced
742: Notes:
743: Sometimes it is more efficient to compute the inner product of the gradient and the step
744: direction than it is to compute the gradient, and this is all the line search typically needs
745: of the gradient.
747: The gradient will still need to be computed at the end of the line
748: search, so you will still need to set a line search gradient evaluation
749: routine
751: Bounded line searches (those used in bounded optimization algorithms)
752: don't use g's directly, but rather (g'x - g'x0)/steplength. You can get the
753: x0 and steplength with `TaoLineSearchGetStartingVector()` and `TaoLineSearchGetStepLength()`
755: Some algorithms (lcl, gpcg) set their own objective routine for the
756: line search, application programmers should be wary of overriding the
757: default objective routine.
759: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjective()`, `TaoLineSearchSetGradient()`, `TaoLineSearchUseTaoRoutines()`
760: @*/
761: PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *f, PetscReal *gts, PetscCtx ctx), PetscCtx ctx)
762: {
763: PetscFunctionBegin;
765: ls->ops->computeobjectiveandgts = func;
766: if (ctx) ls->userctx_funcgts = ctx;
767: ls->usegts = PETSC_TRUE;
768: ls->usetaoroutines = PETSC_FALSE;
769: PetscFunctionReturn(PETSC_SUCCESS);
770: }
772: /*@
773: TaoLineSearchUseTaoRoutines - Informs the `TaoLineSearch` to use the
774: objective and gradient evaluation routines from the given `Tao` object. The default.
776: Logically Collective
778: Input Parameters:
779: + ls - the `TaoLineSearch` context
780: - ts - the `Tao` context with defined objective/gradient evaluation routines
782: Level: developer
784: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`
785: @*/
786: PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts)
787: {
788: PetscFunctionBegin;
791: ls->tao = ts;
792: ls->usetaoroutines = PETSC_TRUE;
793: PetscFunctionReturn(PETSC_SUCCESS);
794: }
796: /*@
797: TaoLineSearchComputeObjective - Computes the objective function value at a given point
799: Collective
801: Input Parameters:
802: + ls - the `TaoLineSearch` context
803: - x - input vector
805: Output Parameter:
806: . f - Objective value at `x`
808: Level: developer
810: Note:
811: `TaoLineSearchComputeObjective()` is typically used within line searches
812: so most users would not generally call this routine themselves.
814: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
815: @*/
816: PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f)
817: {
818: Vec gdummy;
819: PetscReal gts;
821: PetscFunctionBegin;
824: PetscAssertPointer(f, 3);
825: PetscCheckSameComm(ls, 1, x, 2);
826: if (ls->usetaoroutines) {
827: PetscCall(TaoComputeObjective(ls->tao, x, f));
828: } else {
829: 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");
830: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
831: if (ls->ops->computeobjective) PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
832: else if (ls->ops->computeobjectiveandgradient) {
833: PetscCall(VecDuplicate(x, &gdummy));
834: PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgradient)(ls, x, f, gdummy, ls->userctx_funcgrad));
835: PetscCall(VecDestroy(&gdummy));
836: } else PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, >s, ls->userctx_funcgts));
837: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
838: }
839: ls->nfeval++;
840: PetscFunctionReturn(PETSC_SUCCESS);
841: }
843: /*@
844: TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point
846: Collective
848: Input Parameters:
849: + ls - the `TaoLineSearch` context
850: - x - input vector
852: Output Parameters:
853: + f - Objective value at `x`
854: - g - Gradient vector at `x`
856: Level: developer
858: Note:
859: `TaoLineSearchComputeObjectiveAndGradient()` is typically used within line searches
860: so most users would not generally call this routine themselves.
862: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchSetObjectiveRoutine()`
863: @*/
864: PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g)
865: {
866: PetscFunctionBegin;
869: PetscAssertPointer(f, 3);
871: PetscCheckSameComm(ls, 1, x, 2);
872: PetscCheckSameComm(ls, 1, g, 4);
873: if (ls->usetaoroutines) {
874: PetscCall(TaoComputeObjectiveAndGradient(ls->tao, x, f, g));
875: } else {
876: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
877: if (ls->ops->computeobjectiveandgradient) PetscCallBack("TaoLineSearch callback objective/gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, f, g, ls->userctx_funcgrad));
878: else {
879: PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
880: PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
881: }
882: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
883: PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
884: }
885: ls->nfgeval++;
886: PetscFunctionReturn(PETSC_SUCCESS);
887: }
889: /*@
890: TaoLineSearchComputeGradient - Computes the gradient of the objective function
892: Collective
894: Input Parameters:
895: + ls - the `TaoLineSearch` context
896: - x - input vector
898: Output Parameter:
899: . g - gradient vector
901: Level: developer
903: Note:
904: `TaoComputeGradient()` is typically used within line searches
905: so most users would not generally call this routine themselves.
907: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeObjective()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetGradient()`
908: @*/
909: PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g)
910: {
911: PetscReal fdummy;
913: PetscFunctionBegin;
917: PetscCheckSameComm(ls, 1, x, 2);
918: PetscCheckSameComm(ls, 1, g, 3);
919: if (ls->usetaoroutines) {
920: PetscCall(TaoComputeGradient(ls->tao, x, g));
921: } else {
922: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
923: if (ls->ops->computegradient) PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
924: else PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, &fdummy, g, ls->userctx_funcgrad));
925: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
926: }
927: ls->ngeval++;
928: PetscFunctionReturn(PETSC_SUCCESS);
929: }
931: /*@
932: TaoLineSearchComputeObjectiveAndGTS - Computes the objective function value and inner product of gradient and
933: step direction at a given point
935: Collective
937: Input Parameters:
938: + ls - the `TaoLineSearch` context
939: - x - input vector
941: Output Parameters:
942: + f - Objective value at `x`
943: - gts - inner product of gradient and step direction at `x`
945: Level: developer
947: Note:
948: `TaoLineSearchComputeObjectiveAndGTS()` is typically used within line searches
949: so most users would not generally call this routine themselves.
951: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
952: @*/
953: PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts)
954: {
955: PetscFunctionBegin;
958: PetscAssertPointer(f, 3);
959: PetscAssertPointer(gts, 4);
960: PetscCheckSameComm(ls, 1, x, 2);
961: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
962: PetscCallBack("TaoLineSearch callback objective/gts", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, gts, ls->userctx_funcgts));
963: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
964: PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
965: ls->nfeval++;
966: PetscFunctionReturn(PETSC_SUCCESS);
967: }
969: /*@
970: TaoLineSearchGetSolution - Returns the solution to the line search
972: Collective
974: Input Parameter:
975: . ls - the `TaoLineSearch` context
977: Output Parameters:
978: + x - the new solution
979: . f - the objective function value at `x`
980: . g - the gradient at `x`
981: . steplength - the multiple of the step direction taken by the line search
982: - reason - the reason why the line search terminated
984: Level: developer
986: .seealso: `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
987: @*/
988: PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
989: {
990: PetscFunctionBegin;
993: PetscAssertPointer(f, 3);
995: PetscAssertPointer(reason, 6);
996: if (ls->new_x) PetscCall(VecCopy(ls->new_x, x));
997: *f = ls->new_f;
998: if (ls->new_g) PetscCall(VecCopy(ls->new_g, g));
999: if (steplength) *steplength = ls->step;
1000: *reason = ls->reason;
1001: PetscFunctionReturn(PETSC_SUCCESS);
1002: }
1004: /*@
1005: TaoLineSearchGetStartingVector - Gets a the initial point of the line
1006: search.
1008: Not Collective
1010: Input Parameter:
1011: . ls - the `TaoLineSearch` context
1013: Output Parameter:
1014: . x - The initial point of the line search
1016: Level: advanced
1018: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStepDirection()`
1019: @*/
1020: PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x)
1021: {
1022: PetscFunctionBegin;
1024: if (x) *x = ls->start_x;
1025: PetscFunctionReturn(PETSC_SUCCESS);
1026: }
1028: /*@
1029: TaoLineSearchGetStepDirection - Gets the step direction of the line
1030: search.
1032: Not Collective
1034: Input Parameter:
1035: . ls - the `TaoLineSearch` context
1037: Output Parameter:
1038: . s - the step direction of the line search
1040: Level: advanced
1042: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`
1043: @*/
1044: PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s)
1045: {
1046: PetscFunctionBegin;
1048: if (s) *s = ls->stepdirection;
1049: PetscFunctionReturn(PETSC_SUCCESS);
1050: }
1052: /*@
1053: TaoLineSearchGetFullStepObjective - Returns the objective function value at the full step. Useful for some minimization algorithms.
1055: Not Collective
1057: Input Parameter:
1058: . ls - the `TaoLineSearch` context
1060: Output Parameter:
1061: . f_fullstep - the objective value at the full step length
1063: Level: developer
1065: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
1066: @*/
1067: PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep)
1068: {
1069: PetscFunctionBegin;
1071: *f_fullstep = ls->f_fullstep;
1072: PetscFunctionReturn(PETSC_SUCCESS);
1073: }
1075: /*@
1076: TaoLineSearchSetVariableBounds - Sets the upper and lower bounds for a bounded line search
1078: Logically Collective
1080: Input Parameters:
1081: + ls - the `TaoLineSearch` context
1082: . xl - vector of lower bounds
1083: - xu - vector of upper bounds
1085: Level: beginner
1087: Note:
1088: If the variable bounds are not set with this routine, then
1089: `PETSC_NINFINITY` and `PETSC_INFINITY` are assumed
1091: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoSetVariableBounds()`, `TaoLineSearchCreate()`
1092: @*/
1093: PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls, Vec xl, Vec xu)
1094: {
1095: PetscFunctionBegin;
1099: PetscCall(PetscObjectReference((PetscObject)xl));
1100: PetscCall(PetscObjectReference((PetscObject)xu));
1101: PetscCall(VecDestroy(&ls->lower));
1102: PetscCall(VecDestroy(&ls->upper));
1103: ls->lower = xl;
1104: ls->upper = xu;
1105: ls->bounded = (PetscBool)(xl || xu);
1106: PetscFunctionReturn(PETSC_SUCCESS);
1107: }
1109: /*@
1110: TaoLineSearchSetInitialStepLength - Sets the initial step length of a line
1111: search. If this value is not set then 1.0 is assumed.
1113: Logically Collective
1115: Input Parameters:
1116: + ls - the `TaoLineSearch` context
1117: - s - the initial step size
1119: Level: intermediate
1121: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchGetStepLength()`, `TaoLineSearchApply()`
1122: @*/
1123: PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls, PetscReal s)
1124: {
1125: PetscFunctionBegin;
1128: ls->initstep = s;
1129: PetscFunctionReturn(PETSC_SUCCESS);
1130: }
1132: /*@
1133: TaoLineSearchGetStepLength - Get the current step length
1135: Not Collective
1137: Input Parameter:
1138: . ls - the `TaoLineSearch` context
1140: Output Parameter:
1141: . s - the current step length
1143: Level: intermediate
1145: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetInitialStepLength()`, `TaoLineSearchApply()`
1146: @*/
1147: PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls, PetscReal *s)
1148: {
1149: PetscFunctionBegin;
1151: *s = ls->step;
1152: PetscFunctionReturn(PETSC_SUCCESS);
1153: }
1155: /*@C
1156: TaoLineSearchRegister - Adds a line-search algorithm to the registry
1158: Not Collective, No Fortran Support
1160: Input Parameters:
1161: + sname - name of a new user-defined solver
1162: - func - routine to Create method context
1164: Calling sequence of `func`:
1165: . ls - the `TaoLineSearch` object to set with the `TaoLineSearchType` specific structure
1167: Example Usage:
1168: .vb
1169: TaoLineSearchRegister("my_linesearch", MyLinesearchCreate);
1170: .ve
1172: Then, your solver can be chosen with the procedural interface via
1173: .vb
1174: TaoLineSearchSetType(ls, "my_linesearch")
1175: .ve
1176: or at runtime via the option
1177: .vb
1178: -tao_ls_type my_linesearch
1179: .ve
1181: Level: developer
1183: Note:
1184: `TaoLineSearchRegister()` may be called multiple times to add several user-defined solvers.
1186: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`
1187: @*/
1188: PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch ls))
1189: {
1190: PetscFunctionBegin;
1191: PetscCall(TaoLineSearchInitializePackage());
1192: PetscCall(PetscFunctionListAdd(&TaoLineSearchList, sname, func));
1193: PetscFunctionReturn(PETSC_SUCCESS);
1194: }
1196: /*@
1197: TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching
1198: for all `TaoLineSearch` options in the database.
1200: Collective
1202: Input Parameters:
1203: + ls - the `TaoLineSearch` solver context
1204: - p - the prefix string to prepend to all line search requests
1206: Level: advanced
1208: Notes:
1209: A hyphen (-) must NOT be given at the beginning of the prefix name.
1210: The first character of all runtime options is AUTOMATICALLY the hyphen.
1212: This is inherited from the `Tao` object so rarely needs to be set
1214: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1215: @*/
1216: PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[])
1217: {
1218: return PetscObjectAppendOptionsPrefix((PetscObject)ls, p);
1219: }
1221: /*@
1222: TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1223: `TaoLineSearch` options in the database
1225: Not Collective
1227: Input Parameter:
1228: . ls - the `TaoLineSearch` context
1230: Output Parameter:
1231: . p - pointer to the prefix string used is returned
1233: Level: advanced
1235: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchAppendOptionsPrefix()`
1236: @*/
1237: PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[])
1238: {
1239: return PetscObjectGetOptionsPrefix((PetscObject)ls, p);
1240: }
1242: /*@
1243: TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all
1244: `TaoLineSearch` options in the database.
1246: Logically Collective
1248: Input Parameters:
1249: + ls - the `TaoLineSearch` context
1250: - p - the prefix string to prepend to all `ls` option requests
1252: Level: advanced
1254: Notes:
1255: A hyphen (-) must NOT be given at the beginning of the prefix name.
1256: The first character of all runtime options is AUTOMATICALLY the hyphen.
1258: This is inherited from the `Tao` object so rarely needs to be set
1260: For example, to distinguish between the runtime options for two
1261: different line searches, one could call
1262: .vb
1263: TaoLineSearchSetOptionsPrefix(ls1,"sys1_")
1264: TaoLineSearchSetOptionsPrefix(ls2,"sys2_")
1265: .ve
1267: This would enable use of different options for each system, such as
1268: .vb
1269: -sys1_tao_ls_type mt
1270: -sys2_tao_ls_type armijo
1271: .ve
1273: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchAppendOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1274: @*/
1275: PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[])
1276: {
1277: return PetscObjectSetOptionsPrefix((PetscObject)ls, p);
1278: }