xref: /petsc/src/tao/bound/impls/tron/tron.c (revision 8f1e51d3981cfc186935185b9917d9c649dc861f)
1aaa7dc30SBarry Smith #include <../src/tao/bound/impls/tron/tron.h>
2aaa7dc30SBarry Smith #include <../src/tao/matrix/submatfree.h>
3a7e14dcfSSatish Balay 
4a7e14dcfSSatish Balay 
5a7e14dcfSSatish Balay /* TRON Routines */
6441846f8SBarry Smith static PetscErrorCode TronGradientProjections(Tao,TAO_TRON*);
7a7e14dcfSSatish Balay /*------------------------------------------------------------*/
8a7e14dcfSSatish Balay #undef __FUNCT__
9a7e14dcfSSatish Balay #define __FUNCT__ "TaoDestroy_TRON"
10441846f8SBarry Smith static PetscErrorCode TaoDestroy_TRON(Tao tao)
11a7e14dcfSSatish Balay {
12a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
13a7e14dcfSSatish Balay   PetscErrorCode ierr;
14a7e14dcfSSatish Balay 
15a7e14dcfSSatish Balay   PetscFunctionBegin;
16a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->X_New);CHKERRQ(ierr);
17a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->G_New);CHKERRQ(ierr);
18a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->Work);CHKERRQ(ierr);
19a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->DXFree);CHKERRQ(ierr);
20a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->R);CHKERRQ(ierr);
21a7e14dcfSSatish Balay   ierr = VecDestroy(&tron->diag);CHKERRQ(ierr);
22a7e14dcfSSatish Balay   ierr = VecScatterDestroy(&tron->scatter);CHKERRQ(ierr);
23a7e14dcfSSatish Balay   ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr);
24a7e14dcfSSatish Balay   ierr = MatDestroy(&tron->H_sub);CHKERRQ(ierr);
25a7e14dcfSSatish Balay   ierr = MatDestroy(&tron->Hpre_sub);CHKERRQ(ierr);
26302440fdSBarry Smith   ierr = PetscFree(tao->data);CHKERRQ(ierr);
27a7e14dcfSSatish Balay   PetscFunctionReturn(0);
28a7e14dcfSSatish Balay }
29a7e14dcfSSatish Balay 
30a7e14dcfSSatish Balay /*------------------------------------------------------------*/
31a7e14dcfSSatish Balay #undef __FUNCT__
32a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetFromOptions_TRON"
334416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_TRON(PetscOptionItems *PetscOptionsObject,Tao tao)
34a7e14dcfSSatish Balay {
35a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
36a7e14dcfSSatish Balay   PetscErrorCode ierr;
37a7e14dcfSSatish Balay   PetscBool      flg;
38a7e14dcfSSatish Balay 
39a7e14dcfSSatish Balay   PetscFunctionBegin;
401a1499c8SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Newton Trust Region Method for bound constrained optimization");CHKERRQ(ierr);
411522df2eSJason Sarich   ierr = PetscOptionsInt("-tao_tron_maxgpits","maximum number of gradient projections per TRON iterate","TaoSetMaxGPIts",tron->maxgpits,&tron->maxgpits,&flg);CHKERRQ(ierr);
42a7e14dcfSSatish Balay   ierr = PetscOptionsTail();CHKERRQ(ierr);
43a7e14dcfSSatish Balay   ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr);
44a7e14dcfSSatish Balay   ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr);
45a7e14dcfSSatish Balay   PetscFunctionReturn(0);
46a7e14dcfSSatish Balay }
47a7e14dcfSSatish Balay 
48a7e14dcfSSatish Balay /*------------------------------------------------------------*/
49a7e14dcfSSatish Balay #undef __FUNCT__
50a7e14dcfSSatish Balay #define __FUNCT__ "TaoView_TRON"
51441846f8SBarry Smith static PetscErrorCode TaoView_TRON(Tao tao, PetscViewer viewer)
52a7e14dcfSSatish Balay {
53a7e14dcfSSatish Balay   TAO_TRON         *tron = (TAO_TRON *)tao->data;
54a7e14dcfSSatish Balay   PetscBool        isascii;
55a7e14dcfSSatish Balay   PetscErrorCode   ierr;
56a7e14dcfSSatish Balay 
57a7e14dcfSSatish Balay   PetscFunctionBegin;
58a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
59a7e14dcfSSatish Balay   if (isascii) {
60a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
61a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"Total PG its: %D,",tron->total_gp_its);CHKERRQ(ierr);
6247a47007SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"PG tolerance: %g \n",(double)tron->pg_ftol);CHKERRQ(ierr);
63a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
64a7e14dcfSSatish Balay   }
65a7e14dcfSSatish Balay   PetscFunctionReturn(0);
66a7e14dcfSSatish Balay }
67a7e14dcfSSatish Balay 
68a7e14dcfSSatish Balay 
69a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
70a7e14dcfSSatish Balay #undef __FUNCT__
71a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetup_TRON"
72441846f8SBarry Smith static PetscErrorCode TaoSetup_TRON(Tao tao)
73a7e14dcfSSatish Balay {
74a7e14dcfSSatish Balay   PetscErrorCode ierr;
75a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
76a7e14dcfSSatish Balay 
77a7e14dcfSSatish Balay   PetscFunctionBegin;
78a7e14dcfSSatish Balay 
79a7e14dcfSSatish Balay   /* Allocate some arrays */
80a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->diag);CHKERRQ(ierr);
81a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->X_New);CHKERRQ(ierr);
82a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->G_New);CHKERRQ(ierr);
83a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tron->Work);CHKERRQ(ierr);
84a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tao->gradient);CHKERRQ(ierr);
85a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution, &tao->stepdirection);CHKERRQ(ierr);
86a7e14dcfSSatish Balay   if (!tao->XL) {
87a7e14dcfSSatish Balay       ierr = VecDuplicate(tao->solution, &tao->XL);CHKERRQ(ierr);
88e270355aSBarry Smith       ierr = VecSet(tao->XL, PETSC_NINFINITY);CHKERRQ(ierr);
89a7e14dcfSSatish Balay   }
90a7e14dcfSSatish Balay   if (!tao->XU) {
91a7e14dcfSSatish Balay       ierr = VecDuplicate(tao->solution, &tao->XU);CHKERRQ(ierr);
92e270355aSBarry Smith       ierr = VecSet(tao->XU, PETSC_INFINITY);CHKERRQ(ierr);
93a7e14dcfSSatish Balay   }
94a7e14dcfSSatish Balay   PetscFunctionReturn(0);
95a7e14dcfSSatish Balay }
96a7e14dcfSSatish Balay 
97a7e14dcfSSatish Balay 
98a7e14dcfSSatish Balay 
99a7e14dcfSSatish Balay #undef __FUNCT__
100a7e14dcfSSatish Balay #define __FUNCT__ "TaoSolve_TRON"
101441846f8SBarry Smith static PetscErrorCode TaoSolve_TRON(Tao tao)
10247a47007SBarry Smith {
103a7e14dcfSSatish Balay   TAO_TRON                     *tron = (TAO_TRON *)tao->data;
104a7e14dcfSSatish Balay   PetscErrorCode               ierr;
1058931d482SJason Sarich   PetscInt                     its;
106e4cb33bbSBarry Smith   TaoConvergedReason           reason = TAO_CONTINUE_ITERATING;
107e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING;
108a7e14dcfSSatish Balay   PetscReal                    prered,actred,delta,f,f_new,rhok,gdx,xdiff,stepsize;
10947a47007SBarry Smith 
110a7e14dcfSSatish Balay   PetscFunctionBegin;
111a7e14dcfSSatish Balay   tron->pgstepsize=1.0;
112a7e14dcfSSatish Balay   tao->trust = tao->trust0;
113a7e14dcfSSatish Balay   /*   Project the current point onto the feasible set */
114a7e14dcfSSatish Balay   ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr);
115a7e14dcfSSatish Balay   ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr);
116a7e14dcfSSatish Balay   ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr);
117a7e14dcfSSatish Balay 
118a7e14dcfSSatish Balay   ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&tron->f,tao->gradient);CHKERRQ(ierr);
119a7e14dcfSSatish Balay   ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr);
12053506e15SBarry Smith 
121a7e14dcfSSatish Balay   ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr);
122a7e14dcfSSatish Balay 
123a7e14dcfSSatish Balay   /* Project the gradient and calculate the norm */
124a7e14dcfSSatish Balay   ierr = VecBoundGradientProjection(tao->gradient,tao->solution, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr);
125a7e14dcfSSatish Balay   ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr);
126a7e14dcfSSatish Balay 
12753506e15SBarry Smith   if (PetscIsInfOrNanReal(tron->f) || PetscIsInfOrNanReal(tron->gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf pr NaN");
128a7e14dcfSSatish Balay   if (tao->trust <= 0) {
129a7e14dcfSSatish Balay     tao->trust=PetscMax(tron->gnorm*tron->gnorm,1.0);
130a7e14dcfSSatish Balay   }
131a7e14dcfSSatish Balay 
132a7e14dcfSSatish Balay   tron->stepsize=tao->trust;
1338931d482SJason Sarich   ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, tron->stepsize, &reason);CHKERRQ(ierr);
134a7e14dcfSSatish Balay   while (reason==TAO_CONTINUE_ITERATING){
135ae93cb3cSJason Sarich     tao->ksp_its=0;
136a7e14dcfSSatish Balay     ierr = TronGradientProjections(tao,tron);CHKERRQ(ierr);
137a7e14dcfSSatish Balay     f=tron->f; delta=tao->trust;
138a7e14dcfSSatish Balay     tron->n_free_last = tron->n_free;
139ffad9901SBarry Smith     ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr);
140a7e14dcfSSatish Balay 
141a7e14dcfSSatish Balay     ierr = ISGetSize(tron->Free_Local, &tron->n_free);CHKERRQ(ierr);
142a7e14dcfSSatish Balay 
143a7e14dcfSSatish Balay     /* If no free variables */
144a7e14dcfSSatish Balay     if (tron->n_free == 0) {
145955c1f14SBarry Smith       ierr = PetscInfo(tao,"No free variables in tron iteration.\n");CHKERRQ(ierr);
14655723ba5SJason Sarich       ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr);
1478931d482SJason Sarich       ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, delta, &reason);CHKERRQ(ierr);
14855723ba5SJason Sarich       if (!reason) {
14955723ba5SJason Sarich         reason = TAO_CONVERGED_STEPTOL;
15055723ba5SJason Sarich         ierr = TaoSetConvergedReason(tao,reason);CHKERRQ(ierr);
15155723ba5SJason Sarich       }
152a7e14dcfSSatish Balay       break;
153a7e14dcfSSatish Balay     }
154a7e14dcfSSatish Balay     /* use free_local to mask/submat gradient, hessian, stepdirection */
155b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->R);CHKERRQ(ierr);
156b98f30f2SJason Sarich     ierr = TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->DXFree);CHKERRQ(ierr);
157a7e14dcfSSatish Balay     ierr = VecSet(tron->DXFree,0.0);CHKERRQ(ierr);
158a7e14dcfSSatish Balay     ierr = VecScale(tron->R, -1.0);CHKERRQ(ierr);
159b98f30f2SJason Sarich     ierr = TaoMatGetSubMat(tao->hessian, tron->Free_Local, tron->diag, tao->subset_type, &tron->H_sub);CHKERRQ(ierr);
160a7e14dcfSSatish Balay     if (tao->hessian == tao->hessian_pre) {
161a7e14dcfSSatish Balay       ierr = MatDestroy(&tron->Hpre_sub);CHKERRQ(ierr);
162a7e14dcfSSatish Balay       ierr = PetscObjectReference((PetscObject)(tron->H_sub));CHKERRQ(ierr);
163a7e14dcfSSatish Balay       tron->Hpre_sub = tron->H_sub;
164a7e14dcfSSatish Balay     } else {
165b98f30f2SJason Sarich       ierr = TaoMatGetSubMat(tao->hessian_pre, tron->Free_Local, tron->diag, tao->subset_type,&tron->Hpre_sub);CHKERRQ(ierr);
166a7e14dcfSSatish Balay     }
167a7e14dcfSSatish Balay     ierr = KSPReset(tao->ksp);CHKERRQ(ierr);
16823ee1639SBarry Smith     ierr = KSPSetOperators(tao->ksp, tron->H_sub, tron->Hpre_sub);CHKERRQ(ierr);
169a7e14dcfSSatish Balay     while (1) {
170a7e14dcfSSatish Balay 
171a7e14dcfSSatish Balay       /* Approximately solve the reduced linear system */
172*8f1e51d3STodd Munson       ierr = KSPCGSetRadius(tao->ksp,delta);CHKERRQ(ierr);
173d8ec8e84SJason Sarich 
174a7e14dcfSSatish Balay       ierr = KSPSolve(tao->ksp, tron->R, tron->DXFree);CHKERRQ(ierr);
175a7e14dcfSSatish Balay       ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr);
176a7e14dcfSSatish Balay       tao->ksp_its+=its;
177ae93cb3cSJason Sarich       tao->ksp_tot_its+=its;
178a7e14dcfSSatish Balay       ierr = VecSet(tao->stepdirection,0.0);CHKERRQ(ierr);
179a7e14dcfSSatish Balay 
180a7e14dcfSSatish Balay       /* Add dxfree matrix to compute step direction vector */
1814473680cSBarry Smith       ierr = VecISAXPY(tao->stepdirection,tron->Free_Local,1.0,tron->DXFree);CHKERRQ(ierr);
182a7e14dcfSSatish Balay 
183a7e14dcfSSatish Balay       ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr);
184335036cbSBarry Smith       ierr = PetscInfo1(tao,"Expected decrease in function value: %14.12e\n",(double)gdx);CHKERRQ(ierr);
185a7e14dcfSSatish Balay 
186a7e14dcfSSatish Balay       ierr = VecCopy(tao->solution, tron->X_New);CHKERRQ(ierr);
187a7e14dcfSSatish Balay       ierr = VecCopy(tao->gradient, tron->G_New);CHKERRQ(ierr);
188a7e14dcfSSatish Balay 
189a7e14dcfSSatish Balay       stepsize=1.0;f_new=f;
190a7e14dcfSSatish Balay 
191a7e14dcfSSatish Balay       ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr);
19247a47007SBarry Smith       ierr = TaoLineSearchApply(tao->linesearch, tron->X_New, &f_new, tron->G_New, tao->stepdirection,&stepsize,&ls_reason);CHKERRQ(ierr);CHKERRQ(ierr);
193a7e14dcfSSatish Balay       ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
194a7e14dcfSSatish Balay 
195a7e14dcfSSatish Balay       ierr = MatMult(tao->hessian, tao->stepdirection, tron->Work);CHKERRQ(ierr);
196a7e14dcfSSatish Balay       ierr = VecAYPX(tron->Work, 0.5, tao->gradient);CHKERRQ(ierr);
197a7e14dcfSSatish Balay       ierr = VecDot(tao->stepdirection, tron->Work, &prered);CHKERRQ(ierr);
198a7e14dcfSSatish Balay       actred = f_new - f;
199a7e14dcfSSatish Balay       if (actred<0) {
200a7e14dcfSSatish Balay         rhok=PetscAbs(-actred/prered);
201a7e14dcfSSatish Balay       } else {
202a7e14dcfSSatish Balay         rhok=0.0;
203a7e14dcfSSatish Balay       }
204a7e14dcfSSatish Balay 
205a7e14dcfSSatish Balay       /* Compare actual improvement to the quadratic model */
206a7e14dcfSSatish Balay       if (rhok > tron->eta1) { /* Accept the point */
207a7e14dcfSSatish Balay         /* d = x_new - x */
208a7e14dcfSSatish Balay         ierr = VecCopy(tron->X_New, tao->stepdirection);CHKERRQ(ierr);
209a7e14dcfSSatish Balay         ierr = VecAXPY(tao->stepdirection, -1.0, tao->solution);CHKERRQ(ierr);
210a7e14dcfSSatish Balay 
211a7e14dcfSSatish Balay         ierr = VecNorm(tao->stepdirection, NORM_2, &xdiff);CHKERRQ(ierr);
212a7e14dcfSSatish Balay         xdiff *= stepsize;
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay         /* Adjust trust region size */
215a7e14dcfSSatish Balay         if (rhok < tron->eta2 ){
216a7e14dcfSSatish Balay           delta = PetscMin(xdiff,delta)*tron->sigma1;
217a7e14dcfSSatish Balay         } else if (rhok > tron->eta4 ){
218a7e14dcfSSatish Balay           delta= PetscMin(xdiff,delta)*tron->sigma3;
219a7e14dcfSSatish Balay         } else if (rhok > tron->eta3 ){
220a7e14dcfSSatish Balay           delta=PetscMin(xdiff,delta)*tron->sigma2;
221a7e14dcfSSatish Balay         }
222a7e14dcfSSatish Balay         ierr = VecBoundGradientProjection(tron->G_New,tron->X_New, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr);
223a7e14dcfSSatish Balay         if (tron->Free_Local) {
224a7e14dcfSSatish Balay           ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr);
225a7e14dcfSSatish Balay         }
226a7e14dcfSSatish Balay         ierr = VecWhichBetween(tao->XL, tron->X_New, tao->XU, &tron->Free_Local);CHKERRQ(ierr);
227a7e14dcfSSatish Balay         f=f_new;
228a7e14dcfSSatish Balay         ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr);
229a7e14dcfSSatish Balay         ierr = VecCopy(tron->X_New, tao->solution);CHKERRQ(ierr);
230a7e14dcfSSatish Balay         ierr = VecCopy(tron->G_New, tao->gradient);CHKERRQ(ierr);
231a7e14dcfSSatish Balay         break;
232a7e14dcfSSatish Balay       }
233a7e14dcfSSatish Balay       else if (delta <= 1e-30) {
234a7e14dcfSSatish Balay         break;
235a7e14dcfSSatish Balay       }
236a7e14dcfSSatish Balay       else {
237a7e14dcfSSatish Balay         delta /= 4.0;
238a7e14dcfSSatish Balay       }
239a7e14dcfSSatish Balay     } /* end linear solve loop */
240a7e14dcfSSatish Balay 
241a7e14dcfSSatish Balay     tron->f=f; tron->actred=actred; tao->trust=delta;
2428931d482SJason Sarich     tao->niter++;
2438931d482SJason Sarich     ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, delta, &reason);CHKERRQ(ierr);
244a7e14dcfSSatish Balay   }  /* END MAIN LOOP  */
245a7e14dcfSSatish Balay 
246a7e14dcfSSatish Balay   PetscFunctionReturn(0);
247a7e14dcfSSatish Balay }
248a7e14dcfSSatish Balay 
249a7e14dcfSSatish Balay 
250a7e14dcfSSatish Balay #undef __FUNCT__
251a7e14dcfSSatish Balay #define __FUNCT__ "TronGradientProjections"
252441846f8SBarry Smith static PetscErrorCode TronGradientProjections(Tao tao,TAO_TRON *tron)
253a7e14dcfSSatish Balay {
254a7e14dcfSSatish Balay   PetscErrorCode                 ierr;
255a7e14dcfSSatish Balay   PetscInt                       i;
256e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_reason;
257a7e14dcfSSatish Balay   PetscReal                      actred=-1.0,actred_max=0.0;
258a7e14dcfSSatish Balay   PetscReal                      f_new;
259a7e14dcfSSatish Balay   /*
260a7e14dcfSSatish Balay      The gradient and function value passed into and out of this
261a7e14dcfSSatish Balay      routine should be current and correct.
262a7e14dcfSSatish Balay 
263a7e14dcfSSatish Balay      The free, active, and binding variables should be already identified
264a7e14dcfSSatish Balay   */
265a7e14dcfSSatish Balay   PetscFunctionBegin;
266a7e14dcfSSatish Balay   if (tron->Free_Local) {
267a7e14dcfSSatish Balay     ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr);
268a7e14dcfSSatish Balay   }
269a7e14dcfSSatish Balay   ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr);
270a7e14dcfSSatish Balay 
271a7e14dcfSSatish Balay   for (i=0;i<tron->maxgpits;i++){
272a7e14dcfSSatish Balay 
273a7e14dcfSSatish Balay     if ( -actred <= (tron->pg_ftol)*actred_max) break;
274a7e14dcfSSatish Balay 
275a7e14dcfSSatish Balay     tron->gp_iterates++; tron->total_gp_its++;
276a7e14dcfSSatish Balay     f_new=tron->f;
277a7e14dcfSSatish Balay 
278a7e14dcfSSatish Balay     ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr);
279a7e14dcfSSatish Balay     ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr);
280a7e14dcfSSatish Balay     ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,tron->pgstepsize);CHKERRQ(ierr);
281a7e14dcfSSatish Balay     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f_new, tao->gradient, tao->stepdirection,
282a7e14dcfSSatish Balay                               &tron->pgstepsize, &ls_reason);CHKERRQ(ierr);
283a7e14dcfSSatish Balay     ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr);
284a7e14dcfSSatish Balay 
285a7e14dcfSSatish Balay 
286a7e14dcfSSatish Balay     /* Update the iterate */
287a7e14dcfSSatish Balay     actred = f_new - tron->f;
288a7e14dcfSSatish Balay     actred_max = PetscMax(actred_max,-(f_new - tron->f));
289a7e14dcfSSatish Balay     tron->f = f_new;
290a7e14dcfSSatish Balay     if (tron->Free_Local) {
291a7e14dcfSSatish Balay       ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr);
292a7e14dcfSSatish Balay     }
293a7e14dcfSSatish Balay     ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr);
294a7e14dcfSSatish Balay   }
295a7e14dcfSSatish Balay 
296a7e14dcfSSatish Balay   PetscFunctionReturn(0);
297a7e14dcfSSatish Balay }
298a7e14dcfSSatish Balay 
299a7e14dcfSSatish Balay #undef __FUNCT__
300a7e14dcfSSatish Balay #define __FUNCT__ "TaoComputeDual_TRON"
301441846f8SBarry Smith static PetscErrorCode TaoComputeDual_TRON(Tao tao, Vec DXL, Vec DXU) {
302a7e14dcfSSatish Balay 
303a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
304a7e14dcfSSatish Balay   PetscErrorCode ierr;
305a7e14dcfSSatish Balay 
306a7e14dcfSSatish Balay   PetscFunctionBegin;
307441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
308a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXL,VEC_CLASSID,2);
309a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXU,VEC_CLASSID,3);
31047a47007SBarry Smith   if (!tron->Work || !tao->gradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Dual variables don't exist yet or no longer exist.\n");
311a7e14dcfSSatish Balay 
312a7e14dcfSSatish Balay   ierr = VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tron->Work);CHKERRQ(ierr);
313a7e14dcfSSatish Balay   ierr = VecCopy(tron->Work,DXL);CHKERRQ(ierr);
314a7e14dcfSSatish Balay   ierr = VecAXPY(DXL,-1.0,tao->gradient);CHKERRQ(ierr);
315a7e14dcfSSatish Balay   ierr = VecSet(DXU,0.0);CHKERRQ(ierr);
316a7e14dcfSSatish Balay   ierr = VecPointwiseMax(DXL,DXL,DXU);CHKERRQ(ierr);
317a7e14dcfSSatish Balay 
318a7e14dcfSSatish Balay   ierr = VecCopy(tao->gradient,DXU);CHKERRQ(ierr);
319a7e14dcfSSatish Balay   ierr = VecAXPY(DXU,-1.0,tron->Work);CHKERRQ(ierr);
320a7e14dcfSSatish Balay   ierr = VecSet(tron->Work,0.0);CHKERRQ(ierr);
321a7e14dcfSSatish Balay   ierr = VecPointwiseMin(DXU,tron->Work,DXU);CHKERRQ(ierr);
322a7e14dcfSSatish Balay   PetscFunctionReturn(0);
323a7e14dcfSSatish Balay }
324a7e14dcfSSatish Balay 
325a7e14dcfSSatish Balay /*------------------------------------------------------------*/
3261522df2eSJason Sarich /*MC
3271522df2eSJason Sarich   TAOTRON - The TRON algorithm is an active-set Newton trust region method
3281522df2eSJason Sarich   for bound-constrained minimization.
3291522df2eSJason Sarich 
3301522df2eSJason Sarich   Options Database Keys:
3311522df2eSJason Sarich + -tao_tron_maxgpits - maximum number of gradient projections per TRON iterate
3321522df2eSJason Sarich - -tao_subset_type - "subvec","mask","matrix-free", strategies for handling active-sets
3331522df2eSJason Sarich 
3341eb8069cSJason Sarich   Level: beginner
3351522df2eSJason Sarich M*/
336a7e14dcfSSatish Balay #undef __FUNCT__
337a7e14dcfSSatish Balay #define __FUNCT__ "TaoCreate_TRON"
338728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_TRON(Tao tao)
339a7e14dcfSSatish Balay {
340a7e14dcfSSatish Balay   TAO_TRON       *tron;
341a7e14dcfSSatish Balay   PetscErrorCode ierr;
3428caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
343a7e14dcfSSatish Balay 
34447a47007SBarry Smith   PetscFunctionBegin;
345a7e14dcfSSatish Balay   tao->ops->setup = TaoSetup_TRON;
346a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_TRON;
347a7e14dcfSSatish Balay   tao->ops->view = TaoView_TRON;
348a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_TRON;
349a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_TRON;
350a7e14dcfSSatish Balay   tao->ops->computedual = TaoComputeDual_TRON;
351a7e14dcfSSatish Balay 
3523c9e27cfSGeoffrey Irving   ierr = PetscNewLog(tao,&tron);CHKERRQ(ierr);
3536f4723b1SBarry Smith   tao->data = (void*)tron;
3546552cf8aSJason Sarich 
3556552cf8aSJason Sarich   /* Override default settings (unless already changed) */
3566552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 50;
3576552cf8aSJason Sarich 
3586552cf8aSJason Sarich #if defined(PETSC_USE_REAL_SINGLE)
3596552cf8aSJason Sarich   if (!tao->steptol_changed) tao->steptol = 1.0e-6;
3606552cf8aSJason Sarich #else
3616552cf8aSJason Sarich   if (!tao->steptol_changed) tao->steptol = 1.0e-12;
3626552cf8aSJason Sarich #endif
3636552cf8aSJason Sarich 
3646552cf8aSJason Sarich   if (!tao->trust0_changed) tao->trust0 = 1.0;
365a7e14dcfSSatish Balay 
366a7e14dcfSSatish Balay   /* Initialize pointers and variables */
367a7e14dcfSSatish Balay   tron->n            = 0;
368a7e14dcfSSatish Balay   tron->maxgpits     = 3;
369a7e14dcfSSatish Balay   tron->pg_ftol      = 0.001;
370a7e14dcfSSatish Balay 
371a7e14dcfSSatish Balay   tron->eta1         = 1.0e-4;
372a7e14dcfSSatish Balay   tron->eta2         = 0.25;
373a7e14dcfSSatish Balay   tron->eta3         = 0.50;
374a7e14dcfSSatish Balay   tron->eta4         = 0.90;
375a7e14dcfSSatish Balay 
376a7e14dcfSSatish Balay   tron->sigma1       = 0.5;
377a7e14dcfSSatish Balay   tron->sigma2       = 2.0;
378a7e14dcfSSatish Balay   tron->sigma3       = 4.0;
379a7e14dcfSSatish Balay 
380a7e14dcfSSatish Balay   tron->gp_iterates  = 0; /* Cumulative number */
381a7e14dcfSSatish Balay   tron->total_gp_its = 0;
382a7e14dcfSSatish Balay   tron->n_free       = 0;
383a7e14dcfSSatish Balay 
3846c23d075SBarry Smith   tron->DXFree=NULL;
3856c23d075SBarry Smith   tron->R=NULL;
3866c23d075SBarry Smith   tron->X_New=NULL;
3876c23d075SBarry Smith   tron->G_New=NULL;
3886c23d075SBarry Smith   tron->Work=NULL;
3896c23d075SBarry Smith   tron->Free_Local=NULL;
3906c23d075SBarry Smith   tron->H_sub=NULL;
3916c23d075SBarry Smith   tron->Hpre_sub=NULL;
392a7e14dcfSSatish Balay   tao->subset_type = TAO_SUBSET_SUBVEC;
393a7e14dcfSSatish Balay 
394a7e14dcfSSatish Balay   ierr = TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch);CHKERRQ(ierr);
395a7e14dcfSSatish Balay   ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr);
396441846f8SBarry Smith   ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr);
3975d527766SPatrick Farrell   ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr);
398a7e14dcfSSatish Balay 
399a7e14dcfSSatish Balay   ierr = KSPCreate(((PetscObject)tao)->comm, &tao->ksp);CHKERRQ(ierr);
4005d527766SPatrick Farrell   ierr = KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix);CHKERRQ(ierr);
401*8f1e51d3STodd Munson   ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr);
402a7e14dcfSSatish Balay   PetscFunctionReturn(0);
403a7e14dcfSSatish Balay }
404728e0ed0SBarry Smith 
405