static PetscErrorCode TaoComputeDual_GPCG(Tao tao, Vec DXL, Vec DXU) { TAO_GPCG *gpcg = (TAO_GPCG *)tao->data; PetscErrorCode ierr; PetscFunctionBegin; ierr = VecBoundGradientProjection(tao->gradient, tao->solution, tao->XL, tao->XU, gpcg->Work);CHKERRQ(ierr); ierr = VecCopy(gpcg->Work, DXL);CHKERRQ(ierr); ierr = VecAXPY(DXL,-1.0,tao->gradient);CHKERRQ(ierr); ierr = VecSet(DXU,0.0);CHKERRQ(ierr); ierr = VecPointwiseMax(DXL,DXL,DXU);CHKERRQ(ierr); ierr = VecCopy(tao->gradient,DXU);CHKERRQ(ierr); ierr = VecAXPY(DXU,-1.0,gpcg->Work);CHKERRQ(ierr); ierr = VecSet(gpcg->Work,0.0);CHKERRQ(ierr); ierr = VecPointwiseMin(DXU,gpcg->Work,DXU);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode GPCGGradProjections(Tao tao) { PetscErrorCode ierr; TAO_GPCG *gpcg = (TAO_GPCG *)tao->data; PetscInt i; PetscReal actred=-1.0,actred_max=0.0, gAg,gtg=gpcg->gnorm,alpha; PetscReal f_new,gdx,stepsize; Vec DX=tao->stepdirection,XL=tao->XL,XU=tao->XU,Work=gpcg->Work; Vec X=tao->solution,G=tao->gradient; TaoLineSearchConvergedReason lsflag=TAOLINESEARCH_CONTINUE_ITERATING; /* The free, active, and binding variables should be already identified */ PetscFunctionBegin; for (i=0;i<gpcg->maxgpits;i++){ if ( -actred <= (gpcg->pg_ftol)*actred_max) break; ierr = VecBoundGradientProjection(G,X,XL,XU,DX);CHKERRQ(ierr); ierr = VecScale(DX,-1.0);CHKERRQ(ierr); ierr = VecDot(DX,G,&gdx);CHKERRQ(ierr); ierr = MatMult(tao->hessian,DX,Work);CHKERRQ(ierr); ierr = VecDot(DX,Work,&gAg);CHKERRQ(ierr); gpcg->gp_iterates++; gpcg->total_gp_its++; gtg=-gdx; alpha = PetscAbsReal(gtg/gAg); ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,alpha);CHKERRQ(ierr); f_new=gpcg->f; ierr = TaoLineSearchApply(tao->linesearch,X,&f_new,G,DX,&stepsize,&lsflag);CHKERRQ(ierr); /* Update the iterate */ actred = f_new - gpcg->f; actred_max = PetscMax(actred_max,-(f_new - gpcg->f)); gpcg->f = f_new; ierr = ISDestroy(&gpcg->Free_Local);CHKERRQ(ierr); ierr = VecWhichBetween(XL,X,XU,&gpcg->Free_Local);CHKERRQ(ierr); } gpcg->gnorm=gtg; PetscFunctionReturn(0); } /* End gradient projections */
static PetscErrorCode TaoComputeDual_TRON(Tao tao, Vec DXL, Vec DXU) { TAO_TRON *tron = (TAO_TRON *)tao->data; PetscErrorCode ierr; PetscFunctionBegin; PetscValidHeaderSpecific(tao,TAO_CLASSID,1); PetscValidHeaderSpecific(DXL,VEC_CLASSID,2); PetscValidHeaderSpecific(DXU,VEC_CLASSID,3); if (!tron->Work || !tao->gradient) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Dual variables don't exist yet or no longer exist.\n"); ierr = VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,tron->Work);CHKERRQ(ierr); ierr = VecCopy(tron->Work,DXL);CHKERRQ(ierr); ierr = VecAXPY(DXL,-1.0,tao->gradient);CHKERRQ(ierr); ierr = VecSet(DXU,0.0);CHKERRQ(ierr); ierr = VecPointwiseMax(DXL,DXL,DXU);CHKERRQ(ierr); ierr = VecCopy(tao->gradient,DXU);CHKERRQ(ierr); ierr = VecAXPY(DXU,-1.0,tron->Work);CHKERRQ(ierr); ierr = VecSet(tron->Work,0.0);CHKERRQ(ierr); ierr = VecPointwiseMin(DXU,tron->Work,DXU);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode TaoLineSearchApply_MT(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s) { PetscErrorCode ierr; TaoLineSearch_MT *mt; PetscReal xtrapf = 4.0; PetscReal finit, width, width1, dginit, fm, fxm, fym, dgm, dgxm, dgym; PetscReal dgx, dgy, dg, dg2, fx, fy, stx, sty, dgtest; PetscReal ftest1=0.0, ftest2=0.0; PetscInt i, stage1,n1,n2,nn1,nn2; PetscReal bstepmin1, bstepmin2, bstepmax; PetscBool g_computed=PETSC_FALSE; /* to prevent extra gradient computation */ PetscFunctionBegin; PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1); PetscValidHeaderSpecific(x,VEC_CLASSID,2); PetscValidScalarPointer(f,3); PetscValidHeaderSpecific(g,VEC_CLASSID,4); PetscValidHeaderSpecific(s,VEC_CLASSID,5); /* comm,type,size checks are done in interface TaoLineSearchApply */ mt = (TaoLineSearch_MT*)(ls->data); ls->reason = TAOLINESEARCH_CONTINUE_ITERATING; /* Check work vector */ if (!mt->work) { ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr); mt->x = x; ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr); } else if (x != mt->x) { ierr = VecDestroy(&mt->work);CHKERRQ(ierr); ierr = VecDuplicate(x,&mt->work);CHKERRQ(ierr); ierr = PetscObjectDereference((PetscObject)mt->x);CHKERRQ(ierr); mt->x = x; ierr = PetscObjectReference((PetscObject)mt->x);CHKERRQ(ierr); } if (ls->bounded) { /* Compute step length needed to make all variables equal a bound */ /* Compute the smallest steplength that will make one nonbinding variable equal the bound */ ierr = VecGetLocalSize(ls->upper,&n1);CHKERRQ(ierr); ierr = VecGetLocalSize(mt->x, &n2);CHKERRQ(ierr); ierr = VecGetSize(ls->upper,&nn1);CHKERRQ(ierr); ierr = VecGetSize(mt->x,&nn2);CHKERRQ(ierr); if (n1 != n2 || nn1 != nn2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Variable vector not compatible with bounds vector"); ierr = VecScale(s,-1.0);CHKERRQ(ierr); ierr = VecBoundGradientProjection(s,x,ls->lower,ls->upper,s);CHKERRQ(ierr); ierr = VecScale(s,-1.0);CHKERRQ(ierr); ierr = VecStepBoundInfo(x,s,ls->lower,ls->upper,&bstepmin1,&bstepmin2,&bstepmax);CHKERRQ(ierr); ls->stepmax = PetscMin(bstepmax,1.0e15); } ierr = VecDot(g,s,&dginit);CHKERRQ(ierr); if (PetscIsInfOrNanReal(dginit)) { ierr = PetscInfo1(ls,"Initial Line Search step * g is Inf or Nan (%g)\n",(double)dginit);CHKERRQ(ierr); ls->reason=TAOLINESEARCH_FAILED_INFORNAN; PetscFunctionReturn(0); } if (dginit >= 0.0) { ierr = PetscInfo1(ls,"Initial Line Search step * g is not descent direction (%g)\n",(double)dginit);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_FAILED_ASCENT; PetscFunctionReturn(0); } /* Initialization */ mt->bracket = 0; stage1 = 1; finit = *f; dgtest = ls->ftol * dginit; width = ls->stepmax - ls->stepmin; width1 = width * 2.0; ierr = VecCopy(x,mt->work);CHKERRQ(ierr); /* Variable dictionary: stx, fx, dgx - the step, function, and derivative at the best step sty, fy, dgy - the step, function, and derivative at the other endpoint of the interval of uncertainty step, f, dg - the step, function, and derivative at the current step */ stx = 0.0; fx = finit; dgx = dginit; sty = 0.0; fy = finit; dgy = dginit; ls->step=ls->initstep; for (i=0; i< ls->max_funcs; i++) { /* Set min and max steps to correspond to the interval of uncertainty */ if (mt->bracket) { ls->stepmin = PetscMin(stx,sty); ls->stepmax = PetscMax(stx,sty); } else { ls->stepmin = stx; ls->stepmax = ls->step + xtrapf * (ls->step - stx); } /* Force the step to be within the bounds */ ls->step = PetscMax(ls->step,ls->stepmin); ls->step = PetscMin(ls->step,ls->stepmax); /* If an unusual termination is to occur, then let step be the lowest point obtained thus far */ if ((stx!=0) && (((mt->bracket) && (ls->step <= ls->stepmin || ls->step >= ls->stepmax)) || ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol * ls->stepmax)) || ((ls->nfeval+ls->nfgeval) >= ls->max_funcs - 1) || (mt->infoc == 0))) { ls->step = stx; } ierr = VecCopy(x,mt->work);CHKERRQ(ierr); ierr = VecAXPY(mt->work,ls->step,s);CHKERRQ(ierr); /* W = X + step*S */ if (ls->bounded) { ierr = VecMedian(ls->lower, mt->work, ls->upper, mt->work);CHKERRQ(ierr); } if (ls->usegts) { ierr = TaoLineSearchComputeObjectiveAndGTS(ls,mt->work,f,&dg);CHKERRQ(ierr); g_computed=PETSC_FALSE; } else { ierr = TaoLineSearchComputeObjectiveAndGradient(ls,mt->work,f,g);CHKERRQ(ierr); g_computed=PETSC_TRUE; if (ls->bounded) { ierr = VecDot(g,x,&dg);CHKERRQ(ierr); ierr = VecDot(g,mt->work,&dg2);CHKERRQ(ierr); dg = (dg2 - dg)/ls->step; } else { ierr = VecDot(g,s,&dg);CHKERRQ(ierr); } } if (0 == i) { ls->f_fullstep=*f; } if (PetscIsInfOrNanReal(*f) || PetscIsInfOrNanReal(dg)) { /* User provided compute function generated Not-a-Number, assume domain violation and set function value and directional derivative to infinity. */ *f = PETSC_INFINITY; dg = PETSC_INFINITY; } ftest1 = finit + ls->step * dgtest; if (ls->bounded) { ftest2 = finit + ls->step * dgtest * ls->ftol; } /* Convergence testing */ if (((*f - ftest1 <= 1.0e-10 * PetscAbsReal(finit)) && (PetscAbsReal(dg) + ls->gtol*dginit <= 0.0))) { ierr = PetscInfo(ls, "Line search success: Sufficient decrease and directional deriv conditions hold\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_SUCCESS; break; } /* Check Armijo if beyond the first breakpoint */ if (ls->bounded && (*f <= ftest2) && (ls->step >= bstepmin2)) { ierr = PetscInfo(ls,"Line search success: Sufficient decrease.\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_SUCCESS; break; } /* Checks for bad cases */ if (((mt->bracket) && (ls->step <= ls->stepmin||ls->step >= ls->stepmax)) || (!mt->infoc)) { ierr = PetscInfo(ls,"Rounding errors may prevent further progress. May not be a step satisfying\n");CHKERRQ(ierr); ierr = PetscInfo(ls,"sufficient decrease and curvature conditions. Tolerances may be too small.\n");CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_OTHER; break; } if ((ls->step == ls->stepmax) && (*f <= ftest1) && (dg <= dgtest)) { ierr = PetscInfo1(ls,"Step is at the upper bound, stepmax (%g)\n",(double)ls->stepmax);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_UPPERBOUND; break; } if ((ls->step == ls->stepmin) && (*f >= ftest1) && (dg >= dgtest)) { ierr = PetscInfo1(ls,"Step is at the lower bound, stepmin (%g)\n",(double)ls->stepmin);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_LOWERBOUND; break; } if ((mt->bracket) && (ls->stepmax - ls->stepmin <= ls->rtol*ls->stepmax)){ ierr = PetscInfo1(ls,"Relative width of interval of uncertainty is at most rtol (%g)\n",(double)ls->rtol);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_RTOL; break; } /* In the first stage, we seek a step for which the modified function has a nonpositive value and nonnegative derivative */ if ((stage1) && (*f <= ftest1) && (dg >= dginit * PetscMin(ls->ftol, ls->gtol))) { stage1 = 0; } /* A modified function is used to predict the step only if we have not obtained a step for which the modified function has a nonpositive function value and nonnegative derivative, and if a lower function value has been obtained but the decrease is not sufficient */ if ((stage1) && (*f <= fx) && (*f > ftest1)) { fm = *f - ls->step * dgtest; /* Define modified function */ fxm = fx - stx * dgtest; /* and derivatives */ fym = fy - sty * dgtest; dgm = dg - dgtest; dgxm = dgx - dgtest; dgym = dgy - dgtest; /* if (dgxm * (ls->step - stx) >= 0.0) */ /* Update the interval of uncertainty and compute the new step */ ierr = Tao_mcstep(ls,&stx,&fxm,&dgxm,&sty,&fym,&dgym,&ls->step,&fm,&dgm);CHKERRQ(ierr); fx = fxm + stx * dgtest; /* Reset the function and */ fy = fym + sty * dgtest; /* gradient values */ dgx = dgxm + dgtest; dgy = dgym + dgtest; } else { /* Update the interval of uncertainty and compute the new step */ ierr = Tao_mcstep(ls,&stx,&fx,&dgx,&sty,&fy,&dgy,&ls->step,f,&dg);CHKERRQ(ierr); } /* Force a sufficient decrease in the interval of uncertainty */ if (mt->bracket) { if (PetscAbsReal(sty - stx) >= 0.66 * width1) ls->step = stx + 0.5*(sty - stx); width1 = width; width = PetscAbsReal(sty - stx); } } if ((ls->nfeval+ls->nfgeval) > ls->max_funcs) { ierr = PetscInfo2(ls,"Number of line search function evals (%D) > maximum (%D)\n",(ls->nfeval+ls->nfgeval),ls->max_funcs);CHKERRQ(ierr); ls->reason = TAOLINESEARCH_HALTED_MAXFCN; } /* Finish computations */ ierr = PetscInfo2(ls,"%D function evals in line search, step = %g\n",(ls->nfeval+ls->nfgeval),(double)ls->step);CHKERRQ(ierr); /* Set new solution vector and compute gradient if needed */ ierr = VecCopy(mt->work,x);CHKERRQ(ierr); if (!g_computed) { ierr = TaoLineSearchComputeGradient(ls,mt->work,g);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_SSFLS(Tao tao) { TAO_SSLS *ssls = (TAO_SSLS *)tao->data; PetscReal psi, ndpsi, normd, innerd, t=0; PetscReal delta, rho; PetscInt iter=0,kspits; TaoConvergedReason reason; TaoLineSearchConvergedReason ls_reason; PetscErrorCode ierr; PetscFunctionBegin; /* Assume that Setup has been called! Set the structure for the Jacobian and create a linear solver. */ delta = ssls->delta; rho = ssls->rho; ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); /* Project solution inside bounds */ ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); ierr = TaoLineSearchSetObjectiveAndGradientRoutine(tao->linesearch,Tao_SSLS_FunctionGradient,tao);CHKERRQ(ierr); ierr = TaoLineSearchSetObjectiveRoutine(tao->linesearch,Tao_SSLS_Function,tao);CHKERRQ(ierr); /* Calculate the function value and fischer function value at the current iterate */ ierr = TaoLineSearchComputeObjectiveAndGradient(tao->linesearch,tao->solution,&psi,ssls->dpsi);CHKERRQ(ierr); ierr = VecNorm(ssls->dpsi,NORM_2,&ndpsi);CHKERRQ(ierr); while (1) { ierr=PetscInfo3(tao, "iter: %D, merit: %g, ndpsi: %g\n",iter, (double)ssls->merit, (double)ndpsi);CHKERRQ(ierr); /* Check the termination criteria */ ierr = TaoMonitor(tao,iter++,ssls->merit,ndpsi,0.0,t,&reason);CHKERRQ(ierr); if (reason!=TAO_CONTINUE_ITERATING) break; /* Calculate direction. (Really negative of newton direction. Therefore, rest of the code uses -d.) */ ierr = KSPSetOperators(tao->ksp,tao->jacobian,tao->jacobian_pre);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,ssls->ff,tao->stepdirection);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); tao->ksp_its+=kspits; ierr = VecCopy(tao->stepdirection,ssls->w);CHKERRQ(ierr); ierr = VecScale(ssls->w,-1.0);CHKERRQ(ierr); ierr = VecBoundGradientProjection(ssls->w,tao->solution,tao->XL,tao->XU,ssls->w);CHKERRQ(ierr); ierr = VecNorm(ssls->w,NORM_2,&normd);CHKERRQ(ierr); ierr = VecDot(ssls->w,ssls->dpsi,&innerd);CHKERRQ(ierr); /* Make sure that we have a descent direction */ if (innerd >= -delta*pow(normd, rho)) { ierr = PetscInfo(tao, "newton direction not descent\n");CHKERRQ(ierr); ierr = VecCopy(ssls->dpsi,tao->stepdirection);CHKERRQ(ierr); ierr = VecDot(ssls->w,ssls->dpsi,&innerd);CHKERRQ(ierr); } ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); innerd = -innerd; ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0); ierr = TaoLineSearchApply(tao->linesearch,tao->solution,&psi,ssls->dpsi,tao->stepdirection,&t,&ls_reason);CHKERRQ(ierr); ierr = VecNorm(ssls->dpsi,NORM_2,&ndpsi);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_TRON(Tao tao) { TAO_TRON *tron = (TAO_TRON *)tao->data; PetscErrorCode ierr; PetscInt its; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; TaoLineSearchConvergedReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING; PetscReal prered,actred,delta,f,f_new,rhok,gdx,xdiff,stepsize; PetscFunctionBegin; tron->pgstepsize=1.0; tao->trust = tao->trust0; /* Project the current point onto the feasible set */ ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&tron->f,tao->gradient);CHKERRQ(ierr); ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr); ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr); /* Project the gradient and calculate the norm */ ierr = VecBoundGradientProjection(tao->gradient,tao->solution, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr); ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr); if (PetscIsInfOrNanReal(tron->f) || PetscIsInfOrNanReal(tron->gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf pr NaN"); if (tao->trust <= 0) { tao->trust=PetscMax(tron->gnorm*tron->gnorm,1.0); } tron->stepsize=tao->trust; ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, tron->stepsize, &reason);CHKERRQ(ierr); while (reason==TAO_CONTINUE_ITERATING){ tao->ksp_its=0; ierr = TronGradientProjections(tao,tron);CHKERRQ(ierr); f=tron->f; delta=tao->trust; tron->n_free_last = tron->n_free; ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); ierr = ISGetSize(tron->Free_Local, &tron->n_free);CHKERRQ(ierr); /* If no free variables */ if (tron->n_free == 0) { actred=0; ierr = PetscInfo(tao,"No free variables in tron iteration.\n");CHKERRQ(ierr); ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr); ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, delta, &reason);CHKERRQ(ierr); if (!reason) { reason = TAO_CONVERGED_STEPTOL; ierr = TaoSetConvergedReason(tao,reason);CHKERRQ(ierr); } break; } /* use free_local to mask/submat gradient, hessian, stepdirection */ ierr = TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->R);CHKERRQ(ierr); ierr = TaoVecGetSubVec(tao->gradient,tron->Free_Local,tao->subset_type,0.0,&tron->DXFree);CHKERRQ(ierr); ierr = VecSet(tron->DXFree,0.0);CHKERRQ(ierr); ierr = VecScale(tron->R, -1.0);CHKERRQ(ierr); ierr = TaoMatGetSubMat(tao->hessian, tron->Free_Local, tron->diag, tao->subset_type, &tron->H_sub);CHKERRQ(ierr); if (tao->hessian == tao->hessian_pre) { ierr = MatDestroy(&tron->Hpre_sub);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)(tron->H_sub));CHKERRQ(ierr); tron->Hpre_sub = tron->H_sub; } else { ierr = TaoMatGetSubMat(tao->hessian_pre, tron->Free_Local, tron->diag, tao->subset_type,&tron->Hpre_sub);CHKERRQ(ierr); } ierr = KSPReset(tao->ksp);CHKERRQ(ierr); ierr = KSPSetOperators(tao->ksp, tron->H_sub, tron->Hpre_sub);CHKERRQ(ierr); while (1) { /* Approximately solve the reduced linear system */ ierr = KSPSTCGSetRadius(tao->ksp,delta);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp, tron->R, tron->DXFree);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its+=its; tao->ksp_tot_its+=its; ierr = VecSet(tao->stepdirection,0.0);CHKERRQ(ierr); /* Add dxfree matrix to compute step direction vector */ ierr = VecISAXPY(tao->stepdirection,tron->Free_Local,1.0,tron->DXFree);CHKERRQ(ierr); if (0) { PetscReal rhs,stepnorm; ierr = VecNorm(tron->R,NORM_2,&rhs);CHKERRQ(ierr); ierr = VecNorm(tron->DXFree,NORM_2,&stepnorm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"|rhs|=%g\t|s|=%g\n",(double)rhs,(double)stepnorm);CHKERRQ(ierr); } ierr = VecDot(tao->gradient, tao->stepdirection, &gdx);CHKERRQ(ierr); ierr = PetscInfo1(tao,"Expected decrease in function value: %14.12e\n",(double)gdx);CHKERRQ(ierr); ierr = VecCopy(tao->solution, tron->X_New);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, tron->G_New);CHKERRQ(ierr); stepsize=1.0;f_new=f; ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); ierr = TaoLineSearchApply(tao->linesearch, tron->X_New, &f_new, tron->G_New, tao->stepdirection,&stepsize,&ls_reason);CHKERRQ(ierr);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); ierr = MatMult(tao->hessian, tao->stepdirection, tron->Work);CHKERRQ(ierr); ierr = VecAYPX(tron->Work, 0.5, tao->gradient);CHKERRQ(ierr); ierr = VecDot(tao->stepdirection, tron->Work, &prered);CHKERRQ(ierr); actred = f_new - f; if (actred<0) { rhok=PetscAbs(-actred/prered); } else { rhok=0.0; } /* Compare actual improvement to the quadratic model */ if (rhok > tron->eta1) { /* Accept the point */ /* d = x_new - x */ ierr = VecCopy(tron->X_New, tao->stepdirection);CHKERRQ(ierr); ierr = VecAXPY(tao->stepdirection, -1.0, tao->solution);CHKERRQ(ierr); ierr = VecNorm(tao->stepdirection, NORM_2, &xdiff);CHKERRQ(ierr); xdiff *= stepsize; /* Adjust trust region size */ if (rhok < tron->eta2 ){ delta = PetscMin(xdiff,delta)*tron->sigma1; } else if (rhok > tron->eta4 ){ delta= PetscMin(xdiff,delta)*tron->sigma3; } else if (rhok > tron->eta3 ){ delta=PetscMin(xdiff,delta)*tron->sigma2; } ierr = VecBoundGradientProjection(tron->G_New,tron->X_New, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr); if (tron->Free_Local) { ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr); } ierr = VecWhichBetween(tao->XL, tron->X_New, tao->XU, &tron->Free_Local);CHKERRQ(ierr); f=f_new; ierr = VecNorm(tao->gradient,NORM_2,&tron->gnorm);CHKERRQ(ierr); ierr = VecCopy(tron->X_New, tao->solution);CHKERRQ(ierr); ierr = VecCopy(tron->G_New, tao->gradient);CHKERRQ(ierr); break; } else if (delta <= 1e-30) { break; } else { delta /= 4.0; } } /* end linear solve loop */ tron->f=f; tron->actred=actred; tao->trust=delta; tao->niter++; ierr = TaoMonitor(tao, tao->niter, tron->f, tron->gnorm, 0.0, delta, &reason);CHKERRQ(ierr); } /* END MAIN LOOP */ PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_GPCG(Tao tao) { TAO_GPCG *gpcg = (TAO_GPCG *)tao->data; PetscErrorCode ierr; PetscInt its; PetscReal actred,f,f_new,gnorm,gdx,stepsize,xtb; PetscReal xtHx; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; PetscFunctionBegin; ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); /* Using f = .5*x'Hx + x'b + c and g=Hx + b, compute b,c */ ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, gpcg->B);CHKERRQ(ierr); ierr = MatMult(tao->hessian,tao->solution,gpcg->Work);CHKERRQ(ierr); ierr = VecDot(gpcg->Work, tao->solution, &xtHx);CHKERRQ(ierr); ierr = VecAXPY(gpcg->B,-1.0,gpcg->Work);CHKERRQ(ierr); ierr = VecDot(gpcg->B,tao->solution,&xtb);CHKERRQ(ierr); gpcg->c=f-xtHx/2.0-xtb; if (gpcg->Free_Local) { ierr = ISDestroy(&gpcg->Free_Local);CHKERRQ(ierr); } ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&gpcg->Free_Local);CHKERRQ(ierr); /* Project the gradient and calculate the norm */ ierr = VecCopy(tao->gradient,gpcg->G_New);CHKERRQ(ierr); ierr = VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU,gpcg->PG);CHKERRQ(ierr); ierr = VecNorm(gpcg->PG,NORM_2,&gpcg->gnorm);CHKERRQ(ierr); tao->step=1.0; gpcg->f = f; /* Check Stopping Condition */ ierr=TaoMonitor(tao,tao->niter,f,gpcg->gnorm,0.0,tao->step,&reason);CHKERRQ(ierr); while (reason == TAO_CONTINUE_ITERATING){ tao->ksp_its=0; ierr = GPCGGradProjections(tao);CHKERRQ(ierr); ierr = ISGetSize(gpcg->Free_Local,&gpcg->n_free);CHKERRQ(ierr); f=gpcg->f; gnorm=gpcg->gnorm; ierr = KSPReset(tao->ksp);CHKERRQ(ierr); if (gpcg->n_free > 0){ /* Create a reduced linear system */ ierr = VecDestroy(&gpcg->R);CHKERRQ(ierr); ierr = VecDestroy(&gpcg->DXFree);CHKERRQ(ierr); ierr = TaoVecGetSubVec(tao->gradient,gpcg->Free_Local, tao->subset_type, 0.0, &gpcg->R);CHKERRQ(ierr); ierr = VecScale(gpcg->R, -1.0);CHKERRQ(ierr); ierr = TaoVecGetSubVec(tao->stepdirection,gpcg->Free_Local,tao->subset_type, 0.0, &gpcg->DXFree);CHKERRQ(ierr); ierr = VecSet(gpcg->DXFree,0.0);CHKERRQ(ierr); ierr = TaoMatGetSubMat(tao->hessian, gpcg->Free_Local, gpcg->Work, tao->subset_type, &gpcg->Hsub);CHKERRQ(ierr); if (tao->hessian_pre == tao->hessian) { ierr = MatDestroy(&gpcg->Hsub_pre);CHKERRQ(ierr); ierr = PetscObjectReference((PetscObject)gpcg->Hsub);CHKERRQ(ierr); gpcg->Hsub_pre = gpcg->Hsub; } else { ierr = TaoMatGetSubMat(tao->hessian, gpcg->Free_Local, gpcg->Work, tao->subset_type, &gpcg->Hsub_pre);CHKERRQ(ierr); } ierr = KSPReset(tao->ksp);CHKERRQ(ierr); ierr = KSPSetOperators(tao->ksp,gpcg->Hsub,gpcg->Hsub_pre);CHKERRQ(ierr); ierr = KSPSolve(tao->ksp,gpcg->R,gpcg->DXFree);CHKERRQ(ierr); ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); tao->ksp_its+=its; tao->ksp_tot_its+=its; ierr = VecSet(tao->stepdirection,0.0);CHKERRQ(ierr); ierr = VecISAXPY(tao->stepdirection,gpcg->Free_Local,1.0,gpcg->DXFree);CHKERRQ(ierr); ierr = VecDot(tao->stepdirection,tao->gradient,&gdx);CHKERRQ(ierr); ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); f_new=f; ierr = TaoLineSearchApply(tao->linesearch,tao->solution,&f_new,tao->gradient,tao->stepdirection,&stepsize,&ls_status);CHKERRQ(ierr); actred = f_new - f; /* Evaluate the function and gradient at the new point */ ierr = VecBoundGradientProjection(tao->gradient,tao->solution,tao->XL,tao->XU, gpcg->PG);CHKERRQ(ierr); ierr = VecNorm(gpcg->PG, NORM_2, &gnorm);CHKERRQ(ierr); f=f_new; ierr = ISDestroy(&gpcg->Free_Local);CHKERRQ(ierr); ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&gpcg->Free_Local);CHKERRQ(ierr); } else { actred = 0; gpcg->step=1.0; /* if there were no free variables, no cg method */ } tao->niter++; ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,gpcg->step,&reason);CHKERRQ(ierr); gpcg->f=f;gpcg->gnorm=gnorm; gpcg->actred=actred; if (reason!=TAO_CONTINUE_ITERATING) break; } /* END MAIN LOOP */ PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_BLMVM(Tao tao) { PetscErrorCode ierr; TAO_BLMVM *blmP = (TAO_BLMVM *)tao->data; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; PetscReal f, fold, gdx, gnorm; PetscReal stepsize = 1.0,delta; PetscFunctionBegin; /* Project initial point onto bounds */ ierr = TaoComputeVariableBounds(tao);CHKERRQ(ierr); ierr = VecMedian(tao->XL,tao->solution,tao->XU,tao->solution);CHKERRQ(ierr); ierr = TaoLineSearchSetVariableBounds(tao->linesearch,tao->XL,tao->XU);CHKERRQ(ierr); /* Check convergence criteria */ ierr = TaoComputeObjectiveAndGradient(tao, tao->solution,&f,blmP->unprojected_gradient);CHKERRQ(ierr); ierr = VecBoundGradientProjection(blmP->unprojected_gradient,tao->solution, tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf pr NaN"); ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, stepsize, &reason);CHKERRQ(ierr); if (reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); /* Set initial scaling for the function */ if (f != 0.0) { delta = 2.0*PetscAbsScalar(f) / (gnorm*gnorm); } else { delta = 2.0 / (gnorm*gnorm); } ierr = MatLMVMSetDelta(blmP->M,delta);CHKERRQ(ierr); /* Set counter for gradient/reset steps */ blmP->grad = 0; blmP->reset = 0; /* Have not converged; continue with Newton method */ while (reason == TAO_CONTINUE_ITERATING) { /* Compute direction */ ierr = MatLMVMUpdate(blmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(blmP->M, blmP->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); ierr = VecBoundGradientProjection(tao->stepdirection,tao->solution,tao->XL,tao->XU,tao->gradient);CHKERRQ(ierr); /* Check for success (descent direction) */ ierr = VecDot(blmP->unprojected_gradient, tao->gradient, &gdx);CHKERRQ(ierr); if (gdx <= 0) { /* Step is not descent or solve was not successful Use steepest descent direction (scaled) */ ++blmP->grad; if (f != 0.0) { delta = 2.0*PetscAbsScalar(f) / (gnorm*gnorm); } else { delta = 2.0 / (gnorm*gnorm); } ierr = MatLMVMSetDelta(blmP->M,delta);CHKERRQ(ierr); ierr = MatLMVMReset(blmP->M);CHKERRQ(ierr); ierr = MatLMVMUpdate(blmP->M, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(blmP->M,blmP->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); } ierr = VecScale(tao->stepdirection,-1.0);CHKERRQ(ierr); /* Perform the linesearch */ fold = f; ierr = VecCopy(tao->solution, blmP->Xold);CHKERRQ(ierr); ierr = VecCopy(blmP->unprojected_gradient, blmP->Gold);CHKERRQ(ierr); ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, blmP->unprojected_gradient, tao->stepdirection, &stepsize, &ls_status);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { /* Linesearch failed Reset factors and use scaled (projected) gradient step */ ++blmP->reset; f = fold; ierr = VecCopy(blmP->Xold, tao->solution);CHKERRQ(ierr); ierr = VecCopy(blmP->Gold, blmP->unprojected_gradient);CHKERRQ(ierr); if (f != 0.0) { delta = 2.0* PetscAbsScalar(f) / (gnorm*gnorm); } else { delta = 2.0/ (gnorm*gnorm); } ierr = MatLMVMSetDelta(blmP->M,delta);CHKERRQ(ierr); ierr = MatLMVMReset(blmP->M);CHKERRQ(ierr); ierr = MatLMVMUpdate(blmP->M, tao->solution, blmP->unprojected_gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(blmP->M, blmP->unprojected_gradient, tao->stepdirection);CHKERRQ(ierr); ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); /* This may be incorrect; linesearch has values fo stepmax and stepmin that should be reset. */ ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0);CHKERRQ(ierr); ierr = TaoLineSearchApply(tao->linesearch,tao->solution,&f, blmP->unprojected_gradient, tao->stepdirection, &stepsize, &ls_status);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); if (ls_status != TAOLINESEARCH_SUCCESS && ls_status != TAOLINESEARCH_SUCCESS_USER) { tao->reason = TAO_DIVERGED_LS_FAILURE; break; } } /* Check for converged */ ierr = VecBoundGradientProjection(blmP->unprojected_gradient, tao->solution, tao->XL, tao->XU, tao->gradient);CHKERRQ(ierr); ierr = TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm);CHKERRQ(ierr); if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Not-a-Number"); tao->niter++; ierr = TaoMonitor(tao, tao->niter, f, gnorm, 0.0, stepsize, &reason);CHKERRQ(ierr); } PetscFunctionReturn(0); }