Date: 2022-08-02T03:15:15+00:00

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: /*@C
     12:    TaoLineSearchViewFromOptions - View from Options

     14:    Collective on TaoLineSearch

     16:    Input Parameters:
     17: +  A - the Tao context
     18: .  obj - Optional object
     19: -  name - command line option

     21:    Level: intermediate
     22: .seealso:  TaoLineSearch, TaoLineSearchView, PetscObjectViewFromOptions(), TaoLineSearchCreate()
     23: @*/
     24: PetscErrorCode TaoLineSearchViewFromOptions(TaoLineSearch A,PetscObject obj,const char name[])
     25: {
     27:   PetscObjectViewFromOptions((PetscObject)A,obj,name);
     28:   return 0;
     29: }

     31: /*@C
     32:   TaoLineSearchView - Prints information about the TaoLineSearch

     34:   Collective on TaoLineSearch

     36:   InputParameters:
     37: + ls - the Tao context
     38: - viewer - visualization context

     40:   Options Database Key:
     41: . -tao_ls_view - Calls TaoLineSearchView() at the end of each line search

     43:   Notes:
     44:   The available visualization contexts include
     45: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
     46: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
     47:          output where only the first processor opens
     48:          the file.  All other processors send their
     49:          data to the first processor to print.

     51:   Level: beginner

     53: .seealso: PetscViewerASCIIOpen()
     54: @*/

     56: PetscErrorCode TaoLineSearchView(TaoLineSearch ls, PetscViewer viewer)
     57: {
     58:   PetscBool               isascii, isstring;
     59:   TaoLineSearchType       type;

     62:   if (!viewer) {
     63:     PetscViewerASCIIGetStdout(((PetscObject)ls)->comm, &viewer);
     64:   }

     68:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
     69:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
     70:   if (isascii) {
     71:     PetscObjectPrintClassNamePrefixType((PetscObject)ls, viewer);
     72:     if (ls->ops->view) {
     73:       PetscViewerASCIIPushTab(viewer);
     74:       (*ls->ops->view)(ls,viewer);
     75:       PetscViewerASCIIPopTab(viewer);
     76:     }
     77:     PetscViewerASCIIPushTab(viewer);
     78:     PetscViewerASCIIPrintf(viewer,"maximum function evaluations=%D\n",ls->max_funcs);
     79:     PetscViewerASCIIPrintf(viewer,"tolerances: ftol=%g, rtol=%g, gtol=%g\n",(double)ls->ftol,(double)ls->rtol,(double)ls->gtol);
     80:     PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D\n",ls->nfeval);
     81:     PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D\n",ls->ngeval);
     82:     PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D\n",ls->nfgeval);

     84:     if (ls->bounded) {
     85:       PetscViewerASCIIPrintf(viewer,"using variable bounds\n");
     86:     }
     87:     PetscViewerASCIIPrintf(viewer,"Termination reason: %d\n",(int)ls->reason);
     88:     PetscViewerASCIIPopTab(viewer);
     89:   } else if (isstring) {
     90:     TaoLineSearchGetType(ls,&type);
     91:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
     92:   }
     93:   return 0;
     94: }

     96: /*@C
     97:   TaoLineSearchCreate - Creates a TAO Line Search object.  Algorithms in TAO that use
     98:   line-searches will automatically create one.

    100:   Collective

    102:   Input Parameter:
    103: . comm - MPI communicator

    105:   Output Parameter:
    106: . newls - the new TaoLineSearch context

    108:   Available methods include:
    109: + more-thuente - the More-Thuente method
    110: . gpcg - the GPCG method
    111: - unit - Do not perform any line search

    113:    Options Database Keys:
    114: .   -tao_ls_type - select which method TAO should use

    116:    Level: beginner

    118: .seealso: TaoLineSearchSetType(), TaoLineSearchApply(), TaoLineSearchDestroy()
    119: @*/

    121: PetscErrorCode TaoLineSearchCreate(MPI_Comm comm, TaoLineSearch *newls)
    122: {
    123:   TaoLineSearch  ls;

    126:   *newls = NULL;

    128:   TaoLineSearchInitializePackage();

    130:   PetscHeaderCreate(ls,TAOLINESEARCH_CLASSID,"TaoLineSearch","Linesearch","Tao",comm,TaoLineSearchDestroy,TaoLineSearchView);
    131:   ls->bounded = 0;
    132:   ls->max_funcs=30;
    133:   ls->ftol = 0.0001;
    134:   ls->gtol = 0.9;
    135: #if defined(PETSC_USE_REAL_SINGLE)
    136:   ls->rtol = 1.0e-5;
    137: #else
    138:   ls->rtol = 1.0e-10;
    139: #endif
    140:   ls->stepmin=1.0e-20;
    141:   ls->stepmax=1.0e+20;
    142:   ls->step=1.0;
    143:   ls->nfeval=0;
    144:   ls->ngeval=0;
    145:   ls->nfgeval=0;

    147:   ls->ops->computeobjective = NULL;
    148:   ls->ops->computegradient = NULL;
    149:   ls->ops->computeobjectiveandgradient = NULL;
    150:   ls->ops->computeobjectiveandgts = NULL;
    151:   ls->ops->setup = NULL;
    152:   ls->ops->apply = NULL;
    153:   ls->ops->view = NULL;
    154:   ls->ops->setfromoptions = NULL;
    155:   ls->ops->reset = NULL;
    156:   ls->ops->destroy = NULL;
    157:   ls->ops->monitor = NULL;
    158:   ls->usemonitor=PETSC_FALSE;
    159:   ls->setupcalled=PETSC_FALSE;
    160:   ls->usetaoroutines=PETSC_FALSE;
    161:   *newls = ls;
    162:   return 0;
    163: }

    165: /*@
    166:   TaoLineSearchSetUp - Sets up the internal data structures for the later use
    167:   of a Tao solver

    169:   Collective on ls

    171:   Input Parameters:
    172: . ls - the TaoLineSearch context

    174:   Notes:
    175:   The user will not need to explicitly call TaoLineSearchSetUp(), as it will
    176:   automatically be called in TaoLineSearchSolve().  However, if the user
    177:   desires to call it explicitly, it should come after TaoLineSearchCreate()
    178:   but before TaoLineSearchApply().

    180:   Level: developer

    182: .seealso: TaoLineSearchCreate(), TaoLineSearchApply()
    183: @*/

    185: PetscErrorCode TaoLineSearchSetUp(TaoLineSearch ls)
    186: {
    187:   const char     *default_type=TAOLINESEARCHMT;
    188:   PetscBool      flg;

    191:   if (ls->setupcalled) return 0;
    192:   if (!((PetscObject)ls)->type_name) {
    193:     TaoLineSearchSetType(ls,default_type);
    194:   }
    195:   if (ls->ops->setup) {
    196:     (*ls->ops->setup)(ls);
    197:   }
    198:   if (ls->usetaoroutines) {
    199:     TaoIsObjectiveDefined(ls->tao,&flg);
    200:     ls->hasobjective = flg;
    201:     TaoIsGradientDefined(ls->tao,&flg);
    202:     ls->hasgradient = flg;
    203:     TaoIsObjectiveAndGradientDefined(ls->tao,&flg);
    204:     ls->hasobjectiveandgradient = flg;
    205:   } else {
    206:     if (ls->ops->computeobjective) {
    207:       ls->hasobjective = PETSC_TRUE;
    208:     } else {
    209:       ls->hasobjective = PETSC_FALSE;
    210:     }
    211:     if (ls->ops->computegradient) {
    212:       ls->hasgradient = PETSC_TRUE;
    213:     } else {
    214:       ls->hasgradient = PETSC_FALSE;
    215:     }
    216:     if (ls->ops->computeobjectiveandgradient) {
    217:       ls->hasobjectiveandgradient = PETSC_TRUE;
    218:     } else {
    219:       ls->hasobjectiveandgradient = PETSC_FALSE;
    220:     }
    221:   }
    222:   ls->setupcalled = PETSC_TRUE;
    223:   return 0;
    224: }

    226: /*@
    227:   TaoLineSearchReset - Some line searches may carry state information
    228:   from one TaoLineSearchApply() to the next.  This function resets this
    229:   state information.

    231:   Collective on TaoLineSearch

    233:   Input Parameter:
    234: . ls - the TaoLineSearch context

    236:   Level: developer

    238: .seealso: TaoLineSearchCreate(), TaoLineSearchApply()
    239: @*/
    240: PetscErrorCode TaoLineSearchReset(TaoLineSearch ls)
    241: {
    243:   if (ls->ops->reset) {
    244:     (*ls->ops->reset)(ls);
    245:   }
    246:   return 0;
    247: }

    249: /*@
    250:   TaoLineSearchDestroy - Destroys the TAO context that was created with
    251:   TaoLineSearchCreate()

    253:   Collective on TaoLineSearch

    255:   Input Parameter:
    256: . ls - the TaoLineSearch context

    258:   Level: beginner

    260: .seealse: TaoLineSearchCreate(), TaoLineSearchSolve()
    261: @*/
    262: PetscErrorCode TaoLineSearchDestroy(TaoLineSearch *ls)
    263: {
    264:   if (!*ls) return 0;
    266:   if (--((PetscObject)*ls)->refct > 0) {*ls = NULL; return 0;}
    267:   VecDestroy(&(*ls)->stepdirection);
    268:   VecDestroy(&(*ls)->start_x);
    269:   VecDestroy(&(*ls)->upper);
    270:   VecDestroy(&(*ls)->lower);
    271:   if ((*ls)->ops->destroy) {
    272:     (*(*ls)->ops->destroy)(*ls);
    273:   }
    274:   if ((*ls)->usemonitor) {
    275:     PetscViewerDestroy(&(*ls)->viewer);
    276:   }
    277:   PetscHeaderDestroy(ls);
    278:   return 0;
    279: }

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

    284:   Collective on TaoLineSearch

    286:   Input Parameters:
    287: + ls - the Tao context
    288: - s - search direction

    290:   Input/Output Parameters:

    292:   Output Parameters:
    293: + x - On input the current solution, on output x contains the new solution determined by the line search
    294: . f - On input the objective function value at current solution, on output contains the objective function value at new solution
    295: . g - On input the gradient evaluated at x, on output contains the gradient at new solution
    296: . steplength - scalar multiplier of s used ( x = x0 + steplength * x)
    297: - reason - reason why the line-search stopped

    299:   Notes:
    300:   reason will be set to one of:

    302: + TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction
    303: . TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value
    304: . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter
    305: . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached
    306: . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound
    307: . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound
    308: . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance
    309: . TAOLINESEARCH_HALTED_USER - user can set this reason to stop line search
    310: . TAOLINESEARCH_HALTED_OTHER - any other reason
    311: - TAOLINESEARCH_SUCCESS - successful line search

    313:   The algorithm developer must set up the TaoLineSearch with calls to
    314:   TaoLineSearchSetObjectiveRoutine() and TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), or TaoLineSearchUseTaoRoutines()

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

    320:   Level: beginner

    322:   .seealso: TaoLineSearchCreate(), TaoLineSearchSetType(), TaoLineSearchSetInitialStepLength(), TaoAddLineSearchCounts()
    323:  @*/

    325: PetscErrorCode TaoLineSearchApply(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
    326: {
    327:   PetscInt       low1,low2,low3,high1,high2,high3;

    338:   VecGetOwnershipRange(x, &low1, &high1);
    339:   VecGetOwnershipRange(g, &low2, &high2);
    340:   VecGetOwnershipRange(s, &low3, &high3);

    343:   *reason = TAOLINESEARCH_CONTINUE_ITERATING;
    344:   PetscObjectReference((PetscObject)s);
    345:   VecDestroy(&ls->stepdirection);
    346:   ls->stepdirection = s;

    348:   TaoLineSearchSetUp(ls);
    350:   ls->nfeval = 0;
    351:   ls->ngeval = 0;
    352:   ls->nfgeval = 0;
    353:   /* Check parameter values */
    354:   if (ls->ftol < 0.0) {
    355:     PetscInfo(ls,"Bad Line Search Parameter: ftol (%g) < 0\n",(double)ls->ftol);
    356:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    357:   }
    358:   if (ls->rtol < 0.0) {
    359:     PetscInfo(ls,"Bad Line Search Parameter: rtol (%g) < 0\n",(double)ls->rtol);
    360:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    361:   }
    362:   if (ls->gtol < 0.0) {
    363:     PetscInfo(ls,"Bad Line Search Parameter: gtol (%g) < 0\n",(double)ls->gtol);
    364:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    365:   }
    366:   if (ls->stepmin < 0.0) {
    367:     PetscInfo(ls,"Bad Line Search Parameter: stepmin (%g) < 0\n",(double)ls->stepmin);
    368:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    369:   }
    370:   if (ls->stepmax < ls->stepmin) {
    371:     PetscInfo(ls,"Bad Line Search Parameter: stepmin (%g) > stepmax (%g)\n",(double)ls->stepmin,(double)ls->stepmax);
    372:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    373:   }
    374:   if (ls->max_funcs < 0) {
    375:     PetscInfo(ls,"Bad Line Search Parameter: max_funcs (%" PetscInt_FMT ") < 0\n",ls->max_funcs);
    376:     *reason = TAOLINESEARCH_FAILED_BADPARAMETER;
    377:   }
    378:   if (PetscIsInfOrNanReal(*f)) {
    379:     PetscInfo(ls,"Initial Line Search Function Value is Inf or Nan (%g)\n",(double)*f);
    380:     *reason = TAOLINESEARCH_FAILED_INFORNAN;
    381:   }

    383:   PetscObjectReference((PetscObject)x);
    384:   VecDestroy(&ls->start_x);
    385:   ls->start_x = x;

    387:   PetscLogEventBegin(TAOLINESEARCH_Apply,ls,0,0,0);
    388:   (*ls->ops->apply)(ls,x,f,g,s);
    389:   PetscLogEventEnd(TAOLINESEARCH_Apply, ls, 0,0,0);
    390:   *reason = ls->reason;
    391:   ls->new_f = *f;

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

    395:   TaoLineSearchViewFromOptions(ls,NULL,"-tao_ls_view");
    396:   return 0;
    397: }

    399: /*@C
    400:    TaoLineSearchSetType - Sets the algorithm used in a line search

    402:    Collective on TaoLineSearch

    404:    Input Parameters:
    405: +  ls - the TaoLineSearch context
    406: -  type - the TaoLineSearchType selection

    408:   Available methods include:
    409: +  more-thuente - line search with a cubic model enforcing the strong Wolfe/curvature condition
    410: .  armijo - simple backtracking line search enforcing only the sufficient decrease condition
    411: -  unit - do not perform a line search and always accept unit step length

    413:   Options Database Keys:
    414: .  -tao_ls_type <more-thuente, armijo, unit> - select which method TAO should use at runtime

    416:   Level: beginner

    418: .seealso: TaoLineSearchCreate(), TaoLineSearchGetType(), TaoLineSearchApply()

    420: @*/

    422: PetscErrorCode TaoLineSearchSetType(TaoLineSearch ls, TaoLineSearchType type)
    423: {
    424:   PetscErrorCode (*r)(TaoLineSearch);
    425:   PetscBool      flg;

    429:   PetscObjectTypeCompare((PetscObject)ls, type, &flg);
    430:   if (flg) return 0;

    432:   PetscFunctionListFind(TaoLineSearchList,type, (void (**)(void)) &r);
    434:   if (ls->ops->destroy) {
    435:     (*(ls)->ops->destroy)(ls);
    436:   }
    437:   ls->max_funcs = 30;
    438:   ls->ftol = 0.0001;
    439:   ls->gtol = 0.9;
    440: #if defined(PETSC_USE_REAL_SINGLE)
    441:   ls->rtol = 1.0e-5;
    442: #else
    443:   ls->rtol = 1.0e-10;
    444: #endif
    445:   ls->stepmin = 1.0e-20;
    446:   ls->stepmax = 1.0e+20;

    448:   ls->nfeval = 0;
    449:   ls->ngeval = 0;
    450:   ls->nfgeval = 0;
    451:   ls->ops->setup = NULL;
    452:   ls->ops->apply = NULL;
    453:   ls->ops->view = NULL;
    454:   ls->ops->setfromoptions = NULL;
    455:   ls->ops->destroy = NULL;
    456:   ls->setupcalled = PETSC_FALSE;
    457:   (*r)(ls);
    458:   PetscObjectChangeTypeName((PetscObject)ls, type);
    459:   return 0;
    460: }

    462: /*@C
    463:   TaoLineSearchMonitor - Monitor the line search steps. This routine will otuput the
    464:   iteration number, step length, and function value before calling the implementation
    465:   specific monitor.

    467:    Input Parameters:
    468: +  ls - the TaoLineSearch context
    469: .  its - the current iterate number (>=0)
    470: .  f - the current objective function value
    471: -  step - the step length

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

    476:    Level: developer

    478: @*/
    479: PetscErrorCode TaoLineSearchMonitor(TaoLineSearch ls, PetscInt its, PetscReal f, PetscReal step)
    480: {
    481:   PetscInt       tabs;

    484:   if (ls->usemonitor) {
    485:     PetscViewerASCIIGetTab(ls->viewer, &tabs);
    486:     PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel);
    487:     PetscViewerASCIIPrintf(ls->viewer, "%3D LS", its);
    488:     PetscViewerASCIIPrintf(ls->viewer, "  Function value: %g,", (double)f);
    489:     PetscViewerASCIIPrintf(ls->viewer, "  Step length: %g\n", (double)step);
    490:     if (ls->ops->monitor && its > 0) {
    491:       PetscViewerASCIISetTab(ls->viewer, ((PetscObject)ls)->tablevel + 3);
    492:       (*ls->ops->monitor)(ls);
    493:     }
    494:     PetscViewerASCIISetTab(ls->viewer, tabs);
    495:   }
    496:   return 0;
    497: }

    499: /*@
    500:   TaoLineSearchSetFromOptions - Sets various TaoLineSearch parameters from user
    501:   options.

    503:   Collective on TaoLineSearch

    505:   Input Parameter:
    506: . ls - the TaoLineSearch context

    508:   Options Database Keys:
    509: + -tao_ls_type <type> - The algorithm that TAO uses (more-thuente, gpcg, unit)
    510: . -tao_ls_ftol <tol> - tolerance for sufficient decrease
    511: . -tao_ls_gtol <tol> - tolerance for curvature condition
    512: . -tao_ls_rtol <tol> - relative tolerance for acceptable step
    513: . -tao_ls_stepmin <step> - minimum steplength allowed
    514: . -tao_ls_stepmax <step> - maximum steplength allowed
    515: . -tao_ls_max_funcs <n> - maximum number of function evaluations allowed
    516: - -tao_ls_view - display line-search results to standard output

    518:   Level: beginner
    519: @*/
    520: PetscErrorCode TaoLineSearchSetFromOptions(TaoLineSearch ls)
    521: {
    523:   const char     *default_type=TAOLINESEARCHMT;
    524:   char           type[256],monfilename[PETSC_MAX_PATH_LEN];
    525:   PetscViewer    monviewer;
    526:   PetscBool      flg;

    529:   PetscObjectOptionsBegin((PetscObject)ls);
    530:   if (((PetscObject)ls)->type_name) {
    531:     default_type = ((PetscObject)ls)->type_name;
    532:   }
    533:   /* Check for type from options */
    534:   PetscOptionsFList("-tao_ls_type","Tao Line Search type","TaoLineSearchSetType",TaoLineSearchList,default_type,type,256,&flg);
    535:   if (flg) {
    536:     TaoLineSearchSetType(ls,type);
    537:   } else if (!((PetscObject)ls)->type_name) {
    538:     TaoLineSearchSetType(ls,default_type);
    539:   }

    541:   PetscOptionsInt("-tao_ls_max_funcs","max function evals in line search","",ls->max_funcs,&ls->max_funcs,NULL);
    542:   PetscOptionsReal("-tao_ls_ftol","tol for sufficient decrease","",ls->ftol,&ls->ftol,NULL);
    543:   PetscOptionsReal("-tao_ls_gtol","tol for curvature condition","",ls->gtol,&ls->gtol,NULL);
    544:   PetscOptionsReal("-tao_ls_rtol","relative tol for acceptable step","",ls->rtol,&ls->rtol,NULL);
    545:   PetscOptionsReal("-tao_ls_stepmin","lower bound for step","",ls->stepmin,&ls->stepmin,NULL);
    546:   PetscOptionsReal("-tao_ls_stepmax","upper bound for step","",ls->stepmax,&ls->stepmax,NULL);
    547:   PetscOptionsString("-tao_ls_monitor","enable the basic monitor","TaoLineSearchSetMonitor","stdout",monfilename,sizeof(monfilename),&flg);
    548:   if (flg) {
    549:     PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ls),monfilename,&monviewer);
    550:     ls->viewer = monviewer;
    551:     ls->usemonitor = PETSC_TRUE;
    552:   }
    553:   if (ls->ops->setfromoptions) {
    554:     (*ls->ops->setfromoptions)(PetscOptionsObject,ls);
    555:   }
    556:   PetscOptionsEnd();
    557:   return 0;
    558: }

    560: /*@C
    561:   TaoLineSearchGetType - Gets the current line search algorithm

    563:   Not Collective

    565:   Input Parameter:
    566: . ls - the TaoLineSearch context

    568:   Output Parameter:
    569: . type - the line search algorithm in effect

    571:   Level: developer

    573: @*/
    574: PetscErrorCode TaoLineSearchGetType(TaoLineSearch ls, TaoLineSearchType *type)
    575: {
    578:   *type = ((PetscObject)ls)->type_name;
    579:   return 0;
    580: }

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

    586:   Not Collective

    588:   Input Parameter:
    589: . ls - the TaoLineSearch context

    591:   Output Parameters:
    592: + nfeval   - number of function evaluations
    593: . ngeval   - number of gradient evaluations
    594: - nfgeval  - number of function/gradient evaluations

    596:   Level: intermediate

    598:   Note:
    599:   If the line search is using the Tao objective and gradient
    600:   routines directly (see TaoLineSearchUseTaoRoutines()), then TAO
    601:   is already counting the number of evaluations.

    603: @*/
    604: PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval)
    605: {
    607:   *nfeval = ls->nfeval;
    608:   *ngeval = ls->ngeval;
    609:   *nfgeval = ls->nfgeval;
    610:   return 0;
    611: }

    613: /*@
    614:   TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using
    615:   Tao evaluation routines.

    617:   Not Collective

    619:   Input Parameter:
    620: . ls - the TaoLineSearch context

    622:   Output Parameter:
    623: . flg - PETSC_TRUE if the line search is using Tao evaluation routines,
    624:         otherwise PETSC_FALSE

    626:   Level: developer
    627: @*/
    628: PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg)
    629: {
    631:   *flg = ls->usetaoroutines;
    632:   return 0;
    633: }

    635: /*@C
    636:   TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search

    638:   Logically Collective on TaoLineSearch

    640:   Input Parameters:
    641: + ls - the TaoLineSearch context
    642: . func - the objective function evaluation routine
    643: - ctx - the (optional) user-defined context for private data

    645:   Calling sequence of func:
    646: $      func (TaoLinesearch ls, Vec x, PetscReal *f, void *ctx);

    648: + x - input vector
    649: . f - function value
    650: - ctx (optional) user-defined context

    652:   Level: beginner

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

    660:   Note:
    661:   Some algorithms (lcl, gpcg) set their own objective routine for the
    662:   line search, application programmers should be wary of overriding the
    663:   default objective routine.

    665: .seealso: TaoLineSearchCreate(), TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines()
    666: @*/
    667: PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal*, void*), void *ctx)
    668: {

    671:   ls->ops->computeobjective=func;
    672:   if (ctx) ls->userctx_func=ctx;
    673:   ls->usetaoroutines=PETSC_FALSE;
    674:   return 0;
    675: }

    677: /*@C
    678:   TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search

    680:   Logically Collective on TaoLineSearch

    682:   Input Parameters:
    683: + ls - the TaoLineSearch context
    684: . func - the gradient evaluation routine
    685: - ctx - the (optional) user-defined context for private data

    687:   Calling sequence of func:
    688: $      func (TaoLinesearch ls, Vec x, Vec g, void *ctx);

    690: + x - input vector
    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 gradient
    698:   evaluation routine to be different from the Tao's gradient
    699:   evaluation routine. If you use this routine you must also set
    700:   the line search function and/or function/gradient routine.

    702:   Note:
    703:   Some algorithms (lcl, gpcg) set their own gradient routine for the
    704:   line search, application programmers should be wary of overriding the
    705:   default gradient routine.

    707: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines()
    708: @*/
    709: PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec g, void*), void *ctx)
    710: {
    712:   ls->ops->computegradient=func;
    713:   if (ctx) ls->userctx_grad=ctx;
    714:   ls->usetaoroutines=PETSC_FALSE;
    715:   return 0;
    716: }

    718: /*@C
    719:   TaoLineSearchSetObjectiveAndGradientRoutine - Sets the objective/gradient evaluation routine for the line search

    721:   Logically Collective on TaoLineSearch

    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: $      func (TaoLinesearch ls, Vec x, PetscReal *f, Vec g, void *ctx);

    731: + x - input vector
    732: . f - function value
    733: . g - gradient vector
    734: - ctx (optional) user-defined context

    736:   Level: beginner

    738:   Note:
    739:   Use this routine only if you want the line search objective and gradient
    740:   evaluation routines to be different from the Tao's objective
    741:   and gradient evaluation routines.

    743:   Note:
    744:   Some algorithms (lcl, gpcg) set their own objective routine for the
    745:   line search, application programmers should be wary of overriding the
    746:   default objective routine.

    748: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetGradientRoutine(), TaoLineSearchUseTaoRoutines()
    749: @*/
    750: PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal *, Vec g, void*), void *ctx)
    751: {
    753:   ls->ops->computeobjectiveandgradient=func;
    754:   if (ctx) ls->userctx_funcgrad=ctx;
    755:   ls->usetaoroutines = PETSC_FALSE;
    756:   return 0;
    757: }

    759: /*@C
    760:   TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and
    761:   (gradient'*stepdirection) evaluation routine for the line search.
    762:   Sometimes it is more efficient to compute the inner product of the gradient
    763:   and the step direction than it is to compute the gradient, and this is all
    764:   the line search typically needs of the gradient.

    766:   Logically Collective on TaoLineSearch

    768:   Input Parameters:
    769: + ls - the TaoLineSearch context
    770: . func - the objective and gradient evaluation routine
    771: - ctx - the (optional) user-defined context for private data

    773:   Calling sequence of func:
    774: $      func (TaoLinesearch ls, Vec x, PetscReal *f, PetscReal *gts, void *ctx);

    776: + x - input vector
    777: . s - step direction
    778: . f - function value
    779: . gts - inner product of gradient and step direction vectors
    780: - ctx (optional) user-defined context

    782:   Note: The gradient will still need to be computed at the end of the line
    783:   search, so you will still need to set a line search gradient evaluation
    784:   routine

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

    790:   Level: advanced

    792:   Note:
    793:   Some algorithms (lcl, gpcg) set their own objective routine for the
    794:   line search, application programmers should be wary of overriding the
    795:   default objective routine.

    797: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjective(), TaoLineSearchSetGradient(), TaoLineSearchUseTaoRoutines()
    798: @*/
    799: PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *, PetscReal *, void*), void *ctx)
    800: {
    802:   ls->ops->computeobjectiveandgts=func;
    803:   if (ctx) ls->userctx_funcgts=ctx;
    804:   ls->usegts = PETSC_TRUE;
    805:   ls->usetaoroutines = PETSC_FALSE;
    806:   return 0;
    807: }

    809: /*@C
    810:   TaoLineSearchUseTaoRoutines - Informs the TaoLineSearch to use the
    811:   objective and gradient evaluation routines from the given Tao object.

    813:   Logically Collective on TaoLineSearch

    815:   Input Parameters:
    816: + ls - the TaoLineSearch context
    817: - ts - the Tao context with defined objective/gradient evaluation routines

    819:   Level: developer

    821: .seealso: TaoLineSearchCreate()
    822: @*/
    823: PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts)
    824: {
    827:   ls->tao = ts;
    828:   ls->usetaoroutines = PETSC_TRUE;
    829:   return 0;
    830: }

    832: /*@
    833:   TaoLineSearchComputeObjective - Computes the objective function value at a given point

    835:   Collective on TaoLineSearch

    837:   Input Parameters:
    838: + ls - the TaoLineSearch context
    839: - x - input vector

    841:   Output Parameter:
    842: . f - Objective value at X

    844:   Notes:
    845:     TaoLineSearchComputeObjective() is typically used within line searches
    846:   so most users would not generally call this routine themselves.

    848:   Level: developer

    850: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
    851: @*/
    852: PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f)
    853: {
    854:   Vec            gdummy;
    855:   PetscReal      gts;

    861:   if (ls->usetaoroutines) {
    862:     TaoComputeObjective(ls->tao,x,f);
    863:   } else {
    865:     PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);
    866:     PetscStackPush("TaoLineSearch user objective routine");
    867:     if (ls->ops->computeobjective) {
    868:       (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);
    869:     } else if (ls->ops->computeobjectiveandgradient) {
    870:       VecDuplicate(x,&gdummy);
    871:       (*ls->ops->computeobjectiveandgradient)(ls,x,f,gdummy,ls->userctx_funcgrad);
    872:       VecDestroy(&gdummy);
    873:     } else {
    874:       (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,&gts,ls->userctx_funcgts);
    875:     }
    876:     PetscStackPop;
    877:     PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);
    878:   }
    879:   ls->nfeval++;
    880:   return 0;
    881: }

    883: /*@
    884:   TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point

    886:   Collective on Tao

    888:   Input Parameters:
    889: + ls - the TaoLineSearch context
    890: - x - input vector

    892:   Output Parameters:
    893: + f - Objective value at X
    894: - g - Gradient vector at X

    896:   Notes:
    897:     TaoLineSearchComputeObjectiveAndGradient() is typically used within line searches
    898:   so most users would not generally call this routine themselves.

    900:   Level: developer

    902: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
    903: @*/
    904: PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g)
    905: {
    912:   if (ls->usetaoroutines) {
    913:     TaoComputeObjectiveAndGradient(ls->tao,x,f,g);
    914:   } else {
    915:     PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);
    916:     if (ls->ops->computeobjectiveandgradient) {
    917:       PetscStackPush("TaoLineSearch user objective/gradient routine");
    918:       (*ls->ops->computeobjectiveandgradient)(ls,x,f,g,ls->userctx_funcgrad);
    919:       PetscStackPop;
    920:     } else {
    922:       PetscStackPush("TaoLineSearch user objective routine");
    923:       (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);
    924:       PetscStackPop;
    926:       PetscStackPush("TaoLineSearch user gradient routine");
    927:       (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);
    928:       PetscStackPop;
    929:     }
    930:     PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);
    931:     PetscInfo(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));
    932:   }
    933:   ls->nfgeval++;
    934:   return 0;
    935: }

    937: /*@
    938:   TaoLineSearchComputeGradient - Computes the gradient of the objective function

    940:   Collective on TaoLineSearch

    942:   Input Parameters:
    943: + ls - the TaoLineSearch context
    944: - x - input vector

    946:   Output Parameter:
    947: . g - gradient vector

    949:   Notes:
    950:     TaoComputeGradient() is typically used within line searches
    951:   so most users would not generally call this routine themselves.

    953:   Level: developer

    955: .seealso: TaoLineSearchComputeObjective(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetGradient()
    956: @*/
    957: PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g)
    958: {
    959:   PetscReal      fdummy;

    966:   if (ls->usetaoroutines) {
    967:     TaoComputeGradient(ls->tao,x,g);
    968:   } else {
    969:     PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);
    970:     PetscStackPush("TaoLineSearch user gradient routine");
    971:     if (ls->ops->computegradient) {
    972:       (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);
    973:     } else {
    975:       (*ls->ops->computeobjectiveandgradient)(ls,x,&fdummy,g,ls->userctx_funcgrad);
    976:     }
    977:     PetscStackPop;
    978:     PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);
    979:   }
    980:   ls->ngeval++;
    981:   return 0;
    982: }

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

    987:   Collective on Tao

    989:   Input Parameters:
    990: + ls - the TaoLineSearch context
    991: - x - input vector

    993:   Output Parameters:
    994: + f - Objective value at X
    995: - gts - inner product of gradient and step direction at X

    997:   Notes:
    998:     TaoLineSearchComputeObjectiveAndGTS() is typically used within line searches
    999:   so most users would not generally call this routine themselves.

    1001:   Level: developer

    1003: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
    1004: @*/
    1005: PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts)
    1006: {
    1013:   PetscLogEventBegin(TAOLINESEARCH_Eval,ls,0,0,0);
    1014:   PetscStackPush("TaoLineSearch user objective/gts routine");
    1015:   (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,gts,ls->userctx_funcgts);
    1016:   PetscStackPop;
    1017:   PetscLogEventEnd(TAOLINESEARCH_Eval,ls,0,0,0);
    1018:   PetscInfo(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));
    1019:   ls->nfeval++;
    1020:   return 0;
    1021: }

    1023: /*@
    1024:   TaoLineSearchGetSolution - Returns the solution to the line search

    1026:   Collective on TaoLineSearch

    1028:   Input Parameter:
    1029: . ls - the TaoLineSearch context

    1031:   Output Parameters:
    1032: + x - the new solution
    1033: . f - the objective function value at x
    1034: . g - the gradient at x
    1035: . steplength - the multiple of the step direction taken by the line search
    1036: - reason - the reason why the line search terminated

    1038:   reason will be set to one of:

    1040: + TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value
    1041: . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter
    1042: . TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction
    1043: . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached
    1044: . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound
    1045: . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound
    1046: . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance

    1048: . TAOLINESEARCH_HALTED_USER - user can set this reason to stop line search
    1049: . TAOLINESEARCH_HALTED_OTHER - any other reason

    1051: - TAOLINESEARCH_SUCCESS - successful line search

    1053:   Level: developer

    1055: @*/
    1056: PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchConvergedReason *reason)
    1057: {
    1063:   if (ls->new_x) {
    1064:     VecCopy(ls->new_x,x);
    1065:   }
    1066:   *f = ls->new_f;
    1067:   if (ls->new_g) {
    1068:     VecCopy(ls->new_g,g);
    1069:   }
    1070:   if (steplength) *steplength = ls->step;
    1071:   *reason = ls->reason;
    1072:   return 0;
    1073: }

    1075: /*@
    1076:   TaoLineSearchGetStartingVector - Gets a the initial point of the line
    1077:   search.

    1079:   Not Collective

    1081:   Input Parameter:
    1082: . ls - the TaoLineSearch context

    1084:   Output Parameter:
    1085: . x - The initial point of the line search

    1087:   Level: intermediate
    1088: @*/
    1089: PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x)
    1090: {
    1092:   if (x) *x = ls->start_x;
    1093:   return 0;
    1094: }

    1096: /*@
    1097:   TaoLineSearchGetStepDirection - Gets the step direction of the line
    1098:   search.

    1100:   Not Collective

    1102:   Input Parameter:
    1103: . ls - the TaoLineSearch context

    1105:   Output Parameter:
    1106: . s - the step direction of the line search

    1108:   Level: advanced
    1109: @*/
    1110: PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s)
    1111: {
    1113:   if (s) *s = ls->stepdirection;
    1114:   return 0;
    1115: }

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

    1120:   Not Collective

    1122:   Input Parameter:
    1123: . ls - the TaoLineSearch context

    1125:   Output Parameter:
    1126: . f - the objective value at the full step length

    1128:   Level: developer
    1129: @*/

    1131: PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep)
    1132: {
    1134:   *f_fullstep = ls->f_fullstep;
    1135:   return 0;
    1136: }

    1138: /*@
    1139:   TaoLineSearchSetVariableBounds - Sets the upper and lower bounds.

    1141:   Logically Collective on Tao

    1143:   Input Parameters:
    1144: + ls - the TaoLineSearch context
    1145: . xl  - vector of lower bounds
    1146: - xu  - vector of upper bounds

    1148:   Note: If the variable bounds are not set with this routine, then
    1149:   PETSC_NINFINITY and PETSC_INFINITY are assumed

    1151:   Level: beginner

    1153: .seealso: TaoSetVariableBounds(), TaoLineSearchCreate()
    1154: @*/
    1155: PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls,Vec xl, Vec xu)
    1156: {
    1160:   PetscObjectReference((PetscObject)xl);
    1161:   PetscObjectReference((PetscObject)xu);
    1162:   VecDestroy(&ls->lower);
    1163:   VecDestroy(&ls->upper);
    1164:   ls->lower = xl;
    1165:   ls->upper = xu;
    1166:   ls->bounded = 1;
    1167:   return 0;
    1168: }

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

    1174:   Logically Collective on TaoLineSearch

    1176:   Input Parameters:
    1177: + ls - the TaoLineSearch context
    1178: - s - the initial step size

    1180:   Level: intermediate

    1182: .seealso: TaoLineSearchGetStepLength(), TaoLineSearchApply()
    1183: @*/
    1184: PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls,PetscReal s)
    1185: {
    1187:   ls->initstep = s;
    1188:   return 0;
    1189: }

    1191: /*@
    1192:   TaoLineSearchGetStepLength - Get the current step length

    1194:   Not Collective

    1196:   Input Parameters:
    1197: . ls - the TaoLineSearch context

    1199:   Output Parameters:
    1200: . s - the current step length

    1202:   Level: beginner

    1204: .seealso: TaoLineSearchSetInitialStepLength(), TaoLineSearchApply()
    1205: @*/
    1206: PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls,PetscReal *s)
    1207: {
    1209:   *s = ls->step;
    1210:   return 0;
    1211: }

    1213: /*@C
    1214:    TaoLineSearchRegister - Adds a line-search algorithm to the registry

    1216:    Not collective

    1218:    Input Parameters:
    1219: +  sname - name of a new user-defined solver
    1220: -  func - routine to Create method context

    1222:    Notes:
    1223:    TaoLineSearchRegister() may be called multiple times to add several user-defined solvers.

    1225:    Sample usage:
    1226: .vb
    1227:    TaoLineSearchRegister("my_linesearch",MyLinesearchCreate);
    1228: .ve

    1230:    Then, your solver can be chosen with the procedural interface via
    1231: $     TaoLineSearchSetType(ls,"my_linesearch")
    1232:    or at runtime via the option
    1233: $     -tao_ls_type my_linesearch

    1235:    Level: developer

    1237: @*/
    1238: PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch))
    1239: {
    1240:   TaoLineSearchInitializePackage();
    1241:   PetscFunctionListAdd(&TaoLineSearchList, sname, (void (*)(void))func);
    1242:   return 0;
    1243: }

    1245: /*@C
    1246:    TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching
    1247:    for all TaoLineSearch options in the database.

    1249:    Collective on TaoLineSearch

    1251:    Input Parameters:
    1252: +  ls - the TaoLineSearch solver context
    1253: -  prefix - the prefix string to prepend to all line search requests

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

    1259:    Level: advanced

    1261: .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchGetOptionsPrefix()
    1262: @*/
    1263: PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[])
    1264: {
    1265:   return PetscObjectAppendOptionsPrefix((PetscObject)ls,p);
    1266: }

    1268: /*@C
    1269:   TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
    1270:   TaoLineSearch options in the database

    1272:   Not Collective

    1274:   Input Parameters:
    1275: . ls - the TaoLineSearch context

    1277:   Output Parameters:
    1278: . prefix - pointer to the prefix string used is returned

    1280:   Notes:
    1281:     On the fortran side, the user should pass in a string 'prefix' of
    1282:   sufficient length to hold the prefix.

    1284:   Level: advanced

    1286: .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchAppendOptionsPrefix()
    1287: @*/
    1288: PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[])
    1289: {
    1290:   return PetscObjectGetOptionsPrefix((PetscObject)ls,p);
    1291: }

    1293: /*@C
    1294:    TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all
    1295:    TaoLineSearch options in the database.

    1297:    Logically Collective on TaoLineSearch

    1299:    Input Parameters:
    1300: +  ls - the TaoLineSearch context
    1301: -  prefix - the prefix string to prepend to all TAO option requests

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

    1307:    For example, to distinguish between the runtime options for two
    1308:    different line searches, one could call
    1309: .vb
    1310:       TaoLineSearchSetOptionsPrefix(ls1,"sys1_")
    1311:       TaoLineSearchSetOptionsPrefix(ls2,"sys2_")
    1312: .ve

    1314:    This would enable use of different options for each system, such as
    1315: .vb
    1316:       -sys1_tao_ls_type mt
    1317:       -sys2_tao_ls_type armijo
    1318: .ve

    1320:    Level: advanced

    1322: .seealso: TaoLineSearchAppendOptionsPrefix(), TaoLineSearchGetOptionsPrefix()
    1323: @*/

    1325: PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[])
    1326: {
    1327:   return PetscObjectSetOptionsPrefix((PetscObject)ls,p);
    1328: }