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 `TaoLineSearch` context
21: . obj - optional object that provides the prefix for the option names, pass `NULL` to use the options prefix of `A`
22: - name - command line option
24: Options Database Key:
25: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`
27: Level: intermediate
29: Note:
30: This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
31: rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.
33: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchView()`, `PetscObjectViewFromOptions()`, `TaoLineSearchCreate()`, `PetscOptionsCreateViewer()`
34: @*/
35: PetscErrorCode TaoLineSearchViewFromOptions(TaoLineSearch A, PetscObject obj, const char name[])
36: {
37: PetscFunctionBegin;
39: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
40: PetscFunctionReturn(PETSC_SUCCESS);
41: }
43: /*@
44: TaoLineSearchView - Prints information about the `TaoLineSearch`
46: Collective
48: Input Parameters:
49: + ls - the `TaoLineSearch` context
50: - viewer - visualization context
52: Options Database Key:
53: . -tao_ls_view - Calls `TaoLineSearchView()` at the end of each line search
55: Level: beginner
57: Notes:
58: The available visualization contexts include
59: + `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
60: - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
61: output where only the first processor opens
62: the file. All other processors send their
63: data to the first processor to print.
65: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `PetscViewerASCIIOpen()`, `TaoLineSearchViewFromOptions()`
66: @*/
67: PetscErrorCode TaoLineSearchView(TaoLineSearch ls, PetscViewer viewer)
68: {
69: PetscBool isascii, isstring;
70: TaoLineSearchType type;
72: PetscFunctionBegin;
74: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(((PetscObject)ls)->comm, &viewer));
76: PetscCheckSameComm(ls, 1, viewer, 2);
78: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
79: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
80: if (isascii) {
81: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ls, viewer));
82: PetscCall(PetscViewerASCIIPushTab(viewer));
83: PetscTryTypeMethod(ls, view, viewer);
84: PetscCall(PetscViewerASCIIPopTab(viewer));
85: PetscCall(PetscViewerASCIIPushTab(viewer));
86: PetscCall(PetscViewerASCIIPrintf(viewer, "maximum function evaluations=%" PetscInt_FMT "\n", ls->max_funcs));
87: PetscCall(PetscViewerASCIIPrintf(viewer, "tolerances: ftol=%g, rtol=%g, gtol=%g\n", (double)ls->ftol, (double)ls->rtol, (double)ls->gtol));
88: PetscCall(PetscViewerASCIIPrintf(viewer, "total number of function evaluations=%" PetscInt_FMT "\n", ls->nfeval));
89: PetscCall(PetscViewerASCIIPrintf(viewer, "total number of gradient evaluations=%" PetscInt_FMT "\n", ls->ngeval));
90: PetscCall(PetscViewerASCIIPrintf(viewer, "total number of function/gradient evaluations=%" PetscInt_FMT "\n", ls->nfgeval));
92: if (ls->bounded) PetscCall(PetscViewerASCIIPrintf(viewer, "using variable bounds\n"));
93: PetscCall(PetscViewerASCIIPrintf(viewer, "Termination reason: %s\n", TaoLineSearchConvergedReasons[ls->reason]));
94: PetscCall(PetscViewerASCIIPopTab(viewer));
95: } else if (isstring) {
96: PetscCall(TaoLineSearchGetType(ls, &type));
97: PetscCall(PetscViewerStringSPrintf(viewer, " %-3.3s", type));
98: }
99: PetscFunctionReturn(PETSC_SUCCESS);
100: }
102: /*@
103: TaoLineSearchCreate - Creates a `TaoLineSearch` object. Algorithms in `Tao` that use
104: line-searches will automatically create one so this all is rarely needed
106: Collective
108: Input Parameter:
109: . comm - MPI communicator
111: Output Parameter:
112: . newls - the new `TaoLineSearch` context
114: Options Database Key:
115: . -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use
117: Level: developer
119: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchType`, `TaoLineSearchSetType()`, `TaoLineSearchApply()`, `TaoLineSearchDestroy()`
120: @*/
121: PetscErrorCode TaoLineSearchCreate(MPI_Comm comm, TaoLineSearch *newls)
122: {
123: TaoLineSearch ls;
125: PetscFunctionBegin;
126: PetscAssertPointer(newls, 2);
127: PetscCall(TaoLineSearchInitializePackage());
129: PetscCall(PetscHeaderCreate(ls, TAOLINESEARCH_CLASSID, "TaoLineSearch", "Linesearch", "Tao", comm, TaoLineSearchDestroy, TaoLineSearchView));
130: ls->max_funcs = 30;
131: ls->ftol = 0.0001;
132: ls->gtol = 0.9;
133: ls->rtol = PetscDefined(USE_REAL_SINGLE) ? 1.0e-5 : 1.0e-10;
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: ls->rtol = PetscDefined(USE_REAL_SINGLE) ? 1.0e-5 : 1.0e-10;
394: ls->stepmin = 1.0e-20;
395: ls->stepmax = 1.0e+20;
397: ls->nfeval = 0;
398: ls->ngeval = 0;
399: ls->nfgeval = 0;
400: ls->ops->setup = NULL;
401: ls->ops->apply = NULL;
402: ls->ops->view = NULL;
403: ls->ops->setfromoptions = NULL;
404: ls->ops->destroy = NULL;
405: ls->setupcalled = PETSC_FALSE;
406: PetscCall((*r)(ls));
407: PetscCall(PetscObjectChangeTypeName((PetscObject)ls, type));
408: PetscFunctionReturn(PETSC_SUCCESS);
409: }
411: /*@
412: TaoLineSearchMonitor - Monitor the line search steps. This routine will output the
413: iteration number, step length, and function value before calling the implementation
414: specific monitor.
416: Input Parameters:
417: + ls - the `TaoLineSearch` context
418: . its - the current iterate number (>=0)
419: . f - the current objective function value
420: - step - the step length
422: Options Database Key:
423: . -tao_ls_monitor - Use the default monitor, which prints statistics to standard output
425: Level: developer
427: .seealso: `TaoLineSearch`
428: @*/
429: PetscErrorCode TaoLineSearchMonitor(TaoLineSearch ls, PetscInt its, PetscReal f, PetscReal step)
430: {
431: PetscInt tabs;
433: PetscFunctionBegin;
435: if (ls->usemonitor) {
436: PetscCall(PetscViewerASCIIGetTab(ls->viewer, &tabs));
437: PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel));
438: PetscCall(PetscViewerASCIIPrintf(ls->viewer, "%3" PetscInt_FMT " LS", its));
439: PetscCall(PetscViewerASCIIPrintf(ls->viewer, " Function value: %g,", (double)f));
440: PetscCall(PetscViewerASCIIPrintf(ls->viewer, " Step length: %g\n", (double)step));
441: if (ls->ops->monitor && its > 0) {
442: PetscCall(PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel + 3));
443: PetscUseTypeMethod(ls, monitor);
444: }
445: PetscCall(PetscViewerASCIISetTab(ls->viewer, tabs));
446: }
447: PetscFunctionReturn(PETSC_SUCCESS);
448: }
450: /*@
451: TaoLineSearchSetFromOptions - Sets various `TaoLineSearch` parameters from user
452: options.
454: Collective
456: Input Parameter:
457: . ls - the `TaoLineSearch` context
459: Options Database Keys:
460: + -tao_ls_type (unit|more-thuente|gpcg|armijo|owarmijo|ipm) - select which line search `Tao` should use
461: . -tao_ls_ftol tol - tolerance for sufficient decrease
462: . -tao_ls_gtol tol - tolerance for curvature condition
463: . -tao_ls_rtol tol - relative tolerance for acceptable step
464: . -tao_ls_stepinit step - initial steplength allowed
465: . -tao_ls_stepmin step - minimum steplength allowed
466: . -tao_ls_stepmax step - maximum steplength allowed
467: . -tao_ls_max_funcs n - maximum number of function evaluations allowed
468: - -tao_ls_view - display line-search results
470: Level: beginner
472: .seealso: `Tao`, `TaoLineSearch`, `TaoGetLineSearch()`
473: @*/
474: PetscErrorCode TaoLineSearchSetFromOptions(TaoLineSearch ls)
475: {
476: const char *default_type = TAOLINESEARCHMT;
477: char type[256], monfilename[PETSC_MAX_PATH_LEN];
478: PetscViewer monviewer;
479: PetscBool flg;
481: PetscFunctionBegin;
483: PetscObjectOptionsBegin((PetscObject)ls);
484: if (((PetscObject)ls)->type_name) default_type = ((PetscObject)ls)->type_name;
485: /* Check for type from options */
486: PetscCall(PetscOptionsFList("-tao_ls_type", "Tao Line Search type", "TaoLineSearchSetType", TaoLineSearchList, default_type, type, sizeof(type), &flg));
487: if (flg) {
488: PetscCall(TaoLineSearchSetType(ls, type));
489: } else if (!((PetscObject)ls)->type_name) {
490: PetscCall(TaoLineSearchSetType(ls, default_type));
491: }
493: PetscCall(PetscOptionsInt("-tao_ls_max_funcs", "max function evals in line search", "", ls->max_funcs, &ls->max_funcs, NULL));
494: PetscCall(PetscOptionsReal("-tao_ls_ftol", "tol for sufficient decrease", "", ls->ftol, &ls->ftol, NULL));
495: PetscCall(PetscOptionsReal("-tao_ls_gtol", "tol for curvature condition", "", ls->gtol, &ls->gtol, NULL));
496: PetscCall(PetscOptionsReal("-tao_ls_rtol", "relative tol for acceptable step", "", ls->rtol, &ls->rtol, NULL));
497: PetscCall(PetscOptionsReal("-tao_ls_stepmin", "lower bound for step", "", ls->stepmin, &ls->stepmin, NULL));
498: PetscCall(PetscOptionsReal("-tao_ls_stepmax", "upper bound for step", "", ls->stepmax, &ls->stepmax, NULL));
499: PetscCall(PetscOptionsReal("-tao_ls_stepinit", "initial step", "", ls->initstep, &ls->initstep, NULL));
500: PetscCall(PetscOptionsString("-tao_ls_monitor", "enable the basic monitor", "TaoLineSearchSetMonitor", "stdout", monfilename, sizeof(monfilename), &flg));
501: if (flg) {
502: PetscCall(PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ls), monfilename, &monviewer));
503: ls->viewer = monviewer;
504: ls->usemonitor = PETSC_TRUE;
505: }
506: PetscTryTypeMethod(ls, setfromoptions, PetscOptionsObject);
507: PetscOptionsEnd();
508: PetscFunctionReturn(PETSC_SUCCESS);
509: }
511: /*@
512: TaoLineSearchGetType - Gets the current line search algorithm
514: Not Collective
516: Input Parameter:
517: . ls - the `TaoLineSearch` context
519: Output Parameter:
520: . type - the line search algorithm in effect
522: Level: developer
524: Note:
525: `type` should not be retained for later use as it will be an invalid pointer if the `TaoLineSearchType` of `ls` is changed.
527: .seealso: `TaoLineSearch`, `TaoLineSearchSetType()`, `TaoLineSearchType`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`
528: @*/
529: PetscErrorCode TaoLineSearchGetType(TaoLineSearch ls, TaoLineSearchType *type)
530: {
531: PetscFunctionBegin;
533: PetscAssertPointer(type, 2);
534: *type = ((PetscObject)ls)->type_name;
535: PetscFunctionReturn(PETSC_SUCCESS);
536: }
538: /*@
539: TaoLineSearchGetNumberFunctionEvaluations - Gets the number of function and gradient evaluation
540: routines used by the line search in last application (not cumulative).
542: Not Collective
544: Input Parameter:
545: . ls - the `TaoLineSearch` context
547: Output Parameters:
548: + nfeval - number of function evaluations
549: . ngeval - number of gradient evaluations
550: - nfgeval - number of function/gradient evaluations
552: Level: intermediate
554: Note:
555: If the line search is using the `Tao` objective and gradient
556: routines directly (see `TaoLineSearchUseTaoRoutines()`), then the `Tao`
557: is already counting the number of evaluations.
559: .seealso: `TaoLineSearch`
560: @*/
561: PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval)
562: {
563: PetscFunctionBegin;
565: *nfeval = ls->nfeval;
566: *ngeval = ls->ngeval;
567: *nfgeval = ls->nfgeval;
568: PetscFunctionReturn(PETSC_SUCCESS);
569: }
571: /*@
572: TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using
573: the standard `Tao` evaluation routines.
575: Not Collective
577: Input Parameter:
578: . ls - the `TaoLineSearch` context
580: Output Parameter:
581: . flg - `PETSC_TRUE` if the line search is using `Tao` evaluation routines,
582: otherwise `PETSC_FALSE`
584: Level: developer
586: .seealso: `TaoLineSearch`
587: @*/
588: PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg)
589: {
590: PetscFunctionBegin;
592: *flg = ls->usetaoroutines;
593: PetscFunctionReturn(PETSC_SUCCESS);
594: }
596: /*@
597: TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search
599: Logically Collective
601: Input Parameters:
602: + ls - the `TaoLineSearch` context
603: . func - the objective function evaluation routine
604: - ctx - the (optional) user-defined context for private data
606: Calling sequence of `func`:
607: + ls - the line search context
608: . x - input vector
609: . f - function value
610: - ctx - (optional) user-defined context
612: Level: advanced
614: Notes:
615: Use this routine only if you want the line search objective
616: evaluation routine to be different from the `Tao`'s objective
617: evaluation routine. If you use this routine you must also set
618: the line search gradient and/or function/gradient routine.
620: Some algorithms (lcl, gpcg) set their own objective routine for the
621: line search, application programmers should be wary of overriding the
622: default objective routine.
624: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
625: @*/
626: PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, PetscCtx ctx), PetscCtx ctx)
627: {
628: PetscFunctionBegin;
631: ls->ops->computeobjective = func;
632: if (ctx) ls->userctx_func = ctx;
633: ls->usetaoroutines = PETSC_FALSE;
634: PetscFunctionReturn(PETSC_SUCCESS);
635: }
637: /*@
638: TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search
640: Logically Collective
642: Input Parameters:
643: + ls - the `TaoLineSearch` context
644: . func - the gradient evaluation routine
645: - ctx - the (optional) user-defined context for private data
647: Calling sequence of `func`:
648: + ls - the linesearch object
649: . x - input vector
650: . g - gradient vector
651: - ctx - (optional) user-defined context
653: Level: beginner
655: Note:
656: Use this routine only if you want the line search gradient
657: evaluation routine to be different from the `Tao`'s gradient
658: evaluation routine. If you use this routine you must also set
659: the line search function and/or function/gradient routine.
661: Some algorithms (lcl, gpcg) set their own gradient routine for the
662: line search, application programmers should be wary of overriding the
663: default gradient routine.
665: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetObjectiveAndGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
666: @*/
667: PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec g, PetscCtx ctx), PetscCtx ctx)
668: {
669: PetscFunctionBegin;
671: ls->ops->computegradient = func;
672: if (ctx) ls->userctx_grad = ctx;
673: ls->usetaoroutines = PETSC_FALSE;
674: PetscFunctionReturn(PETSC_SUCCESS);
675: }
677: /*@
678: TaoLineSearchSetObjectiveAndGradientRoutine - Sets the objective/gradient evaluation routine for the line search
680: Logically Collective
682: Input Parameters:
683: + ls - the `TaoLineSearch` context
684: . func - the objective and gradient evaluation routine
685: - ctx - the (optional) user-defined context for private data
687: Calling sequence of `func`:
688: + ls - the linesearch object
689: . x - input vector
690: . f - function value
691: . g - gradient vector
692: - ctx - (optional) user-defined context
694: Level: beginner
696: Note:
697: Use this routine only if you want the line search objective and gradient
698: evaluation routines to be different from the `Tao`'s objective
699: and gradient evaluation routines.
701: Some algorithms (lcl, gpcg) set their own objective routine for the
702: line search, application programmers should be wary of overriding the
703: default objective routine.
705: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjectiveRoutine()`, `TaoLineSearchSetGradientRoutine()`, `TaoLineSearchUseTaoRoutines()`
706: @*/
707: PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscCtx ctx), PetscCtx ctx)
708: {
709: PetscFunctionBegin;
711: ls->ops->computeobjectiveandgradient = func;
712: if (ctx) ls->userctx_funcgrad = ctx;
713: ls->usetaoroutines = PETSC_FALSE;
714: PetscFunctionReturn(PETSC_SUCCESS);
715: }
717: /*@
718: TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and
719: (gradient'*stepdirection) evaluation routine for the line search.
721: Logically Collective
723: Input Parameters:
724: + ls - the `TaoLineSearch` context
725: . func - the objective and gradient evaluation routine
726: - ctx - the (optional) user-defined context for private data
728: Calling sequence of `func`:
729: + ls - the linesearch context
730: . x - input vector
731: . s - step direction
732: . f - function value
733: . gts - inner product of gradient and step direction vectors
734: - ctx - (optional) user-defined context
736: Level: advanced
738: Notes:
739: Sometimes it is more efficient to compute the inner product of the gradient and the step
740: direction than it is to compute the gradient, and this is all the line search typically needs
741: of the gradient.
743: The gradient will still need to be computed at the end of the line
744: search, so you will still need to set a line search gradient evaluation
745: routine
747: Bounded line searches (those used in bounded optimization algorithms)
748: don't use g's directly, but rather (g'x - g'x0)/steplength. You can get the
749: x0 and steplength with `TaoLineSearchGetStartingVector()` and `TaoLineSearchGetStepLength()`
751: Some algorithms (lcl, gpcg) set their own objective routine for the
752: line search, application programmers should be wary of overriding the
753: default objective routine.
755: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`, `TaoLineSearchSetObjective()`, `TaoLineSearchSetGradient()`, `TaoLineSearchUseTaoRoutines()`
756: @*/
757: PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode (*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *f, PetscReal *gts, PetscCtx ctx), PetscCtx ctx)
758: {
759: PetscFunctionBegin;
761: ls->ops->computeobjectiveandgts = func;
762: if (ctx) ls->userctx_funcgts = ctx;
763: ls->usegts = PETSC_TRUE;
764: ls->usetaoroutines = PETSC_FALSE;
765: PetscFunctionReturn(PETSC_SUCCESS);
766: }
768: /*@
769: TaoLineSearchUseTaoRoutines - Informs the `TaoLineSearch` to use the
770: objective and gradient evaluation routines from the given `Tao` object. The default.
772: Logically Collective
774: Input Parameters:
775: + ls - the `TaoLineSearch` context
776: - ts - the `Tao` context with defined objective/gradient evaluation routines
778: Level: developer
780: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchCreate()`
781: @*/
782: PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts)
783: {
784: PetscFunctionBegin;
787: ls->tao = ts;
788: ls->usetaoroutines = PETSC_TRUE;
789: PetscFunctionReturn(PETSC_SUCCESS);
790: }
792: /*@
793: TaoLineSearchComputeObjective - Computes the objective function value at a given point
795: Collective
797: Input Parameters:
798: + ls - the `TaoLineSearch` context
799: - x - input vector
801: Output Parameter:
802: . f - Objective value at `x`
804: Level: developer
806: Note:
807: `TaoLineSearchComputeObjective()` is typically used within line searches
808: so most users would not generally call this routine themselves.
810: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
811: @*/
812: PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f)
813: {
814: Vec gdummy;
815: PetscReal gts;
817: PetscFunctionBegin;
820: PetscAssertPointer(f, 3);
821: PetscCheckSameComm(ls, 1, x, 2);
822: if (ls->usetaoroutines) {
823: PetscCall(TaoComputeObjective(ls->tao, x, f));
824: } else {
825: 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");
826: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
827: if (ls->ops->computeobjective) PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
828: else if (ls->ops->computeobjectiveandgradient) {
829: PetscCall(VecDuplicate(x, &gdummy));
830: PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgradient)(ls, x, f, gdummy, ls->userctx_funcgrad));
831: PetscCall(VecDestroy(&gdummy));
832: } else PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, >s, ls->userctx_funcgts));
833: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
834: }
835: ls->nfeval++;
836: PetscFunctionReturn(PETSC_SUCCESS);
837: }
839: /*@
840: TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point
842: Collective
844: Input Parameters:
845: + ls - the `TaoLineSearch` context
846: - x - input vector
848: Output Parameters:
849: + f - Objective value at `x`
850: - g - Gradient vector at `x`
852: Level: developer
854: Note:
855: `TaoLineSearchComputeObjectiveAndGradient()` is typically used within line searches
856: so most users would not generally call this routine themselves.
858: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchSetObjectiveRoutine()`
859: @*/
860: PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g)
861: {
862: PetscFunctionBegin;
865: PetscAssertPointer(f, 3);
867: PetscCheckSameComm(ls, 1, x, 2);
868: PetscCheckSameComm(ls, 1, g, 4);
869: if (ls->usetaoroutines) {
870: PetscCall(TaoComputeObjectiveAndGradient(ls->tao, x, f, g));
871: } else {
872: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
873: if (ls->ops->computeobjectiveandgradient) PetscCallBack("TaoLineSearch callback objective/gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, f, g, ls->userctx_funcgrad));
874: else {
875: PetscCallBack("TaoLineSearch callback objective", (*ls->ops->computeobjective)(ls, x, f, ls->userctx_func));
876: PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
877: }
878: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
879: PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
880: }
881: ls->nfgeval++;
882: PetscFunctionReturn(PETSC_SUCCESS);
883: }
885: /*@
886: TaoLineSearchComputeGradient - Computes the gradient of the objective function
888: Collective
890: Input Parameters:
891: + ls - the `TaoLineSearch` context
892: - x - input vector
894: Output Parameter:
895: . g - gradient vector
897: Level: developer
899: Note:
900: `TaoComputeGradient()` is typically used within line searches
901: so most users would not generally call this routine themselves.
903: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeObjective()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetGradient()`
904: @*/
905: PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g)
906: {
907: PetscReal fdummy;
909: PetscFunctionBegin;
913: PetscCheckSameComm(ls, 1, x, 2);
914: PetscCheckSameComm(ls, 1, g, 3);
915: if (ls->usetaoroutines) {
916: PetscCall(TaoComputeGradient(ls->tao, x, g));
917: } else {
918: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
919: if (ls->ops->computegradient) PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computegradient)(ls, x, g, ls->userctx_grad));
920: else PetscCallBack("TaoLineSearch callback gradient", (*ls->ops->computeobjectiveandgradient)(ls, x, &fdummy, g, ls->userctx_funcgrad));
921: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
922: }
923: ls->ngeval++;
924: PetscFunctionReturn(PETSC_SUCCESS);
925: }
927: /*@
928: TaoLineSearchComputeObjectiveAndGTS - Computes the objective function value and inner product of gradient and
929: step direction at a given point
931: Collective
933: Input Parameters:
934: + ls - the `TaoLineSearch` context
935: - x - input vector
937: Output Parameters:
938: + f - Objective value at `x`
939: - gts - inner product of gradient and step direction at `x`
941: Level: developer
943: Note:
944: `TaoLineSearchComputeObjectiveAndGTS()` is typically used within line searches
945: so most users would not generally call this routine themselves.
947: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchComputeGradient()`, `TaoLineSearchComputeObjectiveAndGradient()`, `TaoLineSearchSetObjectiveRoutine()`
948: @*/
949: PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts)
950: {
951: PetscFunctionBegin;
954: PetscAssertPointer(f, 3);
955: PetscAssertPointer(gts, 4);
956: PetscCheckSameComm(ls, 1, x, 2);
957: PetscCall(PetscLogEventBegin(TAOLINESEARCH_Eval, ls, 0, 0, 0));
958: PetscCallBack("TaoLineSearch callback objective/gts", (*ls->ops->computeobjectiveandgts)(ls, x, ls->stepdirection, f, gts, ls->userctx_funcgts));
959: PetscCall(PetscLogEventEnd(TAOLINESEARCH_Eval, ls, 0, 0, 0));
960: PetscCall(PetscInfo(ls, "TaoLineSearch Function evaluation: %14.12e\n", (double)(*f)));
961: ls->nfeval++;
962: PetscFunctionReturn(PETSC_SUCCESS);
963: }
965: /*@
966: TaoLineSearchGetSolution - Returns the solution to the line search
968: Collective
970: Input Parameter:
971: . ls - the `TaoLineSearch` context
973: Output Parameters:
974: + x - the new solution
975: . f - the objective function value at `x`
976: . g - the gradient at `x`
977: . steplength - the multiple of the step direction taken by the line search
978: - reason - the reason why the line search terminated
980: Level: developer
982: .seealso: `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
983: @*/
984: PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
985: {
986: PetscFunctionBegin;
989: PetscAssertPointer(f, 3);
991: PetscAssertPointer(reason, 6);
992: if (ls->new_x) PetscCall(VecCopy(ls->new_x, x));
993: *f = ls->new_f;
994: if (ls->new_g) PetscCall(VecCopy(ls->new_g, g));
995: if (steplength) *steplength = ls->step;
996: *reason = ls->reason;
997: PetscFunctionReturn(PETSC_SUCCESS);
998: }
1000: /*@
1001: TaoLineSearchGetStartingVector - Gets a the initial point of the line
1002: search.
1004: Not Collective
1006: Input Parameter:
1007: . ls - the `TaoLineSearch` context
1009: Output Parameter:
1010: . x - The initial point of the line search
1012: Level: advanced
1014: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStepDirection()`
1015: @*/
1016: PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x)
1017: {
1018: PetscFunctionBegin;
1020: if (x) *x = ls->start_x;
1021: PetscFunctionReturn(PETSC_SUCCESS);
1022: }
1024: /*@
1025: TaoLineSearchGetStepDirection - Gets the step direction of the line
1026: search.
1028: Not Collective
1030: Input Parameter:
1031: . ls - the `TaoLineSearch` context
1033: Output Parameter:
1034: . s - the step direction of the line search
1036: Level: advanced
1038: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`
1039: @*/
1040: PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s)
1041: {
1042: PetscFunctionBegin;
1044: if (s) *s = ls->stepdirection;
1045: PetscFunctionReturn(PETSC_SUCCESS);
1046: }
1048: /*@
1049: TaoLineSearchGetFullStepObjective - Returns the objective function value at the full step. Useful for some minimization algorithms.
1051: Not Collective
1053: Input Parameter:
1054: . ls - the `TaoLineSearch` context
1056: Output Parameter:
1057: . f_fullstep - the objective value at the full step length
1059: Level: developer
1061: .seealso: `TaoLineSearchGetSolution()`, `TaoLineSearchGetStartingVector()`, `TaoLineSearchGetStepDirection()`
1062: @*/
1063: PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep)
1064: {
1065: PetscFunctionBegin;
1067: *f_fullstep = ls->f_fullstep;
1068: PetscFunctionReturn(PETSC_SUCCESS);
1069: }
1071: /*@
1072: TaoLineSearchSetVariableBounds - Sets the upper and lower bounds for a bounded line search
1074: Logically Collective
1076: Input Parameters:
1077: + ls - the `TaoLineSearch` context
1078: . xl - vector of lower bounds
1079: - xu - vector of upper bounds
1081: Level: beginner
1083: Note:
1084: If the variable bounds are not set with this routine, then
1085: `PETSC_NINFINITY` and `PETSC_INFINITY` are assumed
1087: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoSetVariableBounds()`, `TaoLineSearchCreate()`
1088: @*/
1089: PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls, Vec xl, Vec xu)
1090: {
1091: PetscFunctionBegin;
1095: PetscCall(PetscObjectReference((PetscObject)xl));
1096: PetscCall(PetscObjectReference((PetscObject)xu));
1097: PetscCall(VecDestroy(&ls->lower));
1098: PetscCall(VecDestroy(&ls->upper));
1099: ls->lower = xl;
1100: ls->upper = xu;
1101: ls->bounded = (PetscBool)(xl || xu);
1102: PetscFunctionReturn(PETSC_SUCCESS);
1103: }
1105: /*@
1106: TaoLineSearchSetInitialStepLength - Sets the initial step length of a line
1107: search. If this value is not set then 1.0 is assumed.
1109: Logically Collective
1111: Input Parameters:
1112: + ls - the `TaoLineSearch` context
1113: - s - the initial step size
1115: Level: intermediate
1117: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchGetStepLength()`, `TaoLineSearchApply()`
1118: @*/
1119: PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls, PetscReal s)
1120: {
1121: PetscFunctionBegin;
1124: ls->initstep = s;
1125: PetscFunctionReturn(PETSC_SUCCESS);
1126: }
1128: /*@
1129: TaoLineSearchGetStepLength - Get the current step length
1131: Not Collective
1133: Input Parameter:
1134: . ls - the `TaoLineSearch` context
1136: Output Parameter:
1137: . s - the current step length
1139: Level: intermediate
1141: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetInitialStepLength()`, `TaoLineSearchApply()`
1142: @*/
1143: PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls, PetscReal *s)
1144: {
1145: PetscFunctionBegin;
1147: *s = ls->step;
1148: PetscFunctionReturn(PETSC_SUCCESS);
1149: }
1151: /*@
1152: TaoLineSearchRegister - Adds a line-search algorithm to the registry
1154: Not Collective, No Fortran Support
1156: Input Parameters:
1157: + sname - name of a new user-defined solver
1158: - func - routine to Create method context
1160: Calling sequence of `func`:
1161: . ls - the `TaoLineSearch` object to set with the `TaoLineSearchType` specific structure
1163: Example Usage:
1164: .vb
1165: TaoLineSearchRegister("my_linesearch", MyLinesearchCreate);
1166: .ve
1168: Then, your solver can be chosen with the procedural interface via
1169: .vb
1170: TaoLineSearchSetType(ls, "my_linesearch")
1171: .ve
1172: or at runtime via the option
1173: .vb
1174: -tao_ls_type my_linesearch
1175: .ve
1177: Level: developer
1179: Note:
1180: `TaoLineSearchRegister()` may be called multiple times to add several user-defined solvers.
1182: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`
1183: @*/
1184: PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch ls))
1185: {
1186: PetscFunctionBegin;
1187: PetscCall(TaoLineSearchInitializePackage());
1188: PetscCall(PetscFunctionListAdd(&TaoLineSearchList, sname, func));
1189: PetscFunctionReturn(PETSC_SUCCESS);
1190: }
1192: /*@
1193: TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching
1194: for all `TaoLineSearch` options in the database.
1196: Collective
1198: Input Parameters:
1199: + ls - the `TaoLineSearch` solver context
1200: - p - the prefix string to prepend to all line search requests
1202: Level: advanced
1204: Notes:
1205: A hyphen (-) must NOT be given at the beginning of the prefix name.
1206: The first character of all runtime options is AUTOMATICALLY the hyphen.
1208: This is inherited from the `Tao` object so rarely needs to be set
1210: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1211: @*/
1212: PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[])
1213: {
1214: return PetscObjectAppendOptionsPrefix((PetscObject)ls, p);
1215: }
1217: /*@
1218: TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1219: `TaoLineSearch` options in the database
1221: Not Collective
1223: Input Parameter:
1224: . ls - the `TaoLineSearch` context
1226: Output Parameter:
1227: . p - pointer to the prefix string used is returned
1229: Level: advanced
1231: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchSetOptionsPrefix()`, `TaoLineSearchAppendOptionsPrefix()`
1232: @*/
1233: PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[])
1234: {
1235: return PetscObjectGetOptionsPrefix((PetscObject)ls, p);
1236: }
1238: /*@
1239: TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all
1240: `TaoLineSearch` options in the database.
1242: Logically Collective
1244: Input Parameters:
1245: + ls - the `TaoLineSearch` context
1246: - p - the prefix string to prepend to all `ls` option requests
1248: Level: advanced
1250: Notes:
1251: A hyphen (-) must NOT be given at the beginning of the prefix name.
1252: The first character of all runtime options is AUTOMATICALLY the hyphen.
1254: This is inherited from the `Tao` object so rarely needs to be set
1256: For example, to distinguish between the runtime options for two
1257: different line searches, one could call
1258: .vb
1259: TaoLineSearchSetOptionsPrefix(ls1,"sys1_")
1260: TaoLineSearchSetOptionsPrefix(ls2,"sys2_")
1261: .ve
1263: This would enable use of different options for each system, such as
1264: .vb
1265: -sys1_tao_ls_type mt
1266: -sys2_tao_ls_type armijo
1267: .ve
1269: .seealso: [](ch_tao), `Tao`, `TaoLineSearch`, `TaoLineSearchAppendOptionsPrefix()`, `TaoLineSearchGetOptionsPrefix()`
1270: @*/
1271: PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[])
1272: {
1273: return PetscObjectSetOptionsPrefix((PetscObject)ls, p);
1274: }