Actual source code: tron.c
1: /*$Id$*/
3: #include "tron.h" /*I "tao_solver.h" I*/
5: /* TRON Routines */
6: static int TaoGradProjections(TAO_SOLVER,TAO_TRON *);
7: static int TronCheckOptimalFace(TaoVec*, TaoVec*, TaoVec*, TaoVec*, TaoVec*,
8: TaoIndexSet*, TaoIndexSet*, TaoTruth *optimal);
10: /*------------------------------------------------------------*/
13: static int TaoSetDown_TRON(TAO_SOLVER tao, void*solver)
14: {
15: TAO_TRON *tron = (TAO_TRON *)solver;
16: int info;
17: /* Free allocated memory in TRON structure */
18: TaoFunctionBegin;
19:
20: info = TaoVecDestroy(tron->X_New);CHKERRQ(info);
21: info = TaoVecDestroy(tron->G_New);CHKERRQ(info);
22: info = TaoVecDestroy(tron->DX);CHKERRQ(info);tron->DX=0;
23: info = TaoVecDestroy(tron->Work);CHKERRQ(info);
24: info = TaoVecDestroy(tron->DXFree);CHKERRQ(info);
25: info = TaoVecDestroy(tron->R);CHKERRQ(info);
26: info = TaoVecDestroy(tron->G);CHKERRQ(info);
27: info = TaoVecDestroy(tron->PG);CHKERRQ(info);
28: info = TaoVecDestroy(tron->XL);CHKERRQ(info);
29: info = TaoVecDestroy(tron->XU);CHKERRQ(info);
30:
31: info = TaoIndexSetDestroy(tron->Free_Local);CHKERRQ(info);
32: info = TaoIndexSetDestroy(tron->TT);CHKERRQ(info);
33: info = TaoMatDestroy(tron->Hsub);CHKERRQ(info);
35: info = TaoSetLagrangianGradientVector(tao,0);CHKERRQ(info);
36: info = TaoSetStepDirectionVector(tao,0);CHKERRQ(info);
37: info = TaoSetVariableBounds(tao,0,0);CHKERRQ(info);
39: TaoFunctionReturn(0);
40: }
42: /*------------------------------------------------------------*/
45: static int TaoSetOptions_TRON(TAO_SOLVER tao, void*solver)
46: {
47: TAO_TRON *tron = (TAO_TRON *)solver;
48: int info,ival;
49: TaoTruth flg;
51: TaoFunctionBegin;
53: info = TaoOptionsHead("Newton Trust Region Method for bound constrained optimization");CHKERRQ(info);
55: info = TaoOptionInt("-tron_maxgpits","maximum number of gradient projections per TRON iterate","TaoSetMaxGPIts",tron->maxgpits,&tron->maxgpits,&flg);
56: CHKERRQ(info);
58: info = TaoOptionInt("-redistribute","Redistribute Free variables (> 1 processors, only)","TaoPetscISType",1,&ival,&flg); CHKERRQ(info);
60: info = TaoOptionName("-submatrixfree","Mask full matrix instead of extract submatrices","TaoPetscISType",&flg); CHKERRQ(info);
62: info = TaoOptionsTail();CHKERRQ(info);
63: info = TaoLineSearchSetFromOptions(tao);CHKERRQ(info);
65: TaoFunctionReturn(0);
66: }
68: /*------------------------------------------------------------*/
71: static int TaoView_TRON(TAO_SOLVER tao,void*solver)
72: {
73: TAO_TRON *tron = (TAO_TRON *)solver;
74: int info;
76: TaoFunctionBegin;
77: /*
78: info = TaoPrintf1(tao," Variables, Total: %d,",tron->n);
79: info = TaoPrintf3(tao,"Free: %d, Binding: %d \n",
80: tron->n_free, tron->n - tron->n_free,
81: tron->n_bind);CHKERRQ(info);
82: info = TaoPrintf1(tao," Equal lower bound: %d,",
83: tron->n_lower);CHKERRQ(info);
84: info = TaoPrintf1(tao," Equal upper bound: %d \n",
85: tron->n_upper);CHKERRQ(info);
86: */
87: info = TaoPrintInt(tao," Total PG its: %d,",tron->total_gp_its);CHKERRQ(info);
88: info = TaoPrintDouble(tao," PG tolerance: %4.3f \n",tron->pg_ftol);CHKERRQ(info);
89: info = TaoLineSearchView(tao);CHKERRQ(info);
90: info = TaoPrintStatement(tao," Linear Solver minimizes quadratic over Trust Region: \n");CHKERRQ(info);
92: TaoFunctionReturn(0);
93: }
96: /* ---------------------------------------------------------- */
99: static int TaoSetUp_TRON(TAO_SOLVER tao, void*solver){
101: int info;
102: TAO_TRON *tron = (TAO_TRON *)solver;
103: TaoVec* X;
104: TaoMat *HH;
105: TaoIndexSet *TIS;
107: TaoFunctionBegin;
108: info = TaoGetSolution(tao,&tron->X);CHKERRQ(info); X=tron->X;
109: info = TaoGetHessian(tao,&tron->H);CHKERRQ(info); HH=tron->H;
111: /* Allocate some arrays */
112: info = X->Clone(&tron->DX); CHKERRQ(info);
113: info = X->Clone(&tron->X_New); CHKERRQ(info);
114: info = X->Clone(&tron->G_New); CHKERRQ(info);
115: info = X->Clone(&tron->Work); CHKERRQ(info);
116: info = X->Clone(&tron->DXFree); CHKERRQ(info);
117: info = X->Clone(&tron->R); CHKERRQ(info);
118: info = X->Clone(&tron->G); CHKERRQ(info);
119: info = X->Clone(&tron->PG); CHKERRQ(info);
120: info = X->Clone(&tron->XL); CHKERRQ(info);
121: info = X->Clone(&tron->XU); CHKERRQ(info);
123: info = TaoSetLagrangianGradientVector(tao,tron->PG);CHKERRQ(info);
124: info = TaoSetStepDirectionVector(tao,tron->DX);CHKERRQ(info);
125: info = TaoSetVariableBounds(tao,tron->XL,tron->XU);CHKERRQ(info);
127: info = X->GetDimension(&tron->n); CHKERRQ(info);
128:
129: info = X->CreateIndexSet(&tron->Free_Local); CHKERRQ(info);
130: info = tron->Free_Local->Duplicate(&tron->TT); CHKERRQ(info);
132: TIS=tron->Free_Local;
133: info = tron->H->CreateReducedMatrix(TIS,TIS,&tron->Hsub); CHKERRQ(info);
134: info = TaoCreateLinearSolver(tao,HH,220,0); CHKERRQ(info);
136: info = TaoCheckFGH(tao);CHKERRQ(info);
138: TaoFunctionReturn(0);
139: }
145: static int TaoSolve_TRON(TAO_SOLVER tao, void*solver){
147: TAO_TRON *tron = (TAO_TRON *)solver;
148: int info,lsflag,iter=0;
149: TaoTerminateReason reason;
150: TaoTruth optimal_face=TAO_FALSE,success;
151: double prered,actred,delta,f,f_new,f_full,rhok,gnorm,gdx,xdiff,stepsize;
152: TaoVec *XU, *XL;
153: TaoVec *X, *G;
154: TaoVec *PG=tron->PG;
155: TaoVec *R=tron->R, *DXFree=tron->DXFree;
156: TaoVec *X_New=tron->X_New, *G_New=tron->G_New;
157: TaoVec *DX=tron->DX, *Work=tron->Work;
158: TaoMat *H, *Hsub=tron->Hsub;
159: TaoIndexSet *Free_Local = tron->Free_Local, *TIS=tron->TT;
161: TaoFunctionBegin;
163: // Get initial trust region radius
164: info = TaoGetInitialTrustRegionRadius(tao, &tron->delta); CHKERRQ(info);
165: if (tron->delta <= 0) {
166: SETERRQ(1, "Initial trust region radius must be positive");
167: }
169: // Get vectors we will need
170: info = TaoGetSolution(tao, &X); CHKERRQ(info);
171: info = TaoGetGradient(tao, &G); CHKERRQ(info);
172: info = TaoGetHessian(tao, &H); CHKERRQ(info);
173: info = TaoGetVariableBounds(tao, &XL, &XU); CHKERRQ(info);
175: // Check that upper bound greater than lower bound
176: info = TaoEvaluateVariableBounds(tao, XL, XU); CHKERRQ(info);
178: tron->pgstepsize=1.0;
180: /* Project the current point onto the feasible set */
181: info = X->Median(XL,X,XU); CHKERRQ(info);
182:
183: info = TaoComputeMeritFunctionGradient(tao,X,&tron->f,G);CHKERRQ(info);
184: info = Free_Local->WhichBetween(XL,X,XU); CHKERRQ(info);
185:
186: /* Project the gradient and calculate the norm */
187: // info = G_New->CopyFrom(G);CHKERRQ(info);
188: info = PG->BoundGradientProjection(G,XL,X,XU);CHKERRQ(info);
189: info = PG->Norm2(&tron->gnorm); CHKERRQ(info);
191: if (tron->delta <= 0.0){
192: tron->delta=TaoMax(tron->gnorm*tron->gnorm,1.0);
193: // tron->delta = TAO_INFINITY;
194: }
196: tron->stepsize=tron->delta;
198: info = TaoMonitor(tao,iter++,tron->f,tron->gnorm,0.0,tron->delta,&reason);
199: CHKERRQ(info);
201: while (reason==TAO_CONTINUE_ITERATING){
202:
203: info = TaoGradProjections(tao,tron); CHKERRQ(info);
205: info = Free_Local->WhichBetween(XL,X,XU); CHKERRQ(info);
206: info = Free_Local->GetSize(&tron->n_free); CHKERRQ(info);
207: f=tron->f; delta=tron->delta; gnorm=tron->gnorm;
209: if (tron->n_free > 0){
210:
211: info = TaoComputeHessian(tao,X,H);CHKERRQ(info);
213: /* Create a reduced linear system */
214: info = R->SetReducedVec(G,Free_Local);CHKERRQ(info);
215: info = R->Negate(); CHKERRQ(info);
216: info = DXFree->SetReducedVec(DX,Free_Local);CHKERRQ(info);
217: info = DXFree->SetToZero(); CHKERRQ(info);
219: info = Hsub->SetReducedMatrix(H,Free_Local,Free_Local);CHKERRQ(info);
221: info = TaoPreLinearSolve(tao,Hsub);CHKERRQ(info);
223: while (1) {
225: /* Approximately solve the reduced linear system */
227: info = TaoLinearSolveTrustRegion(tao, Hsub, R, DXFree, delta, &success); CHKERRQ(info);
229: info=DX->SetToZero(); CHKERRQ(info);
230: info=DX->ReducedXPY(DXFree,Free_Local);CHKERRQ(info);
232: info = G->Dot(DX,&gdx); CHKERRQ(info);
233: info = PetscInfo1(tao,"Expected decrease in function value: %14.12e\n",gdx); CHKERRQ(info);
235: stepsize=1.0; f_new=f;
236: info = X_New->CopyFrom(X); CHKERRQ(info);
237: info = G_New->CopyFrom(G); CHKERRQ(info);
238:
239: info = TaoLineSearchApply(tao,X_New,G_New,DX,Work,
240: &f_new,&f_full,&stepsize,&lsflag);
241: CHKERRQ(info);
242: info = H->Multiply(DX,Work); CHKERRQ(info);
243: info = Work->Aypx(0.5,G); CHKERRQ(info);
244: info = Work->Dot(DX,&prered); CHKERRQ(info);
245: actred = f_new - f;
246:
247: if (actred<0) rhok=TaoAbsScalar(-actred/prered);
248: else rhok=0.0;
250: /* Compare actual improvement to the quadratic model */
251: if (rhok > tron->eta1) { /* Accept the point */
253: info = DX->Waxpby(1.0,X_New,-1.0, X); CHKERRQ(info);
254: info = DX->Norm2(&xdiff); CHKERRQ(info);
255: xdiff*=stepsize;
257: /* Adjust trust region size */
258: if (rhok < tron->eta2 ){
259: delta = TaoMin(xdiff,delta)*tron->sigma1;
260: } else if (rhok > tron->eta4 ){
261: delta= TaoMin(xdiff,delta)*tron->sigma3;
262: } else if (rhok > tron->eta3 ){
263: delta=TaoMin(xdiff,delta)*tron->sigma2;
264: }
266: info = PG->BoundGradientProjection(G_New,XL,X_New,XU);
267: CHKERRQ(info);
268: info = PG->Norm2(&gnorm); CHKERRQ(info);
269: info = TronCheckOptimalFace(X_New,XL,XU,G_New,PG, Free_Local, TIS,
270: &optimal_face); CHKERRQ(info);
271: if (stepsize < 1 || optimal_face==TAO_FALSE || reason!=TAO_CONTINUE_ITERATING ){
272: f=f_new;
273: info = X->CopyFrom(X_New); CHKERRQ(info);
274: info = G->CopyFrom(G_New); CHKERRQ(info);
275: break;
276: }
277: if (delta<=1e-30){
278: break;
279: }
280: }
281: else if (delta <= 1e-30) {
282: break;
283: }
284: else {
285: delta /= 4.0;
286: }
287: } /* end linear solve loop */
288:
289: } else {
290:
291: actred=0;
292: info = Work->BoundGradientProjection(G,XL,X,XU);
293: CHKERRQ(info);
294: info = Work->Norm2(&gnorm); CHKERRQ(info);
295: /* if there were no free variables, no cg method */
297: }
299: tron->f=f;tron->gnorm=gnorm; tron->actred=actred; tron->delta=delta;
300: info = TaoMonitor(tao,iter,f,gnorm,0.0,delta,&reason); CHKERRQ(info);
301: if (reason!=TAO_CONTINUE_ITERATING) break;
302: iter++;
303:
304: } /* END MAIN LOOP */
306: TaoFunctionReturn(0);
307: }
312: static int TaoGradProjections(TAO_SOLVER tao,TAO_TRON *tron)
313: {
314: int i,lsflag=0,info;
315: TaoTruth sameface=TAO_FALSE;
316: double actred=-1.0,actred_max=0.0;
317: double f_new, f_full;
318: TaoVec *DX=tron->DX,*XL=tron->XL,*XU=tron->XU,*Work=tron->Work;
319: TaoVec *X=tron->X,*G=tron->G;
320: TaoIndexSet *TT1=tron->Free_Local, *TT2=tron->TT, *TT3;
321: /*
322: The gradient and function value passed into and out of this
323: routine should be current and correct.
324:
325: The free, active, and binding variables should be already identified
326: */
327:
328: TaoFunctionBegin;
329:
330: info = TaoGetSolution(tao,&X);CHKERRQ(info);
331: info = TaoGetGradient(tao,&G);CHKERRQ(info);
332: info = TaoGetVariableBounds(tao,&XL,&XU);CHKERRQ(info);
334: info = TT1->WhichBetween(XL,X,XU); CHKERRQ(info);
336: for (i=0;i<tron->maxgpits;i++){
338: if ( -actred <= (tron->pg_ftol)*actred_max) break;
339:
340: tron->gp_iterates++; tron->total_gp_its++;
341: f_new=tron->f;
343: info = DX->ScaleCopyFrom(-1.0,G); CHKERRQ(info);
345: info = TaoLineSearchApply(tao,X,G,DX,Work,
346: &f_new,&f_full,&tron->pgstepsize,&lsflag);
347: CHKERRQ(info);
349: /* Update the iterate */
350: actred = f_new - tron->f;
351: actred_max = TaoMax(actred_max,-(f_new - tron->f));
352: tron->f = f_new;
354: info = TT2->WhichBetween(XL,X,XU); CHKERRQ(info);
355: info = TT2->IsSame(TT1,&sameface); CHKERRQ(info);
356: if (sameface==TAO_TRUE) {
357: break;
358: } else {
359: // info = TT1->WhichBetween(XL,X,XU); CHKERRQ(info);
360: TT3=TT2;
361: TT2=TT1;
362: TT1=TT3;
363: }
365: }
366:
367: TaoFunctionReturn(0);
368: }
373: static int TronCheckOptimalFace(TaoVec *X,TaoVec *XL,TaoVec*XU,TaoVec *PG,TaoVec*W,
374: TaoIndexSet*Free_Local, TaoIndexSet*TT,
375: TaoTruth *optimal)
376: {
377: int info,n_free;
378: double rr;
379: TaoTruth same;
381: TaoFunctionBegin;
382: *optimal = TAO_FALSE;
384: /* Also check to see if the active set is the same */
386: info = TT->WhichBetween(XL,X,XU); CHKERRQ(info);
387: info = Free_Local->IsSame(TT,&same); CHKERRQ(info);
388: info = Free_Local->GetSize(&n_free); CHKERRQ(info);
389: if (same == TAO_FALSE){
390: info = Free_Local->WhichBetween(XL,X,XU); CHKERRQ(info);
391: *optimal = TAO_FALSE;
392: TaoFunctionReturn(0);
393: } else {
394: *optimal = TAO_TRUE;
395: }
397: info = W->CopyFrom(PG); CHKERRQ(info);
398: info = W->Negate(); CHKERRQ(info);
400: info = W->BoundGradientProjection(W,XL,X,XU); CHKERRQ(info);
401: info = W->Axpy(1.0,PG); CHKERRQ(info);
403: info = W->Norm2(&rr); CHKERRQ(info);
404: if (rr>0) *optimal = TAO_FALSE;
406: *optimal = TAO_FALSE;
407: /*
408: info = tron->TT->whichNonNegative(W); CHKERRQ(info);
409: info = tron->TT->GetSize(&n); CHKERRQ(info);
410: if (n==0) *optimal = TAO_TRUE;
411: */
412: TaoFunctionReturn(0);
413: }
419: int TaoDefaultMonitor_TRON(TAO_SOLVER tao,void *dummy)
420: {
421: int info;
422: int its,nfree,nbind;
423: double fct,gnorm;
424: TAO_TRON *tron;
426: TaoFunctionBegin;
427: info = TaoGetSolutionStatus(tao,&its,&fct,&gnorm,0,0,0);CHKERRQ(info);
428: info = TaoGetSolverContext(tao,"tao_tron",(void**)&tron); CHKERRQ(info);
429: if (tron){
430: nfree=tron->n_free;
431: nbind=tron->n_bind;
432: info=TaoPrintInt(tao,"iter = %d,",its); CHKERRQ(info);
433: info=TaoPrintDouble(tao," Function value: %g,",fct); CHKERRQ(info);
434: info=TaoPrintDouble(tao," Residual: %g \n",gnorm);CHKERRQ(info);
435:
436: info=TaoPrintInt(tao," free vars = %d,",nfree); CHKERRQ(info);
437: info=TaoPrintInt(tao," binding vars = %d\n",nbind); CHKERRQ(info);
438: }
439: TaoFunctionReturn(0);
440: }
442: int TaoSetMaxGPIts(TAO_SOLVER tao, int its){
443: int info;
444: TAO_TRON *tron;
446: TaoFunctionBegin;
448: info = TaoGetSolverContext(tao,"tao_tron",(void**)&tron); CHKERRQ(info);
449: if (tron){
450: tron->maxgpits = its;
451: }
452: TaoFunctionReturn(0);
453: }
458: static int TaoGetDualVariables_TRON(TAO_SOLVER tao, TaoVec* DXL, TaoVec* DXU, void *solver){
460: TAO_TRON *tron = (TAO_TRON *) solver;
461: TaoVec *G=tron->G,*GP=tron->Work;
462: TaoVec *X,*XL,*XU;
463: int info;
465: TaoFunctionBegin;
466: info = TaoGetSolution(tao,&X); CHKERRQ(info);
467: info = TaoGetVariableBounds(tao,&XL,&XU); CHKERRQ(info);
468: info = GP->BoundGradientProjection(G,XL,X,XU); CHKERRQ(info);
470: info = DXL->Waxpby(-1.0,G,1.0,GP); CHKERRQ(info);
471: info = DXU->SetToZero(); CHKERRQ(info);
472: info = DXL->PointwiseMaximum(DXL,DXU); CHKERRQ(info);
474: info = DXU->Waxpby(-1.0,GP,1.0,G); CHKERRQ(info);
475: info = GP->SetToZero(); CHKERRQ(info);
476: info = DXU->PointwiseMinimum(GP,DXU); CHKERRQ(info);
478: TaoFunctionReturn(0);
479: }
481: /*------------------------------------------------------------*/
485: int TaoCreate_TRON(TAO_SOLVER tao)
486: {
487: TAO_TRON *tron;
488: int info;
490: TaoFunctionBegin;
492: info = TaoNew(TAO_TRON,&tron); CHKERRQ(info);
493: info = PetscLogObjectMemory(tao,sizeof(TAO_TRON)); CHKERRQ(info);
495: info=TaoSetTaoSolveRoutine(tao,TaoSolve_TRON,(void*)tron); CHKERRQ(info);
496: info=TaoSetTaoSetUpDownRoutines(tao,TaoSetUp_TRON,TaoSetDown_TRON); CHKERRQ(info);
497: info=TaoSetTaoOptionsRoutine(tao,TaoSetOptions_TRON); CHKERRQ(info);
498: info=TaoSetTaoViewRoutine(tao,TaoView_TRON); CHKERRQ(info);
499: info=TaoSetTaoDualVariablesRoutine(tao,TaoGetDualVariables_TRON); CHKERRQ(info);
501: info = TaoSetMaximumIterates(tao, 50); CHKERRQ(info);
502: info = TaoSetTolerances(tao, 1e-10, 1e-10, 0, 0); CHKERRQ(info);
504: info = TaoSetTrustRegionRadius(tao, 1.0); CHKERRQ(info);
505: info = TaoSetTrustRegionTolerance(tao, 1.0e-12); CHKERRQ(info);
507: /* Initialize pointers and variables */
508: tron->n = 0;
509: tron->delta = -1.0;
510: tron->maxgpits = 3;
511: tron->pg_ftol = 0.001;
513: tron->eta1 = 1.0e-4;
514: tron->eta2 = 0.25;
515: tron->eta3 = 0.50;
516: tron->eta4 = 0.90;
518: tron->sigma1 = 0.5;
519: tron->sigma2 = 2.0;
520: tron->sigma3 = 4.0;
522: tron->gp_iterates = 0; /* Cumulative number */
523: tron->cgits = 0; /* Current iteration */
524: tron->total_gp_its = 0;
525: tron->cg_iterates = 0;
526: tron->total_cgits = 0;
527:
528: tron->n_bind = 0;
529: tron->n_free = 0;
530: tron->n_upper = 0;
531: tron->n_lower = 0;
533: tron->DX=0;
534: tron->DXFree=0;
535: tron->R=0;
536: tron->X_New=0;
537: tron->G_New=0;
538: tron->Work=0;
539: tron->Free_Local=0;
540: tron->TT=0;
541: tron->Hsub=0;
543: info = TaoCreateMoreThuenteBoundLineSearch(tao, 0 , 0); CHKERRQ(info);
544: TaoFunctionReturn(0);
545: }