xref: /petsc/src/tao/bound/impls/tron/tron.c (revision 9566063d113dddea24716c546802770db7481bc0)
1aaa7dc30SBarry Smith #include <../src/tao/bound/impls/tron/tron.h>
2aaa7dc30SBarry Smith #include <../src/tao/matrix/submatfree.h>
3a7e14dcfSSatish Balay 
4a7e14dcfSSatish Balay /* TRON Routines */
5441846f8SBarry Smith static PetscErrorCode TronGradientProjections(Tao,TAO_TRON*);
6a7e14dcfSSatish Balay /*------------------------------------------------------------*/
7441846f8SBarry Smith static PetscErrorCode TaoDestroy_TRON(Tao tao)
8a7e14dcfSSatish Balay {
9a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
10a7e14dcfSSatish Balay 
11a7e14dcfSSatish Balay   PetscFunctionBegin;
12*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->X_New));
13*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->G_New));
14*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->Work));
15*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->DXFree));
16*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->R));
17*9566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&tron->diag));
18*9566063dSJacob Faibussowitsch   PetscCall(VecScatterDestroy(&tron->scatter));
19*9566063dSJacob Faibussowitsch   PetscCall(ISDestroy(&tron->Free_Local));
20*9566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&tron->H_sub));
21*9566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&tron->Hpre_sub));
22*9566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
23a7e14dcfSSatish Balay   PetscFunctionReturn(0);
24a7e14dcfSSatish Balay }
25a7e14dcfSSatish Balay 
26a7e14dcfSSatish Balay /*------------------------------------------------------------*/
274416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_TRON(PetscOptionItems *PetscOptionsObject,Tao tao)
28a7e14dcfSSatish Balay {
29a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
30a7e14dcfSSatish Balay   PetscBool      flg;
31a7e14dcfSSatish Balay 
32a7e14dcfSSatish Balay   PetscFunctionBegin;
33*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHead(PetscOptionsObject,"Newton Trust Region Method for bound constrained optimization"));
34*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-tao_tron_maxgpits","maximum number of gradient projections per TRON iterate","TaoSetMaxGPIts",tron->maxgpits,&tron->maxgpits,&flg));
35*9566063dSJacob Faibussowitsch   PetscCall(PetscOptionsTail());
36*9566063dSJacob Faibussowitsch   PetscCall(KSPSetFromOptions(tao->ksp));
37a7e14dcfSSatish Balay   PetscFunctionReturn(0);
38a7e14dcfSSatish Balay }
39a7e14dcfSSatish Balay 
40a7e14dcfSSatish Balay /*------------------------------------------------------------*/
41441846f8SBarry Smith static PetscErrorCode TaoView_TRON(Tao tao, PetscViewer viewer)
42a7e14dcfSSatish Balay {
43a7e14dcfSSatish Balay   TAO_TRON         *tron = (TAO_TRON *)tao->data;
44a7e14dcfSSatish Balay   PetscBool        isascii;
45a7e14dcfSSatish Balay 
46a7e14dcfSSatish Balay   PetscFunctionBegin;
47*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii));
48a7e14dcfSSatish Balay   if (isascii) {
49*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"Total PG its: %D,",tron->total_gp_its));
50*9566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"PG tolerance: %g \n",(double)tron->pg_ftol));
51a7e14dcfSSatish Balay   }
52a7e14dcfSSatish Balay   PetscFunctionReturn(0);
53a7e14dcfSSatish Balay }
54a7e14dcfSSatish Balay 
55a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
56441846f8SBarry Smith static PetscErrorCode TaoSetup_TRON(Tao tao)
57a7e14dcfSSatish Balay {
58a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
59a7e14dcfSSatish Balay 
60a7e14dcfSSatish Balay   PetscFunctionBegin;
61a7e14dcfSSatish Balay 
62a7e14dcfSSatish Balay   /* Allocate some arrays */
63*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tron->diag));
64*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tron->X_New));
65*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tron->G_New));
66*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tron->Work));
67*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tao->gradient));
68*9566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(tao->solution, &tao->stepdirection));
69a7e14dcfSSatish Balay   if (!tao->XL) {
70*9566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(tao->solution, &tao->XL));
71*9566063dSJacob Faibussowitsch     PetscCall(VecSet(tao->XL, PETSC_NINFINITY));
72a7e14dcfSSatish Balay   }
73a7e14dcfSSatish Balay   if (!tao->XU) {
74*9566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(tao->solution, &tao->XU));
75*9566063dSJacob Faibussowitsch     PetscCall(VecSet(tao->XU, PETSC_INFINITY));
76a7e14dcfSSatish Balay   }
77a7e14dcfSSatish Balay   PetscFunctionReturn(0);
78a7e14dcfSSatish Balay }
79a7e14dcfSSatish Balay 
80441846f8SBarry Smith static PetscErrorCode TaoSolve_TRON(Tao tao)
8147a47007SBarry Smith {
82a7e14dcfSSatish Balay   TAO_TRON                     *tron = (TAO_TRON *)tao->data;
838931d482SJason Sarich   PetscInt                     its;
84e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING;
85a7e14dcfSSatish Balay   PetscReal                    prered,actred,delta,f,f_new,rhok,gdx,xdiff,stepsize;
8647a47007SBarry Smith 
87a7e14dcfSSatish Balay   PetscFunctionBegin;
88a7e14dcfSSatish Balay   tron->pgstepsize = 1.0;
89a7e14dcfSSatish Balay   tao->trust = tao->trust0;
90a7e14dcfSSatish Balay   /*   Project the current point onto the feasible set */
91*9566063dSJacob Faibussowitsch   PetscCall(TaoComputeVariableBounds(tao));
92*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU));
93a7e14dcfSSatish Balay 
94ce902467SBarry Smith   /* Project the initial point onto the feasible region */
95*9566063dSJacob Faibussowitsch   PetscCall(VecMedian(tao->XL,tao->solution,tao->XU,tao->solution));
9653506e15SBarry Smith 
97ce902467SBarry Smith   /* Compute the objective function and gradient */
98*9566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao,tao->solution,&tron->f,tao->gradient));
99*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
1003c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(tron->f) && !PetscIsInfOrNanReal(tron->gnorm),PetscObjectComm((PetscObject)tao),PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
101a7e14dcfSSatish Balay 
102a7e14dcfSSatish Balay   /* Project the gradient and calculate the norm */
103*9566063dSJacob Faibussowitsch   PetscCall(VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tao->gradient));
104*9566063dSJacob Faibussowitsch   PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
105a7e14dcfSSatish Balay 
106ce902467SBarry Smith   /* Initialize trust region radius */
107ce902467SBarry Smith   tao->trust=tao->trust0;
108a7e14dcfSSatish Balay   if (tao->trust <= 0) {
109a7e14dcfSSatish Balay     tao->trust=PetscMax(tron->gnorm*tron->gnorm,1.0);
110a7e14dcfSSatish Balay   }
111a7e14dcfSSatish Balay 
112ce902467SBarry Smith   /* Initialize step sizes for the line searches */
113ce902467SBarry Smith   tron->pgstepsize=1.0;
114a7e14dcfSSatish Balay   tron->stepsize=tao->trust;
115ce902467SBarry Smith 
1163ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
117*9566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao,tron->f,tron->gnorm,0.0,tao->ksp_its));
118*9566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao,tao->niter,tron->f,tron->gnorm,0.0,tron->stepsize));
119*9566063dSJacob Faibussowitsch   PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP));
1203ecd9318SAlp Dener   while (tao->reason==TAO_CONTINUE_ITERATING) {
121e1e80dc8SAlp Dener     /* Call general purpose update function */
122e1e80dc8SAlp Dener     if (tao->ops->update) {
123*9566063dSJacob Faibussowitsch       PetscCall((*tao->ops->update)(tao, tao->niter, tao->user_update));
124e1e80dc8SAlp Dener     }
125ce902467SBarry Smith 
126ce902467SBarry Smith     /* Perform projected gradient iterations */
127*9566063dSJacob Faibussowitsch     PetscCall(TronGradientProjections(tao,tron));
128ce902467SBarry Smith 
129*9566063dSJacob Faibussowitsch     PetscCall(VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tao->gradient));
130*9566063dSJacob Faibussowitsch     PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
131ce902467SBarry Smith 
132ce902467SBarry Smith     tao->ksp_its=0;
133a7e14dcfSSatish Balay     f=tron->f; delta=tao->trust;
134a7e14dcfSSatish Balay     tron->n_free_last = tron->n_free;
135*9566063dSJacob Faibussowitsch     PetscCall(TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre));
136a7e14dcfSSatish Balay 
137baa3a814SAlp Dener     /* Generate index set (IS) of which bound constraints are active */
138*9566063dSJacob Faibussowitsch     PetscCall(ISDestroy(&tron->Free_Local));
139*9566063dSJacob Faibussowitsch     PetscCall(VecWhichInactive(tao->XL,tao->solution,tao->gradient,tao->XU,PETSC_TRUE,&tron->Free_Local));
140*9566063dSJacob Faibussowitsch     PetscCall(ISGetSize(tron->Free_Local, &tron->n_free));
141a7e14dcfSSatish Balay 
142a7e14dcfSSatish Balay     /* If no free variables */
143a7e14dcfSSatish Balay     if (tron->n_free == 0) {
144*9566063dSJacob Faibussowitsch       PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
145*9566063dSJacob Faibussowitsch       PetscCall(TaoLogConvergenceHistory(tao,tron->f,tron->gnorm,0.0,tao->ksp_its));
146*9566063dSJacob Faibussowitsch       PetscCall(TaoMonitor(tao,tao->niter,tron->f,tron->gnorm,0.0,delta));
147*9566063dSJacob Faibussowitsch       PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP));
1483ecd9318SAlp Dener       if (!tao->reason) {
1493ecd9318SAlp Dener         tao->reason = TAO_CONVERGED_STEPTOL;
15055723ba5SJason Sarich       }
151a7e14dcfSSatish Balay       break;
152a7e14dcfSSatish Balay     }
153a7e14dcfSSatish Balay     /* use free_local to mask/submat gradient, hessian, stepdirection */
154*9566063dSJacob Faibussowitsch     PetscCall(TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->R));
155*9566063dSJacob Faibussowitsch     PetscCall(TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->DXFree));
156*9566063dSJacob Faibussowitsch     PetscCall(VecSet(tron->DXFree,0.0));
157*9566063dSJacob Faibussowitsch     PetscCall(VecScale(tron->R, -1.0));
158*9566063dSJacob Faibussowitsch     PetscCall(TaoMatGetSubMat(tao->hessian, tron->Free_Local, tron->diag, tao->subset_type, &tron->H_sub));
159a7e14dcfSSatish Balay     if (tao->hessian == tao->hessian_pre) {
160*9566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&tron->Hpre_sub));
161*9566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)(tron->H_sub)));
162a7e14dcfSSatish Balay       tron->Hpre_sub = tron->H_sub;
163a7e14dcfSSatish Balay     } else {
164*9566063dSJacob Faibussowitsch       PetscCall(TaoMatGetSubMat(tao->hessian_pre, tron->Free_Local, tron->diag, tao->subset_type,&tron->Hpre_sub));
165a7e14dcfSSatish Balay     }
166*9566063dSJacob Faibussowitsch     PetscCall(KSPReset(tao->ksp));
167*9566063dSJacob Faibussowitsch     PetscCall(KSPSetOperators(tao->ksp, tron->H_sub, tron->Hpre_sub));
168a7e14dcfSSatish Balay     while (1) {
169a7e14dcfSSatish Balay 
170a7e14dcfSSatish Balay       /* Approximately solve the reduced linear system */
171*9566063dSJacob Faibussowitsch       PetscCall(KSPCGSetRadius(tao->ksp,delta));
172d8ec8e84SJason Sarich 
173*9566063dSJacob Faibussowitsch       PetscCall(KSPSolve(tao->ksp, tron->R, tron->DXFree));
174*9566063dSJacob Faibussowitsch       PetscCall(KSPGetIterationNumber(tao->ksp,&its));
175a7e14dcfSSatish Balay       tao->ksp_its+=its;
176ae93cb3cSJason Sarich       tao->ksp_tot_its+=its;
177*9566063dSJacob Faibussowitsch       PetscCall(VecSet(tao->stepdirection,0.0));
178a7e14dcfSSatish Balay 
179a7e14dcfSSatish Balay       /* Add dxfree matrix to compute step direction vector */
180*9566063dSJacob Faibussowitsch       PetscCall(VecISAXPY(tao->stepdirection,tron->Free_Local,1.0,tron->DXFree));
181a7e14dcfSSatish Balay 
182*9566063dSJacob Faibussowitsch       PetscCall(VecDot(tao->gradient, tao->stepdirection, &gdx));
183*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->solution, tron->X_New));
184*9566063dSJacob Faibussowitsch       PetscCall(VecCopy(tao->gradient, tron->G_New));
185a7e14dcfSSatish Balay 
186a7e14dcfSSatish Balay       stepsize=1.0;f_new=f;
187a7e14dcfSSatish Balay 
188*9566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,1.0));
189*9566063dSJacob Faibussowitsch       PetscCall(TaoLineSearchApply(tao->linesearch, tron->X_New, &f_new, tron->G_New, tao->stepdirection,&stepsize,&ls_reason));
190*9566063dSJacob Faibussowitsch       PetscCall(TaoAddLineSearchCounts(tao));
191a7e14dcfSSatish Balay 
192*9566063dSJacob Faibussowitsch       PetscCall(MatMult(tao->hessian, tao->stepdirection, tron->Work));
193*9566063dSJacob Faibussowitsch       PetscCall(VecAYPX(tron->Work, 0.5, tao->gradient));
194*9566063dSJacob Faibussowitsch       PetscCall(VecDot(tao->stepdirection, tron->Work, &prered));
195a7e14dcfSSatish Balay       actred = f_new - f;
196ce902467SBarry Smith       if ((PetscAbsScalar(actred) <= 1e-6) && (PetscAbsScalar(prered) <= 1e-6)) {
197ce902467SBarry Smith         rhok = 1.0;
198ce902467SBarry Smith       } else if (actred<0) {
199a7e14dcfSSatish Balay         rhok=PetscAbs(-actred/prered);
200a7e14dcfSSatish Balay       } else {
201a7e14dcfSSatish Balay         rhok=0.0;
202a7e14dcfSSatish Balay       }
203a7e14dcfSSatish Balay 
204a7e14dcfSSatish Balay       /* Compare actual improvement to the quadratic model */
205a7e14dcfSSatish Balay       if (rhok > tron->eta1) { /* Accept the point */
206a7e14dcfSSatish Balay         /* d = x_new - x */
207*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(tron->X_New, tao->stepdirection));
208*9566063dSJacob Faibussowitsch         PetscCall(VecAXPY(tao->stepdirection, -1.0, tao->solution));
209a7e14dcfSSatish Balay 
210*9566063dSJacob Faibussowitsch         PetscCall(VecNorm(tao->stepdirection, NORM_2, &xdiff));
211a7e14dcfSSatish Balay         xdiff *= stepsize;
212a7e14dcfSSatish Balay 
213a7e14dcfSSatish Balay         /* Adjust trust region size */
214a7e14dcfSSatish Balay         if (rhok < tron->eta2) {
215a7e14dcfSSatish Balay           delta = PetscMin(xdiff,delta)*tron->sigma1;
216a7e14dcfSSatish Balay         } else if (rhok > tron->eta4) {
217a7e14dcfSSatish Balay           delta= PetscMin(xdiff,delta)*tron->sigma3;
218a7e14dcfSSatish Balay         } else if (rhok > tron->eta3) {
219a7e14dcfSSatish Balay           delta=PetscMin(xdiff,delta)*tron->sigma2;
220a7e14dcfSSatish Balay         }
221*9566063dSJacob Faibussowitsch         PetscCall(VecBoundGradientProjection(tron->G_New,tron->X_New, tao->XL, tao->XU, tao->gradient));
222*9566063dSJacob Faibussowitsch         PetscCall(ISDestroy(&tron->Free_Local));
223*9566063dSJacob Faibussowitsch         PetscCall(VecWhichInactive(tao->XL,tron->X_New,tao->gradient,tao->XU,PETSC_TRUE,&tron->Free_Local));
224a7e14dcfSSatish Balay         f=f_new;
225*9566063dSJacob Faibussowitsch         PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
226*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(tron->X_New, tao->solution));
227*9566063dSJacob Faibussowitsch         PetscCall(VecCopy(tron->G_New, tao->gradient));
228a7e14dcfSSatish Balay         break;
229a7e14dcfSSatish Balay       }
230a7e14dcfSSatish Balay       else if (delta <= 1e-30) {
231a7e14dcfSSatish Balay         break;
232a7e14dcfSSatish Balay       }
233a7e14dcfSSatish Balay       else {
234a7e14dcfSSatish Balay         delta /= 4.0;
235a7e14dcfSSatish Balay       }
236a7e14dcfSSatish Balay     } /* end linear solve loop */
237a7e14dcfSSatish Balay 
238a7e14dcfSSatish Balay     tron->f=f; tron->actred=actred; tao->trust=delta;
2398931d482SJason Sarich     tao->niter++;
240*9566063dSJacob Faibussowitsch     PetscCall(TaoLogConvergenceHistory(tao,tron->f,tron->gnorm,0.0,tao->ksp_its));
241*9566063dSJacob Faibussowitsch     PetscCall(TaoMonitor(tao,tao->niter,tron->f,tron->gnorm,0.0,stepsize));
242*9566063dSJacob Faibussowitsch     PetscCall((*tao->ops->convergencetest)(tao,tao->cnvP));
243a7e14dcfSSatish Balay   }  /* END MAIN LOOP  */
244a7e14dcfSSatish Balay   PetscFunctionReturn(0);
245a7e14dcfSSatish Balay }
246a7e14dcfSSatish Balay 
247441846f8SBarry Smith static PetscErrorCode TronGradientProjections(Tao tao,TAO_TRON *tron)
248a7e14dcfSSatish Balay {
249a7e14dcfSSatish Balay   PetscErrorCode               ierr;
250a7e14dcfSSatish Balay   PetscInt                     i;
251e4cb33bbSBarry Smith   TaoLineSearchConvergedReason ls_reason;
252a7e14dcfSSatish Balay   PetscReal                    actred=-1.0,actred_max=0.0;
253a7e14dcfSSatish Balay   PetscReal                    f_new;
254a7e14dcfSSatish Balay   /*
255a7e14dcfSSatish Balay      The gradient and function value passed into and out of this
256a7e14dcfSSatish Balay      routine should be current and correct.
257a7e14dcfSSatish Balay 
258a7e14dcfSSatish Balay      The free, active, and binding variables should be already identified
259a7e14dcfSSatish Balay   */
260a7e14dcfSSatish Balay   PetscFunctionBegin;
261a7e14dcfSSatish Balay 
262ce902467SBarry Smith   for (i=0;i<tron->maxgpits;++i) {
263a7e14dcfSSatish Balay 
264a7e14dcfSSatish Balay     if (-actred <= (tron->pg_ftol)*actred_max) break;
265a7e14dcfSSatish Balay 
266ce902467SBarry Smith     ++tron->gp_iterates;
267ce902467SBarry Smith     ++tron->total_gp_its;
268a7e14dcfSSatish Balay     f_new=tron->f;
269a7e14dcfSSatish Balay 
270*9566063dSJacob Faibussowitsch     PetscCall(VecCopy(tao->gradient,tao->stepdirection));
271*9566063dSJacob Faibussowitsch     PetscCall(VecScale(tao->stepdirection,-1.0));
272*9566063dSJacob Faibussowitsch     PetscCall(TaoLineSearchSetInitialStepLength(tao->linesearch,tron->pgstepsize));
273a7e14dcfSSatish Balay     ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f_new, tao->gradient, tao->stepdirection,
274*9566063dSJacob Faibussowitsch                               &tron->pgstepsize, &ls_reason);PetscCall(ierr);
275*9566063dSJacob Faibussowitsch     PetscCall(TaoAddLineSearchCounts(tao));
276a7e14dcfSSatish Balay 
277*9566063dSJacob Faibussowitsch     PetscCall(VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tao->gradient));
278*9566063dSJacob Faibussowitsch     PetscCall(VecNorm(tao->gradient,NORM_2,&tron->gnorm));
279ce902467SBarry Smith 
280a7e14dcfSSatish Balay     /* Update the iterate */
281a7e14dcfSSatish Balay     actred = f_new - tron->f;
282a7e14dcfSSatish Balay     actred_max = PetscMax(actred_max,-(f_new - tron->f));
283a7e14dcfSSatish Balay     tron->f = f_new;
284a7e14dcfSSatish Balay   }
285a7e14dcfSSatish Balay   PetscFunctionReturn(0);
286a7e14dcfSSatish Balay }
287a7e14dcfSSatish Balay 
288bdb10af2SPierre Jolivet static PetscErrorCode TaoComputeDual_TRON(Tao tao, Vec DXL, Vec DXU)
289bdb10af2SPierre Jolivet {
290a7e14dcfSSatish Balay 
291a7e14dcfSSatish Balay   TAO_TRON       *tron = (TAO_TRON *)tao->data;
292a7e14dcfSSatish Balay 
293a7e14dcfSSatish Balay   PetscFunctionBegin;
294441846f8SBarry Smith   PetscValidHeaderSpecific(tao,TAO_CLASSID,1);
295a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXL,VEC_CLASSID,2);
296a7e14dcfSSatish Balay   PetscValidHeaderSpecific(DXU,VEC_CLASSID,3);
2973c859ba3SBarry Smith   PetscCheck(tron->Work && tao->gradient,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Dual variables don't exist yet or no longer exist.");
298a7e14dcfSSatish Balay 
299*9566063dSJacob Faibussowitsch   PetscCall(VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tron->Work));
300*9566063dSJacob Faibussowitsch   PetscCall(VecCopy(tron->Work,DXL));
301*9566063dSJacob Faibussowitsch   PetscCall(VecAXPY(DXL,-1.0,tao->gradient));
302*9566063dSJacob Faibussowitsch   PetscCall(VecSet(DXU,0.0));
303*9566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMax(DXL,DXL,DXU));
304a7e14dcfSSatish Balay 
305*9566063dSJacob Faibussowitsch   PetscCall(VecCopy(tao->gradient,DXU));
306*9566063dSJacob Faibussowitsch   PetscCall(VecAXPY(DXU,-1.0,tron->Work));
307*9566063dSJacob Faibussowitsch   PetscCall(VecSet(tron->Work,0.0));
308*9566063dSJacob Faibussowitsch   PetscCall(VecPointwiseMin(DXU,tron->Work,DXU));
309a7e14dcfSSatish Balay   PetscFunctionReturn(0);
310a7e14dcfSSatish Balay }
311a7e14dcfSSatish Balay 
312a7e14dcfSSatish Balay /*------------------------------------------------------------*/
3131522df2eSJason Sarich /*MC
3141522df2eSJason Sarich   TAOTRON - The TRON algorithm is an active-set Newton trust region method
3151522df2eSJason Sarich   for bound-constrained minimization.
3161522df2eSJason Sarich 
3171522df2eSJason Sarich   Options Database Keys:
3181522df2eSJason Sarich + -tao_tron_maxgpits - maximum number of gradient projections per TRON iterate
3191522df2eSJason Sarich - -tao_subset_type - "subvec","mask","matrix-free", strategies for handling active-sets
3201522df2eSJason Sarich 
3211eb8069cSJason Sarich   Level: beginner
3221522df2eSJason Sarich M*/
323728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_TRON(Tao tao)
324a7e14dcfSSatish Balay {
325a7e14dcfSSatish Balay   TAO_TRON       *tron;
3268caf6e8cSBarry Smith   const char     *morethuente_type = TAOLINESEARCHMT;
327a7e14dcfSSatish Balay 
32847a47007SBarry Smith   PetscFunctionBegin;
329a7e14dcfSSatish Balay   tao->ops->setup          = TaoSetup_TRON;
330a7e14dcfSSatish Balay   tao->ops->solve          = TaoSolve_TRON;
331a7e14dcfSSatish Balay   tao->ops->view           = TaoView_TRON;
332a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_TRON;
333a7e14dcfSSatish Balay   tao->ops->destroy        = TaoDestroy_TRON;
334a7e14dcfSSatish Balay   tao->ops->computedual    = TaoComputeDual_TRON;
335a7e14dcfSSatish Balay 
336*9566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(tao,&tron));
3376f4723b1SBarry Smith   tao->data = (void*)tron;
3386552cf8aSJason Sarich 
3396552cf8aSJason Sarich   /* Override default settings (unless already changed) */
3406552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 50;
3416552cf8aSJason Sarich   if (!tao->trust0_changed) tao->trust0 = 1.0;
3424f1535bcSTodd Munson   if (!tao->steptol_changed) tao->steptol = 0.0;
343a7e14dcfSSatish Balay 
344a7e14dcfSSatish Balay   /* Initialize pointers and variables */
345a7e14dcfSSatish Balay   tron->n            = 0;
346a7e14dcfSSatish Balay   tron->maxgpits     = 3;
347a7e14dcfSSatish Balay   tron->pg_ftol      = 0.001;
348a7e14dcfSSatish Balay 
349a7e14dcfSSatish Balay   tron->eta1         = 1.0e-4;
350a7e14dcfSSatish Balay   tron->eta2         = 0.25;
351a7e14dcfSSatish Balay   tron->eta3         = 0.50;
352a7e14dcfSSatish Balay   tron->eta4         = 0.90;
353a7e14dcfSSatish Balay 
354a7e14dcfSSatish Balay   tron->sigma1       = 0.5;
355a7e14dcfSSatish Balay   tron->sigma2       = 2.0;
356a7e14dcfSSatish Balay   tron->sigma3       = 4.0;
357a7e14dcfSSatish Balay 
358a7e14dcfSSatish Balay   tron->gp_iterates  = 0; /* Cumulative number */
359a7e14dcfSSatish Balay   tron->total_gp_its = 0;
360a7e14dcfSSatish Balay   tron->n_free       = 0;
361a7e14dcfSSatish Balay 
3626c23d075SBarry Smith   tron->DXFree=NULL;
3636c23d075SBarry Smith   tron->R=NULL;
3646c23d075SBarry Smith   tron->X_New=NULL;
3656c23d075SBarry Smith   tron->G_New=NULL;
3666c23d075SBarry Smith   tron->Work=NULL;
3676c23d075SBarry Smith   tron->Free_Local=NULL;
3686c23d075SBarry Smith   tron->H_sub=NULL;
3696c23d075SBarry Smith   tron->Hpre_sub=NULL;
370a7e14dcfSSatish Balay   tao->subset_type = TAO_SUBSET_SUBVEC;
371a7e14dcfSSatish Balay 
372*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchCreate(((PetscObject)tao)->comm, &tao->linesearch));
373*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1));
374*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetType(tao->linesearch,morethuente_type));
375*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchUseTaoRoutines(tao->linesearch,tao));
376*9566063dSJacob Faibussowitsch   PetscCall(TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix));
377a7e14dcfSSatish Balay 
378*9566063dSJacob Faibussowitsch   PetscCall(KSPCreate(((PetscObject)tao)->comm, &tao->ksp));
379*9566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1));
380*9566063dSJacob Faibussowitsch   PetscCall(KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix));
381*9566063dSJacob Faibussowitsch   PetscCall(KSPSetType(tao->ksp,KSPSTCG));
382a7e14dcfSSatish Balay   PetscFunctionReturn(0);
383a7e14dcfSSatish Balay }
384