Actual source code: pgd.c
petsc-3.9.4 2018-09-11
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: }