Actual source code: taolinesearch.c

petsc-dev 2014-02-02
Report Typos and Errors
  1: #include <petsctaolinesearch.h> /*I "petsctaolinesearch.h" I*/
  2: #include <petsc-private/taolinesearchimpl.h>

  4: PetscBool TaoLineSearchInitialized = PETSC_FALSE;
  5: PetscFunctionList TaoLineSearchList = NULL;

  7: PetscClassId TAOLINESEARCH_CLASSID=0;
  8: PetscLogEvent TaoLineSearch_ApplyEvent = 0, TaoLineSearch_EvalEvent=0;

 12: /*@C
 13:   TaoLineSearchView - Prints information about the TaoLineSearch

 15:   Collective on TaoLineSearch

 17:   InputParameters:
 18: + ls - the Tao context
 19: - viewer - visualization context

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

 24:   Notes:
 25:   The available visualization contexts include
 26: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
 27: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
 28:          output where only the first processor opens
 29:          the file.  All other processors send their
 30:          data to the first processor to print.

 32:   Level: beginner

 34: .seealso: PetscViewerASCIIOpen()
 35: @*/

 37: PetscErrorCode TaoLineSearchView(TaoLineSearch ls, PetscViewer viewer)
 38: {
 39:   PetscErrorCode          ierr;
 40:   PetscBool               isascii, isstring;
 41:   const TaoLineSearchType type;
 42:   PetscBool               destroyviewer = PETSC_FALSE;

 46:   if (!viewer) {
 47:     destroyviewer = PETSC_TRUE;
 48:     PetscViewerASCIIGetStdout(((PetscObject)ls)->comm, &viewer);
 49:   }

 53:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
 54:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
 55:   if (isascii) {
 56:     if (((PetscObject)ls)->prefix) {
 57:       PetscViewerASCIIPrintf(viewer,"TaoLineSearch Object:(%s)\n",((PetscObject)ls)->prefix);
 58:     } else {
 59:       PetscViewerASCIIPrintf(viewer,"TaoLineSearch Object:\n");
 60:     }
 61:     PetscViewerASCIIPushTab(viewer);
 62:     TaoLineSearchGetType(ls,&type);
 63:     if (type) {
 64:       PetscViewerASCIIPrintf(viewer,"type: %s\n",type);
 65:     } else {
 66:       PetscViewerASCIIPrintf(viewer,"type: not set yet\n");
 67:     }
 68:     if (ls->ops->view) {
 69:       PetscViewerASCIIPushTab(viewer);
 70:       (*ls->ops->view)(ls,viewer);
 71:       PetscViewerASCIIPopTab(viewer);
 72:     }
 73:     PetscViewerASCIIPrintf(viewer,"maximum function evaluations=%D\n",ls->max_funcs);
 74:     PetscViewerASCIIPrintf(viewer,"tolerances: ftol=%g, rtol=%g, gtol=%g\n",(double)ls->ftol,(double)ls->rtol,(double)ls->gtol);
 75:     PetscViewerASCIIPrintf(viewer,"total number of function evaluations=%D\n",ls->nfeval);
 76:     PetscViewerASCIIPrintf(viewer,"total number of gradient evaluations=%D\n",ls->ngeval);
 77:     PetscViewerASCIIPrintf(viewer,"total number of function/gradient evaluations=%D\n",ls->nfgeval);

 79:     if (ls->bounded) {
 80:       PetscViewerASCIIPrintf(viewer,"using variable bounds\n");
 81:     }
 82:     PetscViewerASCIIPrintf(viewer,"Termination reason: %D\n",(int)ls->reason);
 83:     PetscViewerASCIIPopTab(viewer);

 85:   } else if (isstring) {
 86:     TaoLineSearchGetType(ls,&type);
 87:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
 88:   }
 89:   if (destroyviewer) {
 90:     PetscViewerDestroy(&viewer);
 91:   }
 92:   return(0);
 93: }

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

101:   Collective on MPI_Comm

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

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

109:   Available methods include:
110: + more-thuente
111: . gpcg
112: - unit - Do not perform any line search


115:    Options Database Keys:
116: .   -tao_ls_type - select which method TAO should use

118:    Level: beginner

120: .seealso: TaoLineSearchSetType(), TaoLineSearchApply(), TaoLineSearchDestroy()
121: @*/

123: PetscErrorCode TaoLineSearchCreate(MPI_Comm comm, TaoLineSearch *newls)
124: {
126:   TaoLineSearch  ls;

130:   *newls = NULL;

132:  #ifndef PETSC_USE_DYNAMIC_LIBRARIES
133:   TaoLineSearchInitializePackage();
134:  #endif

136:   PetscHeaderCreate(ls,_p_TaoLineSearch,struct _TaoLineSearchOps,TAOLINESEARCH_CLASSID,"TaoLineSearch",0,0,comm,TaoLineSearchDestroy,TaoLineSearchView);
137:   ls->bounded = 0;
138:   ls->max_funcs=30;
139:   ls->ftol = 0.0001;
140:   ls->gtol = 0.9;
141: #if defined(PETSC_USE_REAL_SINGLE)
142:   ls->rtol = 1.0e-5;
143: #else
144:   ls->rtol = 1.0e-10;
145: #endif
146:   ls->stepmin=1.0e-20;
147:   ls->stepmax=1.0e+20;
148:   ls->step=1.0;
149:   ls->nfeval=0;
150:   ls->ngeval=0;
151:   ls->nfgeval=0;

153:   ls->ops->computeobjective=0;
154:   ls->ops->computegradient=0;
155:   ls->ops->computeobjectiveandgradient=0;
156:   ls->ops->computeobjectiveandgts=0;
157:   ls->ops->setup=0;
158:   ls->ops->apply=0;
159:   ls->ops->view=0;
160:   ls->ops->setfromoptions=0;
161:   ls->ops->reset=0;
162:   ls->ops->destroy=0;
163:   ls->setupcalled=PETSC_FALSE;
164:   ls->usetaoroutines=PETSC_FALSE;
165:   *newls = ls;
166:   return(0);
167: }

171: /*@
172:   TaoLineSearchSetUp - Sets up the internal data structures for the later use
173:   of a Tao solver

175:   Collective on ls

177:   Input Parameters:
178: . ls - the TaoLineSearch context

180:   Notes:
181:   The user will not need to explicitly call TaoLineSearchSetUp(), as it will
182:   automatically be called in TaoLineSearchSolve().  However, if the user
183:   desires to call it explicitly, it should come after TaoLineSearchCreate()
184:   but before TaoLineSearchApply().

186:   Level: developer

188: .seealso: TaoLineSearchCreate(), TaoLineSearchApply()
189: @*/

191: PetscErrorCode TaoLineSearchSetUp(TaoLineSearch ls)
192: {
194:   const char     *default_type=TAOLINESEARCH_MT;
195:   PetscBool      flg;

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

236: /*@
237:   TaoLineSearchReset - Some line searches may carry state information
238:   from one TaoLineSearchApply() to the next.  This function resets this
239:   state information.

241:   Collective on TaoLineSearch

243:   Input Parameter:
244: . ls - the TaoLineSearch context

246:   Level: developer

248: .seealso: TaoLineSearchCreate(), TaoLineSearchApply()
249: @*/
250: PetscErrorCode TaoLineSearchReset(TaoLineSearch ls)
251: {

256:   if (ls->ops->reset) {
257:     (*ls->ops->reset)(ls);
258:   }
259:   return(0);
260: }

264: /*@
265:   TaoLineSearchDestroy - Destroys the TAO context that was created with
266:   TaoLineSearchCreate()

268:   Collective on TaoLineSearch

270:   Input Parameter
271: . ls - the TaoLineSearch context

273:   Level: beginner

275: .seealse: TaoLineSearchCreate(), TaoLineSearchSolve()
276: @*/
277: PetscErrorCode TaoLineSearchDestroy(TaoLineSearch *ls)
278: {

282:   if (!*ls) return(0);
284:   if (--((PetscObject)*ls)->refct > 0) {*ls=0; return(0);}
285:   VecDestroy(&(*ls)->stepdirection);
286:   VecDestroy(&(*ls)->start_x);
287:   if ((*ls)->ops->destroy) {
288:     (*(*ls)->ops->destroy)(*ls);
289:   }
290:   PetscHeaderDestroy(ls);
291:   return(0);
292: }

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

299:   Collective on TaoLineSearch

301:   Input Parameters:
302: + ls - the Tao context
303: . x - The current solution (on output x contains the new solution determined by the line search)
304: . f - objective function value at current solution (on output contains the objective function value at new solution)
305: . g - gradient evaluated at x (on output contains the gradient at new solution)
306: - s - search direction

308:   Output Parameters:
309: + x - new solution
310: . f - objective function value at x
311: . g - gradient vector at x
312: . steplength - scalar multiplier of s used ( x = x0 + steplength * x )
313: - reason - reason why the line-search stopped

315:   reason will be set to one of:

317: + TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction
318: . TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value
319: . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter
320: . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached
321: . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound
322: . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound
323: . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance
324: . TAOLINESEARCH_HALTED_USER - user can set this reason to stop line search
325: . TAOLINESEARCH_HALTED_OTHER - any other reason
326: - TAOLINESEARCH_SUCCESS - successful line search

328:   Note:
329:   The algorithm developer must set up the TaoLineSearch with calls to
330:   TaoLineSearchSetObjectiveRoutine() and TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), or TaoLineSearchUseTaoRoutines()

332:   Note:
333:   You may or may not need to follow this with a call to
334:   TaoAddLineSearchCounts(), depending on whether you want these
335:   evaluations to count toward the total function/gradient evaluations.

337:   Level: beginner

339:   .seealso: TaoLineSearchCreate(), TaoLineSearchSetType(), TaoLineSearchSetInitialStepLength(), TaoAddLineSearchCounts()
340:  @*/

342: PetscErrorCode TaoLineSearchApply(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s, PetscReal *steplength, TaoLineSearchTerminationReason *reason)
343: {
345:   PetscViewer    viewer;
346:   PetscInt       low1,low2,low3,high1,high2,high3;
347:   PetscBool      flg;
348:   char           filename[PETSC_MAX_PATH_LEN];

351:   *reason = TAOLINESEARCH_CONTINUE_ITERATING;
361:   VecGetOwnershipRange(x, &low1, &high1);
362:   VecGetOwnershipRange(g, &low2, &high2);
363:   VecGetOwnershipRange(s, &low3, &high3);
364:   if ( low1!= low2 || low1!= low3 || high1!= high2 || high1!= high3) SETERRQ(PETSC_COMM_SELF,1,"InCompatible vector local lengths");

366:   PetscObjectReference((PetscObject)s);
367:   VecDestroy(&ls->stepdirection);
368:   ls->stepdirection = s;

370:   TaoLineSearchSetUp(ls);
371:   if (!ls->ops->apply) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search Object does not have 'apply' routine");
372:   ls->nfeval=0;
373:   ls->ngeval=0;
374:   ls->nfgeval=0;
375:   /* Check parameter values */
376:   if (ls->ftol < 0.0) {
377:     PetscInfo1(ls,"Bad Line Search Parameter: ftol (%g) < 0\n",(double)ls->ftol);
378:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
379:   }
380:   if (ls->rtol < 0.0) {
381:     PetscInfo1(ls,"Bad Line Search Parameter: rtol (%g) < 0\n",(double)ls->rtol);
382:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
383:   }
384:   if (ls->gtol < 0.0) {
385:     PetscInfo1(ls,"Bad Line Search Parameter: gtol (%g) < 0\n",(double)ls->gtol);
386:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
387:   }
388:   if (ls->stepmin < 0.0) {
389:     PetscInfo1(ls,"Bad Line Search Parameter: stepmin (%g) < 0\n",(double)ls->stepmin);
390:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
391:   }
392:   if (ls->stepmax < ls->stepmin) {
393:     PetscInfo2(ls,"Bad Line Search Parameter: stepmin (%g) > stepmax (%g)\n",(double)ls->stepmin,(double)ls->stepmax);
394:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
395:   }
396:   if (ls->max_funcs < 0) {
397:     PetscInfo1(ls,"Bad Line Search Parameter: max_funcs (%D) < 0\n",ls->max_funcs);
398:     *reason=TAOLINESEARCH_FAILED_BADPARAMETER;
399:   }
400:   if (PetscIsInfOrNanReal(*f)) {
401:     PetscInfo1(ls,"Initial Line Search Function Value is Inf or Nan (%g)\n",(double)*f);
402:     *reason=TAOLINESEARCH_FAILED_INFORNAN;
403:   }

405:   PetscObjectReference((PetscObject)x);
406:   VecDestroy(&ls->start_x);
407:   ls->start_x = x;

409:   PetscLogEventBegin(TaoLineSearch_ApplyEvent,ls,0,0,0);
410:   (*ls->ops->apply)(ls,x,f,g,s);
411:   PetscLogEventEnd(TaoLineSearch_ApplyEvent, ls, 0,0,0);
412:   *reason=ls->reason;
413:   ls->new_f = *f;

415:   if (steplength) {
416:     *steplength=ls->step;
417:   }

419:   PetscOptionsGetString(((PetscObject)ls)->prefix,"-tao_ls_view",filename,PETSC_MAX_PATH_LEN,&flg);
420:   if (ls->viewls && !PetscPreLoadingOn) {
421:     PetscViewerASCIIOpen(((PetscObject)ls)->comm,filename,&viewer);
422:     TaoLineSearchView(ls,viewer);
423:     PetscViewerDestroy(&viewer);
424:   }
425:   return(0);
426: }

430: /*@C
431:    TaoLineSearchSetType - Sets the algorithm used in a line search

433:    Collective on TaoLineSearch

435:    Input Parameters:
436: +  ls - the TaoLineSearch context
437: -  type - a known method

439:   Available methods include:
440: + more-thuente
441: . gpcg
442: - unit - Do not perform any line search


445:   Options Database Keys:
446: .   -tao_ls_type - select which method TAO should use

448:   Level: beginner


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

453: @*/

455: PetscErrorCode TaoLineSearchSetType(TaoLineSearch ls, const TaoLineSearchType type)
456: {
458:   PetscErrorCode (*r)(TaoLineSearch);
459:   PetscBool      flg;

464:   PetscObjectTypeCompare((PetscObject)ls, type, &flg);
465:   if (flg) return(0);

467:   PetscFunctionListFind(TaoLineSearchList,type, (void (**)(void)) &r);
468:   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested TaoLineSearch type %s",type);
469:   if (ls->ops->destroy) {
470:     (*(ls)->ops->destroy)(ls);
471:   }
472:   ls->max_funcs=30;
473:   ls->ftol = 0.0001;
474:   ls->gtol = 0.9;
475: #if defined(PETSC_USE_REAL_SINGLE)
476:   ls->rtol = 1.0e-5;
477: #else
478:   ls->rtol = 1.0e-10;
479: #endif
480:   ls->stepmin=1.0e-20;
481:   ls->stepmax=1.0e+20;

483:   ls->nfeval=0;
484:   ls->ngeval=0;
485:   ls->nfgeval=0;
486:   ls->ops->setup=0;
487:   ls->ops->apply=0;
488:   ls->ops->view=0;
489:   ls->ops->setfromoptions=0;
490:   ls->ops->destroy=0;
491:   ls->setupcalled = PETSC_FALSE;
492:   (*r)(ls);
493:   PetscObjectChangeTypeName((PetscObject)ls, type);
494:   return(0);
495: }

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

503:   Collective on TaoLineSearch

505:   Input Paremeter:
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=TAOLINESEARCH_MT;
524:   char           type[256];
525:   PetscBool      flg;

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

544:   PetscOptionsInt("-tao_ls_max_funcs","max function evals in line search","",ls->max_funcs,&ls->max_funcs,0);
545:   PetscOptionsReal("-tao_ls_ftol","tol for sufficient decrease","",ls->ftol,&ls->ftol,0);
546:   PetscOptionsReal("-tao_ls_gtol","tol for curvature condition","",ls->gtol,&ls->gtol,0);
547:   PetscOptionsReal("-tao_ls_rtol","relative tol for acceptable step","",ls->rtol,&ls->rtol,0);
548:   PetscOptionsReal("-tao_ls_stepmin","lower bound for step","",ls->stepmin,&ls->stepmin,0);
549:   PetscOptionsReal("-tao_ls_stepmax","upper bound for step","",ls->stepmax,&ls->stepmax,0);
550:   PetscOptionsBool("-tao_ls_view","view TaoLineSearch info after each line search has completed","TaoLineSearchView",PETSC_FALSE,&ls->viewls,NULL);
551:   if (ls->ops->setfromoptions) {
552:     (*ls->ops->setfromoptions)(ls);
553:   }
554:   PetscOptionsEnd();
555:   return(0);
556: }

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

563:   Not Collective

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

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

571:   Level: developer

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

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

589:   Not Collective

591:   Input Parameter:
592: . ls - the TaoLineSearch context

594:   Output Parameters:
595: + nfeval   - number of function evaluations
596: . ngeval   - number of gradient evaluations
597: - nfgeval  - number of function/gradient evaluations

599:   Level: intermediate

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

606: @*/
607: PetscErrorCode TaoLineSearchGetNumberFunctionEvaluations(TaoLineSearch ls, PetscInt *nfeval, PetscInt *ngeval, PetscInt *nfgeval)
608: {
611:   *nfeval = ls->nfeval;
612:   *ngeval = ls->ngeval;
613:   *nfgeval = ls->nfgeval;
614:   return(0);
615: }

619: /*@
620:   TaoLineSearchIsUsingTaoRoutines - Checks whether the line search is using
621:   Tao evaluation routines.

623:   Not Collective

625:   Input Parameter:
626: . ls - the TaoLineSearch context

628:   Output Parameter:
629: . flg - PETSC_TRUE if the line search is using Tao evaluation routines,
630:         otherwise PETSC_FALSE

632:   Level: developer
633: @*/
634: PetscErrorCode TaoLineSearchIsUsingTaoRoutines(TaoLineSearch ls, PetscBool *flg)
635: {
638:   *flg = ls->usetaoroutines;
639:   return(0);
640: }

644: /*@C
645:   TaoLineSearchSetObjectiveRoutine - Sets the function evaluation routine for the line search

647:   Logically Collective on TaoLineSearch

649:   Input Parameter:
650: + ls - the TaoLineSearch context
651: . func - the objective function evaluation routine
652: - ctx - the (optional) user-defined context for private data

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

657: + x - input vector
658: . f - function value
659: - ctx (optional) user-defined context

661:   Level: beginner

663:   Note:
664:   Use this routine only if you want the line search objective
665:   evaluation routine to be different from the Tao's objective
666:   evaluation routine. If you use this routine you must also set
667:   the line search gradient and/or function/gradient routine.

669:   Note:
670:   Some algorithms (lcl, gpcg) set their own objective routine for the
671:   line search, application programmers should be wary of overriding the
672:   default objective routine.

674: .seealso: TaoLineSearchCreate(), TaoLineSearchSetGradientRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines()
675: @*/
676: PetscErrorCode TaoLineSearchSetObjectiveRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal*, void*), void *ctx)
677: {

681:   ls->ops->computeobjective=func;
682:   if (ctx) ls->userctx_func=ctx;
683:   ls->usetaoroutines=PETSC_FALSE;
684:   return(0);
685: }

689: /*@C
690:   TaoLineSearchSetGradientRoutine - Sets the gradient evaluation routine for the line search

692:   Logically Collective on TaoLineSearch

694:   Input Parameter:
695: + ls - the TaoLineSearch context
696: . func - the gradient evaluation routine
697: - ctx - the (optional) user-defined context for private data

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

702: + x - input vector
703: . g - gradient vector
704: - ctx (optional) user-defined context

706:   Level: beginner

708:   Note:
709:   Use this routine only if you want the line search gradient
710:   evaluation routine to be different from the Tao's gradient
711:   evaluation routine. If you use this routine you must also set
712:   the line search function and/or function/gradient routine.

714:   Note:
715:   Some algorithms (lcl, gpcg) set their own gradient routine for the
716:   line search, application programmers should be wary of overriding the
717:   default gradient routine.

719: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetObjectiveAndGradientRoutine(), TaoLineSearchUseTaoRoutines()
720: @*/
721: PetscErrorCode TaoLineSearchSetGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec g, void*), void *ctx)
722: {
725:   ls->ops->computegradient=func;
726:   if (ctx) ls->userctx_grad=ctx;
727:   ls->usetaoroutines=PETSC_FALSE;
728:   return(0);
729: }

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

736:   Logically Collective on TaoLineSearch

738:   Input Parameter:
739: + ls - the TaoLineSearch context
740: . func - the objective and gradient evaluation routine
741: - ctx - the (optional) user-defined context for private data

743:   Calling sequence of func:
744: $      func (TaoLinesearch ls, Vec x, PetscReal *f, Vec g, void *ctx);

746: + x - input vector
747: . f - function value
748: . g - gradient vector
749: - ctx (optional) user-defined context

751:   Level: beginner

753:   Note:
754:   Use this routine only if you want the line search objective and gradient
755:   evaluation routines to be different from the Tao's objective
756:   and gradient evaluation routines.

758:   Note:
759:   Some algorithms (lcl, gpcg) set their own objective routine for the
760:   line search, application programmers should be wary of overriding the
761:   default objective routine.

763: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjectiveRoutine(), TaoLineSearchSetGradientRoutine(), TaoLineSearchUseTaoRoutines()
764: @*/
765: PetscErrorCode TaoLineSearchSetObjectiveAndGradientRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, PetscReal *, Vec g, void*), void *ctx)
766: {
769:   ls->ops->computeobjectiveandgradient=func;
770:   if (ctx) ls->userctx_funcgrad=ctx;
771:   ls->usetaoroutines = PETSC_FALSE;
772:   return(0);
773: }

777: /*@C
778:   TaoLineSearchSetObjectiveAndGTSRoutine - Sets the objective and
779:   (gradient'*stepdirection) evaluation routine for the line search.
780:   Sometimes it is more efficient to compute the inner product of the gradient
781:   and the step direction than it is to compute the gradient, and this is all
782:   the line search typically needs of the gradient.

784:   Logically Collective on TaoLineSearch

786:   Input Parameter:
787: + ls - the TaoLineSearch context
788: . func - the objective and gradient evaluation routine
789: - ctx - the (optional) user-defined context for private data

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

794: + x - input vector
795: . s - step direction
796: . f - function value
797: . gts - inner product of gradient and step direction vectors
798: - ctx (optional) user-defined context

800:   Note: The gradient will still need to be computed at the end of the line
801:   search, so you will still need to set a line search gradient evaluation
802:   routine

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

808:   Level: advanced

810:   Note:
811:   Some algorithms (lcl, gpcg) set their own objective routine for the
812:   line search, application programmers should be wary of overriding the
813:   default objective routine.

815: .seealso: TaoLineSearchCreate(), TaoLineSearchSetObjective(), TaoLineSearchSetGradient(), TaoLineSearchUseTaoRoutines()
816: @*/
817: PetscErrorCode TaoLineSearchSetObjectiveAndGTSRoutine(TaoLineSearch ls, PetscErrorCode(*func)(TaoLineSearch ls, Vec x, Vec s, PetscReal *, PetscReal *, void*), void *ctx)
818: {
821:   ls->ops->computeobjectiveandgts=func;
822:   if (ctx) ls->userctx_funcgts=ctx;
823:   ls->usegts = PETSC_TRUE;
824:   ls->usetaoroutines=PETSC_FALSE;
825:   return(0);
826: }

830: /*@C
831:   TaoLineSearchUseTaoRoutines - Informs the TaoLineSearch to use the
832:   objective and gradient evaluation routines from the given Tao object.

834:   Logically Collective on TaoLineSearch

836:   Input Parameter:
837: + ls - the TaoLineSearch context
838: - ts - the Tao context with defined objective/gradient evaluation routines

840:   Level: developer

842: .seealso: TaoLineSearchCreate()
843: @*/
844: PetscErrorCode TaoLineSearchUseTaoRoutines(TaoLineSearch ls, Tao ts)
845: {
849:   ls->tao = ts;
850:   ls->usetaoroutines=PETSC_TRUE;
851:   return(0);
852: }

856: /*@
857:   TaoLineSearchComputeObjective - Computes the objective function value at a given point

859:   Collective on TaoLineSearch

861:   Input Parameters:
862: + ls - the TaoLineSearch context
863: - x - input vector

865:   Output Parameter:
866: . f - Objective value at X

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

871:   Level: developer

873: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
874: @*/
875: PetscErrorCode TaoLineSearchComputeObjective(TaoLineSearch ls, Vec x, PetscReal *f)
876: {
878:   Vec            gdummy;
879:   PetscReal      gts;

886:   if (ls->usetaoroutines) {
887:     TaoComputeObjective(ls->tao,x,f);
888:   } else {
889:     PetscLogEventBegin(TaoLineSearch_EvalEvent,ls,0,0,0);
890:     if (!ls->ops->computeobjective && !ls->ops->computeobjectiveandgradient && !ls->ops->computeobjectiveandgts) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective function set");
891:     PetscStackPush("TaoLineSearch user objective routine");
892:     if (ls->ops->computeobjective) {
893:       (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);
894:     } else if (ls->ops->computeobjectiveandgradient) {
895:       VecDuplicate(x,&gdummy);
896:       (*ls->ops->computeobjectiveandgradient)(ls,x,f,gdummy,ls->userctx_funcgrad);
897:       VecDestroy(&gdummy);
898:     } else {
899:       (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,&gts,ls->userctx_funcgts);
900:     }
901:     PetscStackPop;
902:     PetscLogEventEnd(TaoLineSearch_EvalEvent,ls,0,0,0);
903:   }
904:   ls->nfeval++;
905:   return(0);
906: }

910: /*@
911:   TaoLineSearchComputeObjectiveAndGradient - Computes the objective function value at a given point

913:   Collective on Tao

915:   Input Parameters:
916: + ls - the TaoLineSearch context
917: - x - input vector

919:   Output Parameter:
920: + f - Objective value at X
921: - g - Gradient vector at X

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

926:   Level: developer

928: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
929: @*/
930: PetscErrorCode TaoLineSearchComputeObjectiveAndGradient(TaoLineSearch ls, Vec x, PetscReal *f, Vec g)
931: {

941:   if (ls->usetaoroutines) {
942:       TaoComputeObjectiveAndGradient(ls->tao,x,f,g);
943:   } else {
944:     PetscLogEventBegin(TaoLineSearch_EvalEvent,ls,0,0,0);
945:     if (!ls->ops->computeobjective && !ls->ops->computeobjectiveandgradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective function set");
946:     if (!ls->ops->computegradient && !ls->ops->computeobjectiveandgradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have gradient function set");

948:     PetscStackPush("TaoLineSearch user objective/gradient routine");
949:     if (ls->ops->computeobjectiveandgradient) {
950:       (*ls->ops->computeobjectiveandgradient)(ls,x,f,g,ls->userctx_funcgrad);
951:     } else {
952:       (*ls->ops->computeobjective)(ls,x,f,ls->userctx_func);
953:       (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);
954:     }
955:     PetscStackPop;
956:     PetscLogEventEnd(TaoLineSearch_EvalEvent,ls,0,0,0);
957:     PetscInfo1(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));
958:     ls->nfgeval++;
959:   }
960:   return(0);
961: }

965: /*@
966:   TaoLineSearchComputeGradient - Computes the gradient of the objective function

968:   Collective on TaoLineSearch

970:   Input Parameters:
971: + ls - the TaoLineSearch context
972: - x - input vector

974:   Output Parameter:
975: . g - gradient vector

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

980:   Level: developer

982: .seealso: TaoLineSearchComputeObjective(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetGradient()
983: @*/
984: PetscErrorCode TaoLineSearchComputeGradient(TaoLineSearch ls, Vec x, Vec g)
985: {
987:   PetscReal      fdummy;

995:   if (ls->usetaoroutines) {
996:     TaoComputeGradient(ls->tao,x,g);
997:   } else {
998:     PetscLogEventBegin(TaoLineSearch_EvalEvent,ls,0,0,0);
999:     if (!ls->ops->computegradient && !ls->ops->computeobjectiveandgradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have gradient functions set");
1000:     PetscStackPush("TaoLineSearch user gradient routine");
1001:     if (ls->ops->computegradient) {
1002:       (*ls->ops->computegradient)(ls,x,g,ls->userctx_grad);
1003:     } else {
1004:       (*ls->ops->computeobjectiveandgradient)(ls,x,&fdummy,g,ls->userctx_funcgrad);
1005:     }
1006:     PetscStackPop;
1007:     PetscLogEventEnd(TaoLineSearch_EvalEvent,ls,0,0,0);
1008:   }
1009:   ls->ngeval++;
1010:   return(0);
1011: }

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

1018:   Collective on Tao

1020:   Input Parameters:
1021: + ls - the TaoLineSearch context
1022: - x - input vector

1024:   Output Parameter:
1025: + f - Objective value at X
1026: - gts - inner product of gradient and step direction at X

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

1031:   Level: developer

1033: .seealso: TaoLineSearchComputeGradient(), TaoLineSearchComputeObjectiveAndGradient(), TaoLineSearchSetObjectiveRoutine()
1034: @*/
1035: PetscErrorCode TaoLineSearchComputeObjectiveAndGTS(TaoLineSearch ls, Vec x, PetscReal *f, PetscReal *gts)
1036: {
1044:   PetscLogEventBegin(TaoLineSearch_EvalEvent,ls,0,0,0);
1045:   if (!ls->ops->computeobjectiveandgts) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Line Search does not have objective and gts function set");
1046:   PetscStackPush("TaoLineSearch user objective/gts routine");
1047:   (*ls->ops->computeobjectiveandgts)(ls,x,ls->stepdirection,f,gts,ls->userctx_funcgts);
1048:   PetscStackPop;
1049:   PetscLogEventEnd(TaoLineSearch_EvalEvent,ls,0,0,0);
1050:   PetscInfo1(ls,"TaoLineSearch Function evaluation: %14.12e\n",(double)(*f));
1051:   ls->nfeval++;
1052:   return(0);
1053: }

1057: /*@
1058:   TaoLineSearchGetSolution - Returns the solution to the line search

1060:   Collective on TaoLineSearch

1062:   Input Parameter:
1063: . ls - the TaoLineSearch context

1065:   Output Parameter:
1066: + x - the new solution
1067: . f - the objective function value at x
1068: . g - the gradient at x
1069: . steplength - the multiple of the step direction taken by the line search
1070: - reason - the reason why the line search terminated

1072:   reason will be set to one of:

1074: + TAOLINESEARCH_FAILED_INFORNAN - function evaluation gives Inf or Nan value
1075: . TAOLINESEARCH_FAILED_BADPARAMETER - negative value set as parameter
1076: . TAOLINESEARCH_FAILED_ASCENT - initial line search step * g is not descent direction
1077: . TAOLINESEARCH_HALTED_MAXFCN - maximum number of function evaluation reached
1078: . TAOLINESEARCH_HALTED_UPPERBOUND - step is at upper bound
1079: . TAOLINESEARCH_HALTED_LOWERBOUND - step is at lower bound
1080: . TAOLINESEARCH_HALTED_RTOL - range of uncertainty is smaller than given tolerance

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

1085: + TAOLINESEARCH_SUCCESS - successful line search

1087:   Level: developer

1089: @*/
1090: PetscErrorCode TaoLineSearchGetSolution(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, PetscReal *steplength, TaoLineSearchTerminationReason *reason)
1091: {

1100:   if (ls->new_x) {
1101:     VecCopy(ls->new_x,x);
1102:   }
1103:   *f = ls->new_f;
1104:   if (ls->new_g) {
1105:     VecCopy(ls->new_g,g);
1106:   }
1107:   if (steplength) {
1108:     *steplength=ls->step;
1109:   }
1110:   *reason = ls->reason;
1111:   return(0);
1112: }

1116: /*@
1117:   TaoLineSearchGetStartingVector - Gets a the initial point of the line
1118:   search.

1120:   Not Collective

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

1125:   Output Parameter:
1126: . x - The initial point of the line search

1128:   Level: intermediate
1129: @*/
1130: PetscErrorCode TaoLineSearchGetStartingVector(TaoLineSearch ls, Vec *x)
1131: {
1134:   if (x) {
1135:     *x = ls->start_x;
1136:   }
1137:   return(0);
1138: }

1142: /*@
1143:   TaoLineSearchGetStepDirection - Gets the step direction of the line
1144:   search.

1146:   Not Collective

1148:   Input Parameter:
1149: . ls - the TaoLineSearch context

1151:   Output Parameter:
1152: . s - the step direction of the line search

1154:   Level: advanced
1155: @*/
1156: PetscErrorCode TaoLineSearchGetStepDirection(TaoLineSearch ls, Vec *s)
1157: {
1160:   if (s) {
1161:     *s = ls->stepdirection;
1162:   }
1163:   return(0);

1165: }

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

1172:   Not Collective

1174:   Input Parameter:
1175: . ls - the TaoLineSearch context

1177:   Output Parameter:
1178: . f - the objective value at the full step length

1180:   Level: developer
1181: @*/

1183: PetscErrorCode TaoLineSearchGetFullStepObjective(TaoLineSearch ls, PetscReal *f_fullstep)
1184: {
1187:   *f_fullstep = ls->f_fullstep;
1188:   return(0);
1189: }

1193: /*@
1194:   TaoLineSearchSetVariableBounds - Sets the upper and lower bounds.

1196:   Logically Collective on Tao

1198:   Input Parameters:
1199: + ls - the TaoLineSearch context
1200: . xl  - vector of lower bounds
1201: - xu  - vector of upper bounds

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

1206:   Level: beginner

1208: .seealso: TaoSetVariableBounds(), TaoLineSearchCreate()
1209: @*/
1210: PetscErrorCode TaoLineSearchSetVariableBounds(TaoLineSearch ls,Vec xl, Vec xu)
1211: {
1216:   ls->lower = xl;
1217:   ls->upper = xu;
1218:   ls->bounded = 1;
1219:   return(0);
1220: }

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

1228:   Logically Collective on TaoLineSearch

1230:   Input Parameters:
1231: + ls - the TaoLineSearch context
1232: - s - the initial step size

1234:   Level: intermediate

1236: .seealso: TaoLineSearchGetStepLength(), TaoLineSearchApply()
1237: @*/
1238: PetscErrorCode TaoLineSearchSetInitialStepLength(TaoLineSearch ls,PetscReal s)
1239: {
1242:   ls->initstep = s;
1243:   return(0);
1244: }

1248: /*@
1249:   TaoLineSearchGetStepLength - Get the current step length

1251:   Not Collective

1253:   Input Parameters:
1254: . ls - the TaoLineSearch context

1256:   Output Parameters
1257: . s - the current step length

1259:   Level: beginner

1261: .seealso: TaoLineSearchSetInitialStepLength(), TaoLineSearchApply()
1262: @*/
1263: PetscErrorCode TaoLineSearchGetStepLength(TaoLineSearch ls,PetscReal *s)
1264: {
1267:   *s = ls->step;
1268:   return(0);
1269: }

1273: /*MC
1274:    TaoLineSearchRegister - Adds a line-search algorithm to the registry

1276:    Not collective

1278:    Input Parameters:
1279: +  sname - name of a new user-defined solver
1280: -  func - routine to Create method context

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

1285:    Sample usage:
1286: .vb
1287:    TaoLineSearchRegister("my_linesearch",MyLinesearchCreate);
1288: .ve

1290:    Then, your solver can be chosen with the procedural interface via
1291: $     TaoLineSearchSetType(ls,"my_linesearch")
1292:    or at runtime via the option
1293: $     -tao_ls_type my_linesearch

1295:    Level: developer

1297: .seealso: TaoLineSearchRegisterDestroy()
1298: M*/
1299: PetscErrorCode TaoLineSearchRegister(const char sname[], PetscErrorCode (*func)(TaoLineSearch))
1300: {
1303:   PetscFunctionListAdd(&TaoLineSearchList, sname, (void (*)(void))func);
1304:   return(0);
1305: }

1309: /*@C
1310:    TaoLineSearchRegisterDestroy - Frees the list of line-search algorithms that were
1311:    registered by TaoLineSearchRegister().

1313:    Not Collective

1315:    Level: developer

1317: .seealso: TaoLineSearchRegister()
1318: @*/
1319: PetscErrorCode TaoLineSearchRegisterDestroy(void)
1320: {
1323:   PetscFunctionListDestroy(&TaoLineSearchList);
1324:   TaoLineSearchInitialized = PETSC_FALSE;
1325:   return(0);
1326: }

1330: /*@C
1331:    TaoLineSearchAppendOptionsPrefix - Appends to the prefix used for searching
1332:    for all TaoLineSearch options in the database.


1335:    Collective on TaoLineSearch

1337:    Input Parameters:
1338: +  ls - the TaoLineSearch solver context
1339: -  prefix - the prefix string to prepend to all line search requests

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


1346:    Level: advanced

1348: .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchGetOptionsPrefix()
1349: @*/
1350: PetscErrorCode TaoLineSearchAppendOptionsPrefix(TaoLineSearch ls, const char p[])
1351: {
1352:   return PetscObjectAppendOptionsPrefix((PetscObject)ls,p);
1353: }

1357: /*@C
1358:   TaoLineSearchGetOptionsPrefix - Gets the prefix used for searching for all
1359:   TaoLineSearch options in the database

1361:   Not Collective

1363:   Input Parameters:
1364: . ls - the TaoLineSearch context

1366:   Output Parameters:
1367: . prefix - pointer to the prefix string used is returned

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

1372:   Level: advanced

1374: .seealso: TaoLineSearchSetOptionsPrefix(), TaoLineSearchAppendOptionsPrefix()
1375: @*/
1376: PetscErrorCode TaoLineSearchGetOptionsPrefix(TaoLineSearch ls, const char *p[])
1377: {
1378:   return PetscObjectGetOptionsPrefix((PetscObject)ls,p);
1379: }

1383: /*@C
1384:    TaoLineSearchSetOptionsPrefix - Sets the prefix used for searching for all
1385:    TaoLineSearch options in the database.


1388:    Logically Collective on TaoLineSearch

1390:    Input Parameters:
1391: +  ls - the TaoLineSearch context
1392: -  prefix - the prefix string to prepend to all TAO option requests

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

1398:    For example, to distinguish between the runtime options for two
1399:    different line searches, one could call
1400: .vb
1401:       TaoLineSearchSetOptionsPrefix(ls1,"sys1_")
1402:       TaoLineSearchSetOptionsPrefix(ls2,"sys2_")
1403: .ve

1405:    This would enable use of different options for each system, such as
1406: .vb
1407:       -sys1_tao_ls_type mt
1408:       -sys2_tao_ls_type armijo
1409: .ve

1411:    Level: advanced

1413: .seealso: TaoLineSearchAppendOptionsPrefix(), TaoLineSearchGetOptionsPrefix()
1414: @*/

1416: PetscErrorCode TaoLineSearchSetOptionsPrefix(TaoLineSearch ls, const char p[])
1417: {
1418:   return PetscObjectSetOptionsPrefix((PetscObject)ls,p);
1419: }