static PetscErrorCode TronGradientProjections(Tao tao,TAO_TRON *tron) { PetscErrorCode ierr; PetscInt i; TaoLineSearchConvergedReason ls_reason; PetscReal actred=-1.0,actred_max=0.0; PetscReal f_new; /* The gradient and function value passed into and out of this routine should be current and correct. The free, active, and binding variables should be already identified */ PetscFunctionBegin; if (tron->Free_Local) { ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr); } ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr); for (i=0;i<tron->maxgpits;i++){ if ( -actred <= (tron->pg_ftol)*actred_max) break; tron->gp_iterates++; tron->total_gp_its++; f_new=tron->f; ierr = VecCopy(tao->gradient, tao->stepdirection);CHKERRQ(ierr); ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,tron->pgstepsize);CHKERRQ(ierr); ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f_new, tao->gradient, tao->stepdirection, &tron->pgstepsize, &ls_reason);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); /* Update the iterate */ actred = f_new - tron->f; actred_max = PetscMax(actred_max,-(f_new - tron->f)); tron->f = f_new; if (tron->Free_Local) { ierr = ISDestroy(&tron->Free_Local);CHKERRQ(ierr); } ierr = VecWhichBetween(tao->XL,tao->solution,tao->XU,&tron->Free_Local);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_OWLQN(Tao tao) { TAO_OWLQN *lmP = (TAO_OWLQN *)tao->data; PetscReal f, fold, gdx, gnorm; PetscReal step = 1.0; PetscReal delta; PetscErrorCode ierr; PetscInt stepType; PetscInt iter = 0; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; TaoLineSearchConvergedReason ls_status = TAOLINESEARCH_CONTINUE_ITERATING; PetscFunctionBegin; if (tao->XL || tao->XU || tao->ops->computebounds) { ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by owlqn algorithm\n");CHKERRQ(ierr); } /* Check convergence criteria */ ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, lmP->GV);CHKERRQ(ierr); ierr = ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda);CHKERRQ(ierr); ierr = VecNorm(lmP->GV,NORM_2,&gnorm);CHKERRQ(ierr); if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); ierr = TaoMonitor(tao, iter, f, gnorm, 0.0, step, &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(lmP->M,delta);CHKERRQ(ierr); /* Set counter for gradient/reset steps */ lmP->bfgs = 0; lmP->sgrad = 0; lmP->grad = 0; /* Have not converged; continue with Newton method */ while (reason == TAO_CONTINUE_ITERATING) { /* Compute direction */ ierr = MatLMVMUpdate(lmP->M,tao->solution,tao->gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(lmP->M, lmP->GV, lmP->D);CHKERRQ(ierr); ierr = ProjDirect_OWLQN(lmP->D,lmP->GV);CHKERRQ(ierr); ++lmP->bfgs; /* Check for success (descent direction) */ ierr = VecDot(lmP->D, lmP->GV , &gdx);CHKERRQ(ierr); if ((gdx <= 0.0) || PetscIsInfOrNanReal(gdx)) { /* Step is not descent or direction produced not a number We can assert bfgsUpdates > 1 in this case because the first solve produces the scaled gradient direction, which is guaranteed to be descent Use steepest descent direction (scaled) */ ++lmP->grad; if (f != 0.0) { delta = 2.0 * PetscAbsScalar(f) / (gnorm*gnorm); } else { delta = 2.0 / (gnorm*gnorm); } ierr = MatLMVMSetDelta(lmP->M, delta);CHKERRQ(ierr); ierr = MatLMVMReset(lmP->M);CHKERRQ(ierr); ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(lmP->M,lmP->GV, lmP->D);CHKERRQ(ierr); ierr = ProjDirect_OWLQN(lmP->D,lmP->GV);CHKERRQ(ierr); lmP->bfgs = 1; ++lmP->sgrad; stepType = OWLQN_SCALED_GRADIENT; } else { if (1 == lmP->bfgs) { /* The first BFGS direction is always the scaled gradient */ ++lmP->sgrad; stepType = OWLQN_SCALED_GRADIENT; } else { ++lmP->bfgs; stepType = OWLQN_BFGS; } } ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); /* Perform the linesearch */ fold = f; ierr = VecCopy(tao->solution, lmP->Xold);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, lmP->Gold);CHKERRQ(ierr); ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step,&ls_status);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); while (((int)ls_status < 0) && (stepType != OWLQN_GRADIENT)) { /* Reset factors and use scaled gradient step */ f = fold; ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, lmP->GV);CHKERRQ(ierr); ierr = ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda);CHKERRQ(ierr); switch(stepType) { case OWLQN_BFGS: /* Failed to obtain acceptable iterate with BFGS step Attempt to use the scaled gradient direction */ if (f != 0.0) { delta = 2.0 * PetscAbsScalar(f) / (gnorm*gnorm); } else { delta = 2.0 / (gnorm*gnorm); } ierr = MatLMVMSetDelta(lmP->M, delta);CHKERRQ(ierr); ierr = MatLMVMReset(lmP->M);CHKERRQ(ierr); ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(lmP->M, lmP->GV, lmP->D);CHKERRQ(ierr); ierr = ProjDirect_OWLQN(lmP->D,lmP->GV);CHKERRQ(ierr); lmP->bfgs = 1; ++lmP->sgrad; stepType = OWLQN_SCALED_GRADIENT; break; case OWLQN_SCALED_GRADIENT: /* The scaled gradient step did not produce a new iterate; attempt to use the gradient direction. Need to make sure we are not using a different diagonal scaling */ ierr = MatLMVMSetDelta(lmP->M, 1.0);CHKERRQ(ierr); ierr = MatLMVMReset(lmP->M);CHKERRQ(ierr); ierr = MatLMVMUpdate(lmP->M, tao->solution, tao->gradient);CHKERRQ(ierr); ierr = MatLMVMSolve(lmP->M, lmP->GV, lmP->D);CHKERRQ(ierr); ierr = ProjDirect_OWLQN(lmP->D,lmP->GV);CHKERRQ(ierr); lmP->bfgs = 1; ++lmP->grad; stepType = OWLQN_GRADIENT; break; } ierr = VecScale(lmP->D, -1.0);CHKERRQ(ierr); /* Perform the linesearch */ ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, lmP->GV, lmP->D, &step, &ls_status);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); } if ((int)ls_status < 0) { /* Failed to find an improving point*/ f = fold; ierr = VecCopy(lmP->Xold, tao->solution);CHKERRQ(ierr); ierr = VecCopy(lmP->Gold, tao->gradient);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, lmP->GV);CHKERRQ(ierr); step = 0.0; } else { /* a little hack here, because that gv is used to store g */ ierr = VecCopy(lmP->GV, tao->gradient);CHKERRQ(ierr); } ierr = ComputePseudoGrad_OWLQN(tao->solution,lmP->GV,lmP->lambda);CHKERRQ(ierr); /* Check for termination */ ierr = VecNorm(lmP->GV,NORM_2,&gnorm);CHKERRQ(ierr); iter++; ierr = TaoMonitor(tao,iter,f,gnorm,0.0,step,&reason);CHKERRQ(ierr); if ((int)ls_status < 0) break; } PetscFunctionReturn(0); }
static PetscErrorCode TaoSolve_SQPCON(Tao tao) { TAO_SQPCON *sqpconP = (TAO_SQPCON*)tao->data; PetscInt iter=0; TaoConvergedReason reason = TAO_CONTINUE_ITERATING; TaoLineSearchConvergedReason ls_reason = TAOLINESEARCH_CONTINUE_ITERATING; PetscReal step=1.0,f,fm, fold; PetscReal cnorm, mnorm; PetscBool use_update=PETSC_TRUE; /* don't update Q if line search failed */ PetscErrorCode ierr; PetscFunctionBegin; /* Scatter to U,V */ ierr = VecScatterBegin(sqpconP->state_scatter, tao->solution, sqpconP->U, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->state_scatter, tao->solution, sqpconP->U, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(sqpconP->design_scatter, tao->solution, sqpconP->V, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->design_scatter, tao->solution, sqpconP->V, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); /* Evaluate Function, Gradient, Constraints, and Jacobian */ ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); ierr = TaoComputeConstraints(tao,tao->solution, tao->constraints);CHKERRQ(ierr); ierr = TaoComputeJacobianState(tao,tao->solution, &tao->jacobian_state, &tao->jacobian_state_pre, &tao->jacobian_state_inv, &sqpconP->statematflag);CHKERRQ(ierr); ierr = TaoComputeJacobianDesign(tao,tao->solution, &tao->jacobian_design, &tao->jacobian_design_pre, &sqpconP->statematflag);CHKERRQ(ierr); /* Scatter gradient to GU,GV */ ierr = VecScatterBegin(sqpconP->state_scatter, tao->gradient, sqpconP->GU, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->state_scatter, tao->gradient, sqpconP->GU, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(sqpconP->design_scatter, tao->gradient, sqpconP->GV, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->design_scatter, tao->gradient, sqpconP->GV, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecNorm(tao->gradient, NORM_2, &mnorm);CHKERRQ(ierr); /* Evaluate constraint norm */ ierr = VecNorm(tao->constraints, NORM_2, &cnorm);CHKERRQ(ierr); /* Monitor convergence */ ierr = TaoMonitor(tao, iter,f,mnorm,cnorm,step,&reason);CHKERRQ(ierr); while (reason == TAO_CONTINUE_ITERATING) { /* Solve tbar = -A\t (t is constraints vector) */ ierr = MatMult(tao->jacobian_state_inv, tao->constraints, sqpconP->Tbar);CHKERRQ(ierr); ierr = VecScale(sqpconP->Tbar, -1.0);CHKERRQ(ierr); /* aqwac = A'\(Q*Tbar + c) */ if (iter > 0) { ierr = MatMult(sqpconP->Q,sqpconP->Tbar,sqpconP->WV);CHKERRQ(ierr); } else { ierr = VecCopy(sqpconP->Tbar, sqpconP->WV);CHKERRQ(ierr); } ierr = VecAXPY(sqpconP->WV,1.0,sqpconP->GU);CHKERRQ(ierr); ierr = MatMultTranspose(tao->jacobian_state_inv, sqpconP->WV, sqpconP->aqwac);CHKERRQ(ierr); /* Reduced Gradient dbar = d - B^t * aqwac */ ierr = MatMultTranspose(tao->jacobian_design,sqpconP->aqwac, sqpconP->dbar);CHKERRQ(ierr); ierr = VecScale(sqpconP->dbar, -1.0);CHKERRQ(ierr); ierr = VecAXPY(sqpconP->dbar,1.0,sqpconP->GV);CHKERRQ(ierr); /* update reduced hessian */ ierr = MatLMVMUpdate(sqpconP->R, sqpconP->V, sqpconP->dbar);CHKERRQ(ierr); /* Solve R*dv = -dbar using approx. hessian */ ierr = MatLMVMSolve(sqpconP->R, sqpconP->dbar, sqpconP->DV);CHKERRQ(ierr); ierr = VecScale(sqpconP->DV, -1.0);CHKERRQ(ierr); /* Backsolve for u = A\(g - B*dv) = tbar - A\(B*dv)*/ ierr = MatMult(tao->jacobian_design, sqpconP->DV, sqpconP->WL);CHKERRQ(ierr); ierr = MatMult(tao->jacobian_state_inv, sqpconP->WL, sqpconP->DU);CHKERRQ(ierr); ierr = VecScale(sqpconP->DU, -1.0);CHKERRQ(ierr); ierr = VecAXPY(sqpconP->DU, 1.0, sqpconP->Tbar);CHKERRQ(ierr); /* Assemble Big D */ ierr = VecScatterBegin(sqpconP->state_scatter, sqpconP->DU, tao->stepdirection, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->state_scatter, sqpconP->DU, tao->stepdirection, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterBegin(sqpconP->design_scatter, sqpconP->DV, tao->stepdirection, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->design_scatter, sqpconP->DV, tao->stepdirection, INSERT_VALUES, SCATTER_REVERSE);CHKERRQ(ierr); /* Perform Line Search */ ierr = VecCopy(tao->solution, sqpconP->Xold);CHKERRQ(ierr); ierr = VecCopy(tao->gradient, sqpconP->Gold);CHKERRQ(ierr); fold = f; ierr = TaoLineSearchComputeObjectiveAndGradient(tao->linesearch,tao->solution,&fm,sqpconP->GL);CHKERRQ(ierr); ierr = TaoLineSearchSetInitialStepLength(tao->linesearch,1.0); ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &fm, sqpconP->GL, tao->stepdirection,&step, &ls_reason);CHKERRQ(ierr); ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); if (ls_reason < 0) { ierr = VecCopy(sqpconP->Xold, tao->solution); ierr = VecCopy(sqpconP->Gold, tao->gradient); f = fold; ierr = VecAXPY(tao->solution, 1.0, tao->stepdirection);CHKERRQ(ierr); ierr = PetscInfo(tao,"Line Search Failed, using full step.");CHKERRQ(ierr); use_update=PETSC_FALSE; } else { use_update = PETSC_TRUE; } /* Scatter X to U,V */ ierr = VecScatterBegin(sqpconP->state_scatter, tao->solution, sqpconP->U, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->state_scatter, tao->solution, sqpconP->U, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(sqpconP->design_scatter, tao->solution, sqpconP->V, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->design_scatter, tao->solution, sqpconP->V, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); /* Evaluate Function, Gradient, Constraints, and Jacobian */ ierr = TaoComputeObjectiveAndGradient(tao,tao->solution,&f,tao->gradient);CHKERRQ(ierr); ierr = TaoComputeConstraints(tao,tao->solution, tao->constraints);CHKERRQ(ierr); ierr = TaoComputeJacobianState(tao,tao->solution, &tao->jacobian_state, &tao->jacobian_state_pre, &tao->jacobian_state_inv, &sqpconP->statematflag);CHKERRQ(ierr); ierr = TaoComputeJacobianDesign(tao,tao->solution, &tao->jacobian_design, &tao->jacobian_design_pre, &sqpconP->designmatflag);CHKERRQ(ierr); /* Scatter gradient to GU,GV */ ierr = VecScatterBegin(sqpconP->state_scatter, tao->gradient, sqpconP->GU, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->state_scatter, tao->gradient, sqpconP->GU, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterBegin(sqpconP->design_scatter, tao->gradient, sqpconP->GV, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); ierr = VecScatterEnd(sqpconP->design_scatter, tao->gradient, sqpconP->GV, INSERT_VALUES, SCATTER_FORWARD);CHKERRQ(ierr); /* Update approx to hessian of the Lagrangian wrt state (Q) with u_k+1, gu_k+1 */ if (use_update) { ierr = MatApproxUpdate(sqpconP->Q,sqpconP->U,sqpconP->GU);CHKERRQ(ierr); } ierr = VecNorm(sqpconP->GL, NORM_2, &mnorm);CHKERRQ(ierr); /* Evaluate constraint norm */ ierr = VecNorm(tao->constraints, NORM_2, &cnorm);CHKERRQ(ierr); /* Monitor convergence */ iter++; ierr = TaoMonitor(tao, iter,f,mnorm,cnorm,step,&reason);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_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); }