xref: /petsc/src/tao/bound/impls/tron/tron.c (revision 3c9e27cfca911a7d7e3219758be42726e83c4ab2)
1a7e14dcfSSatish Balay #include "tron.h"
2a7e14dcfSSatish Balay #include "petsc-private/kspimpl.h"
3a7e14dcfSSatish Balay #include "petsc-private/matimpl.h"
4f89ca46fSSatish Balay #include "../src/tao/matrix/submatfree.h"
5a7e14dcfSSatish Balay 
6a7e14dcfSSatish Balay 
7a7e14dcfSSatish Balay /* TRON Routines */
8a7e14dcfSSatish Balay static PetscErrorCode TronGradientProjections(TaoSolver,TAO_TRON*);
9a7e14dcfSSatish Balay /*------------------------------------------------------------*/
10a7e14dcfSSatish Balay #undef __FUNCT__
11a7e14dcfSSatish Balay #define __FUNCT__ "TaoDestroy_TRON"
12a7e14dcfSSatish Balay static PetscErrorCode TaoDestroy_TRON(TaoSolver tao)
13a7e14dcfSSatish Balay {
14a7e14dcfSSatish Balay   TAO_TRON *tron = (TAO_TRON *)tao->data;
15a7e14dcfSSatish Balay   PetscErrorCode ierr;
16a7e14dcfSSatish Balay 
17a7e14dcfSSatish Balay   PetscFunctionBegin;
18a7e14dcfSSatish Balay 
19a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->X_New);CHKERRQ(ierr);
20a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->G_New);CHKERRQ(ierr);
21a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->Work);CHKERRQ(ierr);
22a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->DXFree);CHKERRQ(ierr);
23a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->R); CHKERRQ(ierr);
24a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->diag); CHKERRQ(ierr);
25a7e14dcfSSatish Balay   ierr = VecScatterDestroy(&tron->scatter); CHKERRQ(ierr);
26a7e14dcfSSatish Balay   ierr = ISDestroy(&tron->Free_Local); CHKERRQ(ierr);
27a7e14dcfSSatish Balay   ierr = MatDestroy(&tron->H_sub); CHKERRQ(ierr);
28a7e14dcfSSatish Balay   ierr = MatDestroy(&tron->Hpre_sub); CHKERRQ(ierr);
29a7e14dcfSSatish Balay   ierr = PetscFree(tao->data);
30a7e14dcfSSatish Balay   tao->data = PETSC_NULL;
31a7e14dcfSSatish Balay 
32a7e14dcfSSatish Balay   PetscFunctionReturn(0);
33a7e14dcfSSatish Balay }
34a7e14dcfSSatish Balay 
35a7e14dcfSSatish Balay /*------------------------------------------------------------*/
36a7e14dcfSSatish Balay #undef __FUNCT__
37a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetFromOptions_TRON"
38a7e14dcfSSatish Balay static PetscErrorCode TaoSetFromOptions_TRON(TaoSolver tao)
39a7e14dcfSSatish Balay {
40a7e14dcfSSatish Balay   TAO_TRON  *tron = (TAO_TRON *)tao->data;
41a7e14dcfSSatish Balay   PetscErrorCode        ierr;
42a7e14dcfSSatish Balay   PetscBool flg;
43a7e14dcfSSatish Balay 
44a7e14dcfSSatish Balay   PetscFunctionBegin;
45a7e14dcfSSatish Balay 
46a7e14dcfSSatish Balay   ierr = PetscOptionsHead("Newton Trust Region Method for bound constrained optimization");CHKERRQ(ierr);
47a7e14dcfSSatish Balay 
48a7e14dcfSSatish Balay   ierr = PetscOptionsInt("-tron_maxgpits","maximum number of gradient projections per TRON iterate","TaoSetMaxGPIts",tron->maxgpits,&tron->maxgpits,&flg);
49a7e14dcfSSatish Balay   CHKERRQ(ierr);
50a7e14dcfSSatish Balay 
51a7e14dcfSSatish Balay   ierr = PetscOptionsTail();CHKERRQ(ierr);
52a7e14dcfSSatish Balay   ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
53a7e14dcfSSatish Balay   ierr = KSPSetFromOptions(tao->ksp); CHKERRQ(ierr);
54a7e14dcfSSatish Balay 
55a7e14dcfSSatish Balay   PetscFunctionReturn(0);
56a7e14dcfSSatish Balay }
57a7e14dcfSSatish Balay 
58a7e14dcfSSatish Balay /*------------------------------------------------------------*/
59a7e14dcfSSatish Balay #undef __FUNCT__
60a7e14dcfSSatish Balay #define __FUNCT__ "TaoView_TRON"
61a7e14dcfSSatish Balay static PetscErrorCode TaoView_TRON(TaoSolver tao, PetscViewer viewer)
62a7e14dcfSSatish Balay {
63a7e14dcfSSatish Balay   TAO_TRON  *tron = (TAO_TRON *)tao->data;
64a7e14dcfSSatish Balay   PetscBool isascii;
65a7e14dcfSSatish Balay   PetscErrorCode   ierr;
66a7e14dcfSSatish Balay 
67a7e14dcfSSatish Balay   PetscFunctionBegin;
68a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
69a7e14dcfSSatish Balay   if (isascii) {
70a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPushTab(viewer); CHKERRQ(ierr);
71a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"Total PG its: %D,",tron->total_gp_its);CHKERRQ(ierr);
72a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"PG tolerance: %G \n",tron->pg_ftol);CHKERRQ(ierr);
73a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPopTab(viewer); CHKERRQ(ierr);
74a7e14dcfSSatish Balay   } else {
75a7e14dcfSSatish Balay     SETERRQ1(((PetscObject)tao)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for TAO TRON",((PetscObject)viewer)->type_name);
76a7e14dcfSSatish Balay   }
77a7e14dcfSSatish Balay   PetscFunctionReturn(0);
78a7e14dcfSSatish Balay }
79a7e14dcfSSatish Balay 
80a7e14dcfSSatish Balay 
81a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
82a7e14dcfSSatish Balay #undef __FUNCT__
83a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetup_TRON"
84a7e14dcfSSatish Balay static PetscErrorCode TaoSetup_TRON(TaoSolver tao)
85a7e14dcfSSatish Balay {
86a7e14dcfSSatish Balay   PetscErrorCode ierr;
87a7e14dcfSSatish Balay   TAO_TRON *tron = (TAO_TRON *)tao->data;
88a7e14dcfSSatish Balay 
89a7e14dcfSSatish Balay   PetscFunctionBegin;
90a7e14dcfSSatish Balay 
91a7e14dcfSSatish Balay   /* Allocate some arrays */
92a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->diag); CHKERRQ(ierr);
93a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->X_New); CHKERRQ(ierr);
94a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->G_New); CHKERRQ(ierr);
95a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->Work); CHKERRQ(ierr);
96a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tao->gradient); CHKERRQ(ierr);
97a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tao->stepdirection); CHKERRQ(ierr);
98a7e14dcfSSatish Balay   if (!tao->XL) {
99a7e14dcfSSatish Balay       ierr = VecDuplicate(tao->solution, &tao->XL); CHKERRQ(ierr);
100a7e14dcfSSatish Balay       ierr = VecSet(tao->XL, TAO_NINFINITY); CHKERRQ(ierr);
101a7e14dcfSSatish Balay   }
102a7e14dcfSSatish Balay   if (!tao->XU) {
103a7e14dcfSSatish Balay       ierr = VecDuplicate(tao->solution, &tao->XU); CHKERRQ(ierr);
104a7e14dcfSSatish Balay       ierr = VecSet(tao->XU, TAO_INFINITY); CHKERRQ(ierr);
105a7e14dcfSSatish Balay   }
106a7e14dcfSSatish Balay 
107a7e14dcfSSatish Balay   PetscFunctionReturn(0);
108a7e14dcfSSatish Balay }
109a7e14dcfSSatish Balay 
110a7e14dcfSSatish Balay 
111a7e14dcfSSatish Balay 
112a7e14dcfSSatish Balay #undef __FUNCT__
113a7e14dcfSSatish Balay #define __FUNCT__ "TaoSolve_TRON"
114a7e14dcfSSatish Balay static PetscErrorCode TaoSolve_TRON(TaoSolver tao){
115a7e14dcfSSatish Balay 
116a7e14dcfSSatish Balay   TAO_TRON *tron = (TAO_TRON *)tao->data;
117a7e14dcfSSatish Balay   PetscErrorCode ierr;
118a7e14dcfSSatish Balay   PetscInt iter=0,its;
119a7e14dcfSSatish Balay 
120a7e14dcfSSatish Balay   TaoSolverTerminationReason reason = TAO_CONTINUE_ITERATING;
121a7e14dcfSSatish Balay   TaoLineSearchTerminationReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING;
122a7e14dcfSSatish Balay   PetscReal prered,actred,delta,f,f_new,rhok,gdx,xdiff,stepsize;
123a7e14dcfSSatish Balay   PetscFunctionBegin;
124a7e14dcfSSatish Balay 
125a7e14dcfSSatish Balay   tron->pgstepsize=1.0;
126a7e14dcfSSatish Balay 
127a7e14dcfSSatish Balay   tao->trust = tao->trust0;
128a7e14dcfSSatish Balay   /*   Project the current point onto the feasible set */
129a7e14dcfSSatish Balay   ierr = TaoComputeVariableBounds(tao); CHKERRQ(ierr);
130a7e14dcfSSatish Balay   ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution); CHKERRQ(ierr);
131a7e14dcfSSatish Balay   ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU); CHKERRQ(ierr);
132a7e14dcfSSatish Balay 
133a7e14dcfSSatish Balay 
134a7e14dcfSSatish Balay   ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&tron->f,tao->gradient);CHKERRQ(ierr);
135a7e14dcfSSatish Balay   if (tron->Free_Local) {
136a7e14dcfSSatish Balay     ierr = ISDestroy(&tron->Free_Local); CHKERRQ(ierr);
137a7e14dcfSSatish Balay     tron->Free_Local = PETSC_NULL;
138a7e14dcfSSatish Balay   }
139a7e14dcfSSatish Balay   ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local); CHKERRQ(ierr);
140a7e14dcfSSatish Balay 
141a7e14dcfSSatish Balay   /* Project the gradient and calculate the norm */
142a7e14dcfSSatish Balay   ierr = VecBoundGradientProjection(tao->gradient,tao->solution, tao->XL, tao->XU, tao->gradient); CHKERRQ(ierr);
143a7e14dcfSSatish Balay   ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm); CHKERRQ(ierr);
144a7e14dcfSSatish Balay 
145a7e14dcfSSatish Balay   if (PetscIsInfOrNanReal(tron->f) || PetscIsInfOrNanReal(tron->gnorm)) {
146a7e14dcfSSatish Balay     SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf pr NaN");
147a7e14dcfSSatish Balay   }
148a7e14dcfSSatish Balay 
149a7e14dcfSSatish Balay   if (tao->trust <= 0) {
150a7e14dcfSSatish Balay     tao->trust=PetscMax(tron->gnorm*tron->gnorm,1.0);
151a7e14dcfSSatish Balay   }
152a7e14dcfSSatish Balay 
153a7e14dcfSSatish Balay   tron->stepsize=tao->trust;
154a7e14dcfSSatish Balay   ierr = TaoMonitor(tao, iter, tron->f, tron->gnorm, 0.0, tron->stepsize, &reason); CHKERRQ(ierr);
155a7e14dcfSSatish Balay   while (reason==TAO_CONTINUE_ITERATING){
156a7e14dcfSSatish Balay 
157a7e14dcfSSatish Balay     ierr = TronGradientProjections(tao,tron); CHKERRQ(ierr);
158a7e14dcfSSatish Balay     f=tron->f; delta=tao->trust;
159a7e14dcfSSatish Balay     tron->n_free_last = tron->n_free;
160a7e14dcfSSatish Balay     ierr = TaoComputeHessian(tao,tao->solution,&tao->hessian, &tao->hessian_pre, &tron->matflag);CHKERRQ(ierr);
161a7e14dcfSSatish Balay 
162a7e14dcfSSatish Balay     ierr = ISGetSize(tron->Free_Local, &tron->n_free);  CHKERRQ(ierr);
163a7e14dcfSSatish Balay 
164a7e14dcfSSatish Balay     /* If no free variables */
165a7e14dcfSSatish Balay     if (tron->n_free == 0) {
166a7e14dcfSSatish Balay       actred=0;
167a7e14dcfSSatish Balay       PetscInfo(tao,"No free variables in tron iteration.");
168a7e14dcfSSatish Balay       break;
169a7e14dcfSSatish Balay 
170a7e14dcfSSatish Balay     }
171a7e14dcfSSatish Balay     /* use free_local to mask/submat gradient, hessian, stepdirection */
172a7e14dcfSSatish Balay     ierr = VecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->R);
173a7e14dcfSSatish Balay     CHKERRQ(ierr);
174a7e14dcfSSatish Balay     ierr = VecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->DXFree);
175a7e14dcfSSatish Balay     CHKERRQ(ierr);
176a7e14dcfSSatish Balay     ierr = VecSet(tron->DXFree,0.0); CHKERRQ(ierr);
177a7e14dcfSSatish Balay     ierr = VecScale(tron->R, -1.0); CHKERRQ(ierr);
178a7e14dcfSSatish Balay     ierr = MatGetSubMat(tao->hessian, tron->Free_Local, tron->diag, tao->subset_type, &tron->H_sub); CHKERRQ(ierr);
179a7e14dcfSSatish Balay     if (tao->hessian == tao->hessian_pre) {
180a7e14dcfSSatish Balay       ierr = MatDestroy(&tron->Hpre_sub); CHKERRQ(ierr);
181a7e14dcfSSatish Balay       ierr = PetscObjectReference((PetscObject)(tron->H_sub)); CHKERRQ(ierr);
182a7e14dcfSSatish Balay       tron->Hpre_sub = tron->H_sub;
183a7e14dcfSSatish Balay     } else {
184a7e14dcfSSatish Balay       ierr = MatGetSubMat(tao->hessian_pre, tron->Free_Local, tron->diag, tao->subset_type,&tron->Hpre_sub);
185a7e14dcfSSatish Balay       CHKERRQ(ierr);
186a7e14dcfSSatish Balay     }
187a7e14dcfSSatish Balay     ierr = KSPReset(tao->ksp); CHKERRQ(ierr);
188a7e14dcfSSatish Balay     ierr = KSPSetOperators(tao->ksp, tron->H_sub, tron->Hpre_sub, tron->matflag); CHKERRQ(ierr);
189a7e14dcfSSatish Balay     while (1) {
190a7e14dcfSSatish Balay 
191a7e14dcfSSatish Balay       /* Approximately solve the reduced linear system */
192a7e14dcfSSatish Balay       ierr = KSPSTCGSetRadius(tao->ksp,delta); CHKERRQ(ierr);
193a7e14dcfSSatish Balay       ierr = KSPSolve(tao->ksp, tron->R, tron->DXFree); CHKERRQ(ierr);
194a7e14dcfSSatish Balay       ierr = KSPGetIterationNumber(tao->ksp,&its); CHKERRQ(ierr);
195a7e14dcfSSatish Balay       tao->ksp_its+=its;
196a7e14dcfSSatish Balay       ierr = VecSet(tao->stepdirection,0.0); CHKERRQ(ierr);
197a7e14dcfSSatish Balay 
198a7e14dcfSSatish Balay       /* Add dxfree matrix to compute step direction vector */
199a7e14dcfSSatish Balay       ierr = VecReducedXPY(tao->stepdirection,tron->DXFree,tron->Free_Local); CHKERRQ(ierr);
200a7e14dcfSSatish Balay       if (0) {
201a7e14dcfSSatish Balay 	PetscReal rhs,stepnorm;
202a7e14dcfSSatish Balay 	ierr = VecNorm(tron->R,NORM_2,&rhs); CHKERRQ(ierr);
203a7e14dcfSSatish Balay 	ierr = VecNorm(tron->DXFree,NORM_2,&stepnorm); CHKERRQ(ierr);
204a7e14dcfSSatish Balay 	ierr = PetscPrintf(PETSC_COMM_WORLD,"|rhs|=%g\t|s|=%g\n",rhs,stepnorm); CHKERRQ(ierr);
205a7e14dcfSSatish Balay       }
206a7e14dcfSSatish Balay 
207a7e14dcfSSatish Balay 
208a7e14dcfSSatish Balay       ierr = VecDot(tao->gradient, tao->stepdirection, &gdx); CHKERRQ(ierr);
209a7e14dcfSSatish Balay       ierr = PetscInfo1(tao,"Expected decrease in function value: %14.12e\n",gdx);
210a7e14dcfSSatish Balay       CHKERRQ(ierr);
211a7e14dcfSSatish Balay 
212a7e14dcfSSatish Balay       ierr = VecCopy(tao->solution, tron->X_New); CHKERRQ(ierr);
213a7e14dcfSSatish Balay       ierr = VecCopy(tao->gradient, tron->G_New); CHKERRQ(ierr);
214a7e14dcfSSatish Balay 
215a7e14dcfSSatish Balay       stepsize=1.0;f_new=f;
216a7e14dcfSSatish Balay 
217a7e14dcfSSatish Balay       ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0); CHKERRQ(ierr);
218a7e14dcfSSatish Balay       ierr = TaoLineSearchApply(tao->linesearch, tron->X_New, &f_new, tron->G_New, tao->stepdirection,
219a7e14dcfSSatish Balay 				&stepsize,&ls_reason); CHKERRQ(ierr); CHKERRQ(ierr);
220a7e14dcfSSatish Balay       ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr);
221a7e14dcfSSatish Balay 
222a7e14dcfSSatish Balay       ierr = MatMult(tao->hessian, tao->stepdirection, tron->Work); CHKERRQ(ierr);
223a7e14dcfSSatish Balay       ierr = VecAYPX(tron->Work, 0.5, tao->gradient); CHKERRQ(ierr);
224a7e14dcfSSatish Balay       ierr = VecDot(tao->stepdirection, tron->Work, &prered); CHKERRQ(ierr);
225a7e14dcfSSatish Balay       actred = f_new - f;
226a7e14dcfSSatish Balay       if (actred<0) {
227a7e14dcfSSatish Balay 	rhok=PetscAbs(-actred/prered);
228a7e14dcfSSatish Balay       } else {
229a7e14dcfSSatish Balay 	rhok=0.0;
230a7e14dcfSSatish Balay       }
231a7e14dcfSSatish Balay 
232a7e14dcfSSatish Balay       /* Compare actual improvement to the quadratic model */
233a7e14dcfSSatish Balay       if (rhok > tron->eta1) { /* Accept the point */
234a7e14dcfSSatish Balay 	/* d = x_new - x */
235a7e14dcfSSatish Balay 	ierr = VecCopy(tron->X_New, tao->stepdirection); CHKERRQ(ierr);
236a7e14dcfSSatish Balay 	ierr = VecAXPY(tao->stepdirection, -1.0, tao->solution); CHKERRQ(ierr);
237a7e14dcfSSatish Balay 
238a7e14dcfSSatish Balay 	ierr = VecNorm(tao->stepdirection, NORM_2, &xdiff); CHKERRQ(ierr);
239a7e14dcfSSatish Balay 	xdiff *= stepsize;
240a7e14dcfSSatish Balay 
241a7e14dcfSSatish Balay 	/* Adjust trust region size */
242a7e14dcfSSatish Balay 	if (rhok < tron->eta2 ){
243a7e14dcfSSatish Balay 	  delta = PetscMin(xdiff,delta)*tron->sigma1;
244a7e14dcfSSatish Balay 	} else if (rhok > tron->eta4 ){
245a7e14dcfSSatish Balay 	  delta= PetscMin(xdiff,delta)*tron->sigma3;
246a7e14dcfSSatish Balay 	} else if (rhok > tron->eta3 ){
247a7e14dcfSSatish Balay 	  delta=PetscMin(xdiff,delta)*tron->sigma2;
248a7e14dcfSSatish Balay 	}
249a7e14dcfSSatish Balay 	ierr = VecBoundGradientProjection(tron->G_New,tron->X_New, tao->XL, tao->XU, tao->gradient); CHKERRQ(ierr);
250a7e14dcfSSatish Balay 	if (tron->Free_Local) {
251a7e14dcfSSatish Balay 	  ierr = ISDestroy(&tron->Free_Local); CHKERRQ(ierr);
252a7e14dcfSSatish Balay 	  tron->Free_Local=PETSC_NULL;
253a7e14dcfSSatish Balay 	}
254a7e14dcfSSatish Balay 	ierr = VecWhichBetween(tao->XL, tron->X_New, tao->XU, &tron->Free_Local); CHKERRQ(ierr);
255a7e14dcfSSatish Balay 	f=f_new;
256a7e14dcfSSatish Balay 	ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm); CHKERRQ(ierr);
257a7e14dcfSSatish Balay 	ierr = VecCopy(tron->X_New, tao->solution); CHKERRQ(ierr);
258a7e14dcfSSatish Balay 	ierr = VecCopy(tron->G_New, tao->gradient); CHKERRQ(ierr);
259a7e14dcfSSatish Balay 	break;
260a7e14dcfSSatish Balay       }
261a7e14dcfSSatish Balay       else if (delta <= 1e-30) {
262a7e14dcfSSatish Balay 	break;
263a7e14dcfSSatish Balay       }
264a7e14dcfSSatish Balay       else {
265a7e14dcfSSatish Balay 	delta /= 4.0;
266a7e14dcfSSatish Balay       }
267a7e14dcfSSatish Balay     } /* end linear solve loop */
268a7e14dcfSSatish Balay 
269a7e14dcfSSatish Balay 
270a7e14dcfSSatish Balay     tron->f=f; tron->actred=actred; tao->trust=delta;
271a7e14dcfSSatish Balay     iter++;
272a7e14dcfSSatish Balay     ierr = TaoMonitor(tao, iter, tron->f, tron->gnorm, 0.0, delta, &reason); CHKERRQ(ierr);
273a7e14dcfSSatish Balay   }  /* END MAIN LOOP  */
274a7e14dcfSSatish Balay 
275a7e14dcfSSatish Balay   PetscFunctionReturn(0);
276a7e14dcfSSatish Balay }
277a7e14dcfSSatish Balay 
278a7e14dcfSSatish Balay 
279a7e14dcfSSatish Balay #undef __FUNCT__
280a7e14dcfSSatish Balay #define __FUNCT__ "TronGradientProjections"
281a7e14dcfSSatish Balay static PetscErrorCode TronGradientProjections(TaoSolver tao,TAO_TRON *tron)
282a7e14dcfSSatish Balay {
283a7e14dcfSSatish Balay   PetscErrorCode ierr;
284a7e14dcfSSatish Balay   PetscInt i;
285a7e14dcfSSatish Balay   TaoLineSearchTerminationReason ls_reason;
286a7e14dcfSSatish Balay   PetscReal actred=-1.0,actred_max=0.0;
287a7e14dcfSSatish Balay   PetscReal f_new;
288a7e14dcfSSatish Balay   /*
289a7e14dcfSSatish Balay      The gradient and function value passed into and out of this
290a7e14dcfSSatish Balay      routine should be current and correct.
291a7e14dcfSSatish Balay 
292a7e14dcfSSatish Balay      The free, active, and binding variables should be already identified
293a7e14dcfSSatish Balay   */
294a7e14dcfSSatish Balay 
295a7e14dcfSSatish Balay   PetscFunctionBegin;
296a7e14dcfSSatish Balay   if (tron->Free_Local) {
297a7e14dcfSSatish Balay     ierr = ISDestroy(&tron->Free_Local); CHKERRQ(ierr);
298a7e14dcfSSatish Balay     tron->Free_Local = PETSC_NULL;
299a7e14dcfSSatish Balay   }
300a7e14dcfSSatish Balay   ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local); CHKERRQ(ierr);
301a7e14dcfSSatish Balay 
302a7e14dcfSSatish Balay   for (i=0;i<tron->maxgpits;i++){
303a7e14dcfSSatish Balay 
304a7e14dcfSSatish Balay     if ( -actred <= (tron->pg_ftol)*actred_max) break;
305a7e14dcfSSatish Balay 
306a7e14dcfSSatish Balay     tron->gp_iterates++; tron->total_gp_its++;
307a7e14dcfSSatish Balay     f_new=tron->f;
308a7e14dcfSSatish Balay 
309a7e14dcfSSatish Balay     ierr = VecCopy(tao->gradient, tao->stepdirection); CHKERRQ(ierr);
310a7e14dcfSSatish Balay     ierr = VecScale(tao->stepdirection, -1.0); CHKERRQ(ierr);
311a7e14dcfSSatish Balay     ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,tron->pgstepsize); CHKERRQ(ierr);
312a7e14dcfSSatish Balay     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f_new, tao->gradient, tao->stepdirection,
313a7e14dcfSSatish Balay 			      &tron->pgstepsize, &ls_reason); CHKERRQ(ierr);
314a7e14dcfSSatish Balay     ierr = TaoAddLineSearchCounts(tao); CHKERRQ(ierr);
315a7e14dcfSSatish Balay 
316a7e14dcfSSatish Balay 
317a7e14dcfSSatish Balay     /* Update the iterate */
318a7e14dcfSSatish Balay     actred = f_new - tron->f;
319a7e14dcfSSatish Balay     actred_max = PetscMax(actred_max,-(f_new - tron->f));
320a7e14dcfSSatish Balay     tron->f = f_new;
321a7e14dcfSSatish Balay     if (tron->Free_Local) {
322a7e14dcfSSatish Balay       ierr = ISDestroy(&tron->Free_Local); CHKERRQ(ierr);
323a7e14dcfSSatish Balay       tron->Free_Local = PETSC_NULL;
324a7e14dcfSSatish Balay     }
325a7e14dcfSSatish Balay     ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local); CHKERRQ(ierr);
326a7e14dcfSSatish Balay   }
327a7e14dcfSSatish Balay 
328a7e14dcfSSatish Balay   PetscFunctionReturn(0);
329a7e14dcfSSatish Balay }
330a7e14dcfSSatish Balay 
331a7e14dcfSSatish Balay #undef __FUNCT__
332a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeDual_TRON"
333a7e14dcfSSatish Balay static PetscErrorCode TaoComputeDual_TRON(TaoSolver tao, Vec DXL, Vec DXU) {
334a7e14dcfSSatish Balay 
335a7e14dcfSSatish Balay   TAO_TRON *tron = (TAO_TRON *)tao->data;
336a7e14dcfSSatish Balay   PetscErrorCode       ierr;
337a7e14dcfSSatish Balay 
338a7e14dcfSSatish Balay   PetscFunctionBegin;
339a7e14dcfSSatish Balay 
340a7e14dcfSSatish Balay   PetscValidHeaderSpecific(tao,TAOSOLVER_CLASSID,1);
341a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXL,VEC_CLASSID,2);
342a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXU,VEC_CLASSID,3);
343a7e14dcfSSatish Balay 
344a7e14dcfSSatish Balay   if (!tron->Work || !tao->gradient) {
345a7e14dcfSSatish Balay       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Dual variables don't exist yet or no longer exist.\n");
346a7e14dcfSSatish Balay   }
347a7e14dcfSSatish Balay 
348a7e14dcfSSatish Balay   ierr = VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tron->Work); CHKERRQ(ierr);
349a7e14dcfSSatish Balay   ierr = VecCopy(tron->Work,DXL); CHKERRQ(ierr);
350a7e14dcfSSatish Balay   ierr = VecAXPY(DXL,-1.0,tao->gradient); CHKERRQ(ierr);
351a7e14dcfSSatish Balay   ierr = VecSet(DXU,0.0); CHKERRQ(ierr);
352a7e14dcfSSatish Balay   ierr = VecPointwiseMax(DXL,DXL,DXU); CHKERRQ(ierr);
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay   ierr = VecCopy(tao->gradient,DXU); CHKERRQ(ierr);
355a7e14dcfSSatish Balay   ierr = VecAXPY(DXU,-1.0,tron->Work); CHKERRQ(ierr);
356a7e14dcfSSatish Balay   ierr = VecSet(tron->Work,0.0); CHKERRQ(ierr);
357a7e14dcfSSatish Balay   ierr = VecPointwiseMin(DXU,tron->Work,DXU); CHKERRQ(ierr);
358a7e14dcfSSatish Balay 
359a7e14dcfSSatish Balay   PetscFunctionReturn(0);
360a7e14dcfSSatish Balay }
361a7e14dcfSSatish Balay 
362a7e14dcfSSatish Balay /*------------------------------------------------------------*/
363a7e14dcfSSatish Balay EXTERN_C_BEGIN
364a7e14dcfSSatish Balay #undef __FUNCT__
365a7e14dcfSSatish Balay #define __FUNCT__ "TaoCreate_TRON"
366a7e14dcfSSatish Balay PetscErrorCode TaoCreate_TRON(TaoSolver tao)
367a7e14dcfSSatish Balay {
368a7e14dcfSSatish Balay   TAO_TRON *tron;
369a7e14dcfSSatish Balay   PetscErrorCode   ierr;
370a7e14dcfSSatish Balay   const char *morethuente_type = TAOLINESEARCH_MT;
371a7e14dcfSSatish Balay   PetscFunctionBegin;
372a7e14dcfSSatish Balay 
373a7e14dcfSSatish Balay   tao->ops->setup = TaoSetup_TRON;
374a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_TRON;
375a7e14dcfSSatish Balay   tao->ops->view = TaoView_TRON;
376a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_TRON;
377a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_TRON;
378a7e14dcfSSatish Balay   tao->ops->computedual = TaoComputeDual_TRON;
379a7e14dcfSSatish Balay 
380*3c9e27cfSGeoffrey Irving   ierr = PetscNewLog(tao,&tron); CHKERRQ(ierr);
381a7e14dcfSSatish Balay 
382a7e14dcfSSatish Balay   tao->max_it = 50;
383a7e14dcfSSatish Balay   tao->fatol = 1e-10;
384a7e14dcfSSatish Balay   tao->frtol = 1e-10;
385a7e14dcfSSatish Balay   tao->data = (void*)tron;
386a7e14dcfSSatish Balay   tao->steptol = 1e-12;
387a7e14dcfSSatish Balay   tao->trust0       = 1.0;
388a7e14dcfSSatish Balay 
389a7e14dcfSSatish Balay   /* Initialize pointers and variables */
390a7e14dcfSSatish Balay   tron->n            = 0;
391a7e14dcfSSatish Balay   tron->maxgpits     = 3;
392a7e14dcfSSatish Balay   tron->pg_ftol      = 0.001;
393a7e14dcfSSatish Balay 
394a7e14dcfSSatish Balay   tron->eta1         = 1.0e-4;
395a7e14dcfSSatish Balay   tron->eta2         = 0.25;
396a7e14dcfSSatish Balay   tron->eta3         = 0.50;
397a7e14dcfSSatish Balay   tron->eta4         = 0.90;
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay   tron->sigma1       = 0.5;
400a7e14dcfSSatish Balay   tron->sigma2       = 2.0;
401a7e14dcfSSatish Balay   tron->sigma3       = 4.0;
402a7e14dcfSSatish Balay 
403a7e14dcfSSatish Balay   tron->gp_iterates  = 0; /* Cumulative number */
404a7e14dcfSSatish Balay   tron->total_gp_its = 0;
405a7e14dcfSSatish Balay 
406a7e14dcfSSatish Balay   tron->n_free       = 0;
407a7e14dcfSSatish Balay 
408a7e14dcfSSatish Balay   tron->DXFree=PETSC_NULL;
409a7e14dcfSSatish Balay   tron->R=PETSC_NULL;
410a7e14dcfSSatish Balay   tron->X_New=PETSC_NULL;
411a7e14dcfSSatish Balay   tron->G_New=PETSC_NULL;
412a7e14dcfSSatish Balay   tron->Work=PETSC_NULL;
413a7e14dcfSSatish Balay   tron->Free_Local=PETSC_NULL;
414a7e14dcfSSatish Balay   tron->H_sub=PETSC_NULL;
415a7e14dcfSSatish Balay   tron->Hpre_sub=PETSC_NULL;
416a7e14dcfSSatish Balay   tao->subset_type = TAO_SUBSET_SUBVEC;
417a7e14dcfSSatish Balay 
418a7e14dcfSSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch); CHKERRQ(ierr);
419a7e14dcfSSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type); CHKERRQ(ierr);
420a7e14dcfSSatish Balay   ierr = TaoLineSearchUseTaoSolverRoutines(tao->linesearch,tao); CHKERRQ(ierr);
421a7e14dcfSSatish Balay 
422a7e14dcfSSatish Balay   ierr = KSPCreate(((PetscObject)tao)->comm, &tao->ksp); CHKERRQ(ierr);
423a7e14dcfSSatish Balay   ierr = KSPSetType(tao->ksp,KSPSTCG); CHKERRQ(ierr);
424a7e14dcfSSatish Balay 
425a7e14dcfSSatish Balay   PetscFunctionReturn(0);
426a7e14dcfSSatish Balay }
427a7e14dcfSSatish Balay EXTERN_C_END
428