Actual source code: rscs.c

  1: #include "src/complementarity/impls/ssls/ssls.h"
  2: // #include "src/tao_impl.h"

  4: int Tao_RSCS_FunctionGradient(TAO_SOLVER, TaoVec*, double*, TaoVec*, void *);
  5: int Tao_RSCS_Function(TAO_SOLVER, TaoVec *, double *, void *);
  6: static int TaoSolve_RSCS(TAO_SOLVER tao, void*solver);

  8: typedef struct {
  9:   TaoVec *f;
 10:   TaoMat *J;
 11: } FGMeritCtx;


 16: static int TaoSolve_RSCS(TAO_SOLVER tao, void*solver){

 18:   TAO_SSLS *asls = (TAO_SSLS *)solver;
 19:   FGMeritCtx  meritctx;
 20:   TaoTerminateReason reason=TAO_CONTINUE_ITERATING;
 21:   TaoVec *x, *l, *u, *ff, *d, *w, *g;
 22:   TaoMat *J,*Jsub;
 23:   TaoVec *dxfree,*r1;
 24:   TaoIndexSet *FreeVariableSet;
 25:   int iter=0, info;
 26:   int lsflag;
 27:   double ndpsi,stepsize=1.0;
 28:   //  double psi,psi1,psi2;
 29:   TaoTruth success;
 30:   double fff,fff_full,gdx;
 31:   double gamma = 0.0, gamma_factor =1.0e-12;
 32:   //  double fref;

 34:   TaoFunctionBegin;

 36:   ff = asls->dpsi;
 37:   d = asls->d;
 38:   g = asls->t1;
 39:   w = asls->w;

 41:   /*
 42:   f = asls->f;
 43:   ff = asls->ff;
 44:   t2 = asls->t2;
 45:   da = asls->da;
 46:   db = asls->db;
 47:   */
 48:   /* Check if upper bound greater than lower bound. */
 49:   info = TaoGetSolution(tao, &x); CHKERRQ(info);
 50:   info = TaoGetVariableBounds(tao, &l, &u); CHKERRQ(info);
 51:   info = TaoEvaluateVariableBounds(tao,l,u); CHKERRQ(info);
 52:   info = TaoGetJacobian(tao, &J); CHKERRQ(info);
 53:   meritctx.J=J;
 54:   meritctx.f=ff;
 55:   info = TaoSetMeritFunction(tao, Tao_RSCS_Function, Tao_RSCS_FunctionGradient,
 56:                              TAO_NULL, TAO_NULL, (void*)&meritctx ); CHKERRQ(info);

 58:   /*   Project the current point onto the feasible set */
 59:   info = x->Median(l,x,u); CHKERRQ(info);
 60:   
 61:   info = TaoComputeMeritFunctionGradient(tao, x, &fff, g); CHKERRQ(info);

 63:   info = x->CreateIndexSet(&FreeVariableSet); CHKERRQ(info);
 64:   info = J->CreateReducedMatrix(FreeVariableSet,FreeVariableSet,&Jsub); CHKERRQ(info);
 65:   info = x->Clone(&dxfree); CHKERRQ(info);
 66:   info = x->Clone(&r1); CHKERRQ(info);

 68:   while (reason==TAO_CONTINUE_ITERATING){
 69:     
 70:     /* Project the gradient and calculate the norm */
 71:     info = w->BoundGradientProjection(ff,l,x,u);CHKERRQ(info);
 72:     info = w->Norm2(&ndpsi); CHKERRQ(info);

 74:     info = TaoMonitor(tao,iter++,fff,ndpsi,0.0,stepsize,&reason);
 75:     CHKERRQ(info);

 77:     if (reason!=TAO_CONTINUE_ITERATING) break;

 79:     info = FreeVariableSet->WhichEqual(w,ff); CHKERRQ(info);

 81:     /* Create a reduced linear system */
 82:     info = r1->SetReducedVec(ff,FreeVariableSet);CHKERRQ(info);
 83:     info = r1->Negate();CHKERRQ(info);

 85:     info = dxfree->SetReducedVec(d,FreeVariableSet);CHKERRQ(info);
 86:     info = dxfree->SetToZero(); CHKERRQ(info);
 87:     
 88:     info = TaoComputeJacobian(tao,x,J);CHKERRQ(info);    
 89:     info = Jsub->SetReducedMatrix(J,FreeVariableSet,FreeVariableSet);CHKERRQ(info);
 90:     
 91:     success = TAO_FALSE;
 92:     gamma = gamma_factor*(ndpsi); 
 93:     while (success==TAO_FALSE) {
 94:       
 95:       /* Approximately solve the reduced linear system */
 96:       info = TaoPreLinearSolve(tao,Jsub);CHKERRQ(info);
 97:       info = TaoLinearSolve(tao,Jsub,r1,dxfree,&success);CHKERRQ(info);
 98:     
 99:       info = d->SetToZero(); CHKERRQ(info);
100:       info = d->ReducedXPY(dxfree,FreeVariableSet);CHKERRQ(info);
101:       
102:       info = d->Dot(ff,&gdx); CHKERRQ(info);
103:       

105:       if (success==TAO_FALSE) { /* Modify diagonal of Hessian if not a descent direction */

107:         info = Jsub->SetReducedMatrix(J,FreeVariableSet,FreeVariableSet);CHKERRQ(info);
108:         gamma *=10; 
109:         //          printf("Shift diagonal: %4.2e\n",gamma);
110:         info = PetscInfo2(tao,"TaoSolve_NLS:  modify diagonal (asuume same nonzero structure), gamma_factor=%g, gamma=%g\n",gamma_factor,gamma);CHKERRQ(info);
111:         info = Jsub->ShiftDiagonal(gamma);CHKERRQ(info);
112:         success = TAO_FALSE;
113:         
114:       } else {
115:         success = TAO_TRUE;
116:       }
117:       
118:     }

120:     //    fref=fff;
121:     info = g->ScaleCopyFrom(-1.0,d);CHKERRQ(info);
122:     stepsize=1.0;        
123:     info = TaoLineSearchApply(tao,x,g,d,w,
124:                               &fff,&fff_full, &stepsize,&lsflag);
125:     CHKERRQ(info);


128:     if (lsflag!=0){
129:       int attempts = 0;

131:       printf("Try Again \n");
132:       info = FreeVariableSet->WhichBetween(l,x,u); CHKERRQ(info);
133:       
134:       /* Create a reduced linear system */
135:       info = r1->SetReducedVec(ff,FreeVariableSet);CHKERRQ(info);
136:       info = r1->Negate();CHKERRQ(info);
137:       
138:       info = dxfree->SetReducedVec(d,FreeVariableSet);CHKERRQ(info);
139:       info = dxfree->SetToZero(); CHKERRQ(info);
140:       
141:       info = TaoComputeJacobian(tao,x,J);CHKERRQ(info);    
142:       info = Jsub->SetReducedMatrix(J,FreeVariableSet,FreeVariableSet);CHKERRQ(info);
143:       
144:       success = TAO_FALSE;
145:       gamma = gamma_factor*(ndpsi); 
146:       while (success==TAO_FALSE && attempts < 10) {
147:         
148:         /* Approximately solve the reduced linear system */
149:         info = TaoPreLinearSolve(tao,Jsub);CHKERRQ(info);
150:         info = TaoLinearSolve(tao,Jsub,r1,dxfree,&success);CHKERRQ(info);
151:         
152:         info = d->SetToZero(); CHKERRQ(info);
153:         info = d->ReducedXPY(dxfree,FreeVariableSet);CHKERRQ(info);
154:         
155:         info = d->Dot(ff,&gdx); CHKERRQ(info);
156:         
157:         if (success==TAO_FALSE) { /* Modify diagonal of Hessian if not a descent direction */
158:           
159:           info = Jsub->SetReducedMatrix(J,FreeVariableSet,FreeVariableSet);CHKERRQ(info);
160:           gamma *= 10; 
161:           //          printf("Shift diagonal: %4.2e\n",gamma);
162:           info = PetscInfo2(tao,"TaoSolve_NLS:  modify diagonal (asuume same nonzero structure), gamma_factor=%g, gamma=%g\n",
163:                                gamma_factor,gamma); CHKERRQ(info);
164:           info = Jsub->ShiftDiagonal(gamma);CHKERRQ(info);
165:           success = TAO_FALSE;
166:           
167:         } else {
168:           success = TAO_TRUE;
169:         }
170:         ++attempts;
171:       }
172:       
173:       //      fref=fff;
174:       info = g->ScaleCopyFrom(-1.0,d);CHKERRQ(info);
175:       stepsize=1.0;        
176:       info = TaoLineSearchApply(tao,x,g,d,w,
177:                                 &fff,&fff_full, &stepsize,&lsflag);
178:       CHKERRQ(info);
179:       
180:     }

182:     if ( iter>=40 && (iter%10==0) ){
183:       printf("Steepest Descent \n");
184:       info = d->ScaleCopyFrom(-1.0,ff);CHKERRQ(info);
185:       info = g->CopyFrom(ff);CHKERRQ(info);
186:       stepsize=1.0;        
187:       info = TaoLineSearchApply(tao,x,g,d,w,
188:                                 &fff,&fff_full, &stepsize,&lsflag);
189:       CHKERRQ(info);
190:       stepsize = 1.0e-6;
191:     }

193:     if (lsflag!=0 ){
194:       printf("Steepest Descent \n");
195:       info = d->ScaleCopyFrom(-1.0,ff);CHKERRQ(info);
196:       info = g->CopyFrom(ff);CHKERRQ(info);
197:       stepsize=1.0;        
198:       info = TaoLineSearchApply(tao,x,g,d,w,
199:                                 &fff,&fff_full, &stepsize,&lsflag);
200:       CHKERRQ(info);
201:       stepsize = 1.0e-6;
202:       
203:     }

205:     printf("Stepsize: %4.2e\n",stepsize);
206:   }  /* END MAIN LOOP  */


209:   info = TaoMatDestroy(Jsub);CHKERRQ(info);
210:   info = TaoVecDestroy(dxfree);CHKERRQ(info);
211:   info = TaoVecDestroy(r1);CHKERRQ(info);
212:   info = TaoIndexSetDestroy(FreeVariableSet);CHKERRQ(info);

214:   TaoFunctionReturn(0);
215: }


218: /* ---------------------------------------------------------- */
222: int TaoCreate_RSCS(TAO_SOLVER tao)
223: {
224:   TAO_SSLS *asls;
225:   int        info;

227:   TaoFunctionBegin;

229:   info = TaoNew(TAO_SSLS, &asls); CHKERRQ(info);
230:   info = PetscLogObjectMemory(tao, sizeof(TAO_SSLS)); CHKERRQ(info);

232:   info=TaoSetTaoSolveRoutine(tao,TaoSolve_RSCS,(void*)asls); CHKERRQ(info);
233:   info=TaoSetTaoSetUpDownRoutines(tao,TaoSetUp_SSLS,TaoSetDown_SSLS); CHKERRQ(info);
234:   info=TaoSetTaoOptionsRoutine(tao,TaoSetOptions_SSLS); CHKERRQ(info);
235:   info=TaoSetTaoViewRoutine(tao,TaoView_SSLS); CHKERRQ(info);

237:   // info = TaoCreateMoreThuenteBoundLineSearch(tao,0,0.9); CHKERRQ(info);
238:   info = TaoCreateNDProjectedArmijoLineSearch(tao); CHKERRQ(info);
239:   //   info = TaoCreateProjectedArmijoLineSearch(tao); CHKERRQ(info);
240:   info = TaoSetMeritFunction(tao, Tao_RSCS_Function, Tao_RSCS_FunctionGradient,
241:                              TAO_NULL, TAO_NULL, asls); CHKERRQ(info);

243:   info = TaoSetMaximumIterates(tao,2000); CHKERRQ(info);
244:   info = TaoSetMaximumFunctionEvaluations(tao,4000); CHKERRQ(info);

246:   info = TaoSetTolerances(tao,0,0,0,0); CHKERRQ(info);
247:   info = TaoSetGradientTolerances(tao,1.0e-16,0.0,0.0); CHKERRQ(info);
248:   info = TaoSetFunctionLowerBound(tao,1.0e-8); CHKERRQ(info);

250:   TaoFunctionReturn(0);
251: }

254: /*------------------------------------------------------------*/
257: int Tao_RSCS_Function(TAO_SOLVER tao, TaoVec *X, double *fcn, void *solver) 
258: {
259:   int info;
260:   double ndpsi;
261:   TaoVec *TT,*XL,*XU;
262:   FGMeritCtx*ctx = (FGMeritCtx*)solver;

264:   TaoFunctionBegin;
265:   info = TaoGetVariableBounds(tao, &XL, &XU); CHKERRQ(info);
266:   info = X->Clone(&TT); CHKERRQ(info);
267:   info = TaoComputeConstraints(tao, X, ctx->f); CHKERRQ(info);
268:   info = TT->Fischer(X, ctx->f, XL, XU); CHKERRQ(info);
269:   //  info = TT->BoundGradientProjection(ctx->f,XL,X,XU);CHKERRQ(info);
270:   info = TT->Norm2(&ndpsi); CHKERRQ(info);
271:   *fcn=ndpsi;
272:   info = PetscInfo1(tao,"RSCS Function value: %4.2e\n",*fcn); CHKERRQ(info);
273:   info = TaoVecDestroy(TT); CHKERRQ(info);
274:   TaoFunctionReturn(0);
275: }

277: /*------------------------------------------------------------*/
280: int Tao_RSCS_FunctionGradient(TAO_SOLVER tao, TaoVec *X, double *fcn, 
281:                               TaoVec *G, void *solver)
282: {
283:   int info;
284:   double ndpsi;
285:   TaoVec *XL,*XU,*TT,*f;
286:   TaoMat *J;
287:   FGMeritCtx*ctx = (FGMeritCtx*)solver;

289:   TaoFunctionBegin;
290:   J=ctx->J;
291:   f=ctx->f;
292:   info = TaoGetVariableBounds(tao, &XL, &XU); CHKERRQ(info);
293:   info = TaoComputeConstraints(tao, X, f); CHKERRQ(info);
294:   //  info = TaoComputeJacobian(tao,X,J); CHKERRQ(info);

296:   if (0==1){
297:     info = G->BoundGradientProjection(f,XL,X,XU);CHKERRQ(info);
298:     info = G->Norm2(&ndpsi); CHKERRQ(info);
299:     info = G->CopyFrom(f);CHKERRQ(info);
300:     *fcn=ndpsi;
301:   } else if (2==2){
302:     info = G->Fischer(X, f, XL, XU); CHKERRQ(info);
303:     info = G->Norm2(fcn); CHKERRQ(info);
304:     info = G->CopyFrom(f);CHKERRQ(info);
305:   } else {
306:     info = G->Clone(&TT); CHKERRQ(info);
307:     info = TT->BoundGradientProjection(f,XL,X,XU);CHKERRQ(info);
308:     info = TT->Norm2(&ndpsi); CHKERRQ(info);
309:     *fcn=ndpsi*ndpsi/2;
310:     *fcn=ndpsi;
311:     info = J->MultiplyTranspose(TT,G);CHKERRQ(info);
312:     info = TaoVecDestroy(TT); CHKERRQ(info);
313:   }

315:   info = PetscInfo1(tao,"RSCS Function value: %4.2e\n",*fcn); CHKERRQ(info);

317:   TaoFunctionReturn(0);
318: }