Actual source code: pgd.c

petsc-3.9.4 2018-09-11
Report Typos and Errors
  1:  #include <../src/tao/bound/impls/pgd/pgd.h>

  3: static PetscErrorCode TaoSolve_PGD(Tao tao)
  4: {
  5:   TAO_PGD                      *pg = (TAO_PGD *)tao->data;
  6:   PetscErrorCode               ierr;
  7:   TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING;

 10:   /*   Project the current point onto the feasible set */
 11:   TaoComputeVariableBounds(tao);
 12:   TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);
 13: 
 14:   /* Project the initial point onto the feasible region */
 15:   VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);
 16: 
 17:   /* Compute the objective function and gradient */
 18:   TaoComputeObjectiveAndGradient(tao,tao->solution,&pg->f,pg->unprojected_gradient);
 19:   VecNorm(pg->unprojected_gradient,NORM_2,&pg->gnorm);
 20:   if (PetscIsInfOrNanReal(pg->f) || PetscIsInfOrNanReal(pg->gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN");
 21: 
 22:   /* Project the gradient and calculate the norm */
 23:   VecBoundGradientProjection(pg->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);
 24:   VecNorm(tao->gradient,NORM_2,&pg->gnorm);
 25: 
 26:   /* Check convergence and give info to monitors */
 27:   tao->reason = TAO_CONTINUE_ITERATING;
 28:   TaoLogConvergenceHistory(tao,pg->f,pg->gnorm,0.0,tao->ksp_its);
 29:   TaoMonitor(tao,tao->niter,pg->f,pg->gnorm,0.0,pg->stepsize);
 30:   (*tao->ops->convergencetest)(tao,tao->cnvP);
 31:   if (tao->reason != TAO_CONTINUE_ITERATING) return(0);
 32: 
 33:   while (tao->reason == TAO_CONTINUE_ITERATING) {
 34:     /* Set step direction to steepest descent */
 35:     VecCopy(pg->unprojected_gradient,tao->stepdirection);
 36:     VecScale(tao->stepdirection,-1.0);
 37: 
 38:     /* Perform line search */
 39:     TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);
 40:     TaoLineSearchApply(tao->linesearch, tao->solution, &pg->f, pg->unprojected_gradient, tao->stepdirection, &pg->stepsize, &ls_status);
 41:     TaoAddLineSearchCounts(tao);
 42:     if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) tao->reason = TAO_DIVERGED_LS_FAILURE;

 44:     /* Project the gradient and calculate the norm */
 45:     VecBoundGradientProjection(pg->unprojected_gradient,tao->solution,tao->XL,tao->XU,tao->gradient);
 46:     VecNorm(tao->gradient,NORM_2,&pg->gnorm);
 47: 
 48:     /* Check convergence and give info to monitors */
 49:     tao->niter++;
 50:     TaoLogConvergenceHistory(tao,pg->f,pg->gnorm,0.0,tao->ksp_its);
 51:     TaoMonitor(tao,tao->niter,pg->f,pg->gnorm,0.0,pg->stepsize);
 52:     (*tao->ops->convergencetest)(tao,tao->cnvP);
 53:   }
 54:   return(0);
 55: }

 57: /* ---------------------------------------------------------- */

 59: static PetscErrorCode TaoSetup_PGD(Tao tao)
 60: {
 61:   TAO_PGD        *pg = (TAO_PGD *)tao->data;

 65:   /* Allocate some arrays */
 66:   VecDuplicate(tao->solution, &tao->gradient);
 67:   VecDuplicate(tao->solution, &tao->stepdirection);
 68:   VecDuplicate(tao->solution, &pg->unprojected_gradient);
 69:   if (!tao->XL) {
 70:     VecDuplicate(tao->solution, &tao->XL);
 71:     VecSet(tao->XL, PETSC_NINFINITY);
 72:   }
 73:   if (!tao->XU) {
 74:     VecDuplicate(tao->solution, &tao->XU);
 75:     VecSet(tao->XU, PETSC_INFINITY);
 76:   }
 77:   return(0);
 78: }

 80: /* ---------------------------------------------------------- */

 82: static PetscErrorCode TaoSetFromOptions_PGD(PetscOptionItems *PetscOptionsObject,Tao tao)
 83: {

 87:   TaoLineSearchSetFromOptions(tao->linesearch);
 88:   return(0);
 89: }

 91: /*------------------------------------------------------------*/

 93: static PetscErrorCode TaoDestroy_PGD(Tao tao)
 94: {
 95:   TAO_PGD        *pg = (TAO_PGD *)tao->data;

 99:   VecDestroy(&pg->unprojected_gradient);
100:   PetscFree(tao->data);
101:   return(0);
102: }

104: /*------------------------------------------------------------*/

106: /*MC
107:   TAOPGD - The PGD algorithm is a projected gradient descent method for 
108:   bound constrained optimization.

110:   Level: beginner
111: M*/
112: PETSC_EXTERN PetscErrorCode TaoCreate_PGD(Tao tao)
113: {
114:   PetscErrorCode               ierr;
115:   TAO_PGD                      *pg;
116:   const char                   *morethuente_type = TAOLINESEARCHMT;
117: 
119:   tao->ops->setup          = TaoSetup_PGD;
120:   tao->ops->solve          = TaoSolve_PGD;
121:   tao->ops->setfromoptions = TaoSetFromOptions_PGD;
122:   tao->ops->destroy        = TaoDestroy_PGD;
123: 
124:   PetscNewLog(tao,&pg);
125:   tao->data = (void*)pg;
126: 
127:   TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);
128:   PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);
129:   TaoLineSearchSetType(tao->linesearch,morethuente_type);
130:   TaoLineSearchUseTaoRoutines(tao->linesearch,tao);
131:   TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);
132:   return(0);
133: }