1ba92ff59SBarry Smith #include <petsctaolinesearch.h> 21daac38eSTodd Munson #include <../src/tao/unconstrained/impls/nls/nlsimpl.h> 3a7e14dcfSSatish Balay 4aaa7dc30SBarry Smith #include <petscksp.h> 5a7e14dcfSSatish Balay 6a7e14dcfSSatish Balay #define NLS_INIT_CONSTANT 0 7a7e14dcfSSatish Balay #define NLS_INIT_DIRECTION 1 8a7e14dcfSSatish Balay #define NLS_INIT_INTERPOLATION 2 9a7e14dcfSSatish Balay #define NLS_INIT_TYPES 3 10a7e14dcfSSatish Balay 11a7e14dcfSSatish Balay #define NLS_UPDATE_STEP 0 12a7e14dcfSSatish Balay #define NLS_UPDATE_REDUCTION 1 13a7e14dcfSSatish Balay #define NLS_UPDATE_INTERPOLATION 2 14a7e14dcfSSatish Balay #define NLS_UPDATE_TYPES 3 15a7e14dcfSSatish Balay 1687f595a5SBarry Smith static const char *NLS_INIT[64] = {"constant", "direction", "interpolation"}; 17a7e14dcfSSatish Balay 1887f595a5SBarry Smith static const char *NLS_UPDATE[64] = {"step", "reduction", "interpolation"}; 19a7e14dcfSSatish Balay 201daac38eSTodd Munson /* 21a7e14dcfSSatish Balay Implements Newton's Method with a line search approach for solving 22a7e14dcfSSatish Balay unconstrained minimization problems. A More'-Thuente line search 23a7e14dcfSSatish Balay is used to guarantee that the bfgs preconditioner remains positive 24a7e14dcfSSatish Balay definite. 25a7e14dcfSSatish Balay 26a7e14dcfSSatish Balay The method can shift the Hessian matrix. The shifting procedure is 27a7e14dcfSSatish Balay adapted from the PATH algorithm for solving complementarity 28a7e14dcfSSatish Balay problems. 29a7e14dcfSSatish Balay 30a7e14dcfSSatish Balay The linear system solve should be done with a conjugate gradient 311daac38eSTodd Munson method, although any method can be used. 321daac38eSTodd Munson */ 33a7e14dcfSSatish Balay 34a7e14dcfSSatish Balay #define NLS_NEWTON 0 35a7e14dcfSSatish Balay #define NLS_BFGS 1 36*0c51296cSAlp Dener #define NLS_GRADIENT 2 37a7e14dcfSSatish Balay 38441846f8SBarry Smith static PetscErrorCode TaoSolve_NLS(Tao tao) 39a7e14dcfSSatish Balay { 40a7e14dcfSSatish Balay PetscErrorCode ierr; 41a7e14dcfSSatish Balay TAO_NLS *nlsP = (TAO_NLS *)tao->data; 421daac38eSTodd Munson KSPType ksp_type; 43*0c51296cSAlp Dener PetscBool is_nash,is_stcg,is_gltr,is_bfgs,is_jacobi; 44a7e14dcfSSatish Balay KSPConvergedReason ksp_reason; 451daac38eSTodd Munson PC pc; 461daac38eSTodd Munson TaoLineSearchConvergedReason ls_reason; 47a7e14dcfSSatish Balay 48a7e14dcfSSatish Balay PetscReal fmin, ftrial, f_full, prered, actred, kappa, sigma; 49a7e14dcfSSatish Balay PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 50a7e14dcfSSatish Balay PetscReal f, fold, gdx, gnorm, pert; 51a7e14dcfSSatish Balay PetscReal step = 1.0; 52a7e14dcfSSatish Balay PetscReal norm_d = 0.0, e_min; 53a7e14dcfSSatish Balay 54a7e14dcfSSatish Balay PetscInt stepType; 55a7e14dcfSSatish Balay PetscInt bfgsUpdates = 0; 56a7e14dcfSSatish Balay PetscInt n,N,kspits; 57b4690188SBarry Smith PetscInt needH = 1; 58a7e14dcfSSatish Balay 59a7e14dcfSSatish Balay PetscInt i_max = 5; 60a7e14dcfSSatish Balay PetscInt j_max = 1; 61a7e14dcfSSatish Balay PetscInt i, j; 62a7e14dcfSSatish Balay 63a7e14dcfSSatish Balay PetscFunctionBegin; 64a7e14dcfSSatish Balay if (tao->XL || tao->XU || tao->ops->computebounds) { 65a7e14dcfSSatish Balay ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by nls algorithm\n");CHKERRQ(ierr); 66a7e14dcfSSatish Balay } 67a7e14dcfSSatish Balay 68a7e14dcfSSatish Balay /* Initialized variables */ 69a7e14dcfSSatish Balay pert = nlsP->sval; 70a7e14dcfSSatish Balay 712d9aa51bSJason Sarich /* Number of times ksp stopped because of these reasons */ 72a7e14dcfSSatish Balay nlsP->ksp_atol = 0; 73a7e14dcfSSatish Balay nlsP->ksp_rtol = 0; 74a7e14dcfSSatish Balay nlsP->ksp_dtol = 0; 75a7e14dcfSSatish Balay nlsP->ksp_ctol = 0; 76a7e14dcfSSatish Balay nlsP->ksp_negc = 0; 77a7e14dcfSSatish Balay nlsP->ksp_iter = 0; 78a7e14dcfSSatish Balay nlsP->ksp_othr = 0; 79a7e14dcfSSatish Balay 80a7e14dcfSSatish Balay /* Initialize trust-region radius when using nash, stcg, or gltr 81ba7fe8fbSTodd Munson Command automatically ignored for other methods 82ba7fe8fbSTodd Munson Will be reset during the first iteration 83ba7fe8fbSTodd Munson */ 841daac38eSTodd Munson ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 851daac38eSTodd Munson ierr = PetscStrcmp(ksp_type,KSPCGNASH,&is_nash);CHKERRQ(ierr); 861daac38eSTodd Munson ierr = PetscStrcmp(ksp_type,KSPCGSTCG,&is_stcg);CHKERRQ(ierr); 871daac38eSTodd Munson ierr = PetscStrcmp(ksp_type,KSPCGGLTR,&is_gltr);CHKERRQ(ierr); 881daac38eSTodd Munson 89ba7fe8fbSTodd Munson ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr); 90a7e14dcfSSatish Balay 911daac38eSTodd Munson if (is_nash || is_stcg || is_gltr) { 921daac38eSTodd Munson if (tao->trust0 < 0.0) SETERRQ(PETSC_COMM_SELF,1,"Initial radius negative"); 93a7e14dcfSSatish Balay tao->trust = tao->trust0; 94a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->min_radius); 95a7e14dcfSSatish Balay tao->trust = PetscMin(tao->trust, nlsP->max_radius); 96a7e14dcfSSatish Balay } 97a7e14dcfSSatish Balay 98a7e14dcfSSatish Balay /* Check convergence criteria */ 99a7e14dcfSSatish Balay ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr); 100a9603a14SPatrick Farrell ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 10187f595a5SBarry Smith if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 102a7e14dcfSSatish Balay 1033ecd9318SAlp Dener tao->reason = TAO_CONTINUE_ITERATING; 1043ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 1053ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 1063ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 1073ecd9318SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 108a7e14dcfSSatish Balay 109*0c51296cSAlp Dener /* Allocate the vectors needed for the BFGS approximation */ 110a7e14dcfSSatish Balay ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 111*0c51296cSAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr); 112*0c51296cSAlp Dener ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr); 113*0c51296cSAlp Dener if (is_bfgs) { 114*0c51296cSAlp Dener nlsP->bfgs_pre = pc; 115*0c51296cSAlp Dener ierr = PCLMVMGetMatLMVM(nlsP->bfgs_pre, &nlsP->M);CHKERRQ(ierr); 116*0c51296cSAlp Dener ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr); 117*0c51296cSAlp Dener ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr); 118*0c51296cSAlp Dener ierr = MatSetSizes(nlsP->M, n, n, N, N);CHKERRQ(ierr); 119*0c51296cSAlp Dener ierr = MatLMVMAllocate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 120*0c51296cSAlp Dener } else if (is_jacobi) { 121baa89ecbSBarry Smith ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 122a7e14dcfSSatish Balay } 123a7e14dcfSSatish Balay 124a7e14dcfSSatish Balay /* Initialize trust-region radius. The initialization is only performed 125a7e14dcfSSatish Balay when we are using Nash, Steihaug-Toint or the Generalized Lanczos method. */ 1261daac38eSTodd Munson if (is_nash || is_stcg || is_gltr) { 127a7e14dcfSSatish Balay switch(nlsP->init_type) { 128a7e14dcfSSatish Balay case NLS_INIT_CONSTANT: 129a7e14dcfSSatish Balay /* Use the initial radius specified */ 130a7e14dcfSSatish Balay break; 131a7e14dcfSSatish Balay 132a7e14dcfSSatish Balay case NLS_INIT_INTERPOLATION: 133a7e14dcfSSatish Balay /* Use the initial radius specified */ 134a7e14dcfSSatish Balay max_radius = 0.0; 135a7e14dcfSSatish Balay 136a7e14dcfSSatish Balay for (j = 0; j < j_max; ++j) { 137a7e14dcfSSatish Balay fmin = f; 138a7e14dcfSSatish Balay sigma = 0.0; 139a7e14dcfSSatish Balay 140a7e14dcfSSatish Balay if (needH) { 141ffad9901SBarry Smith ierr = TaoComputeHessian(tao, tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 142a7e14dcfSSatish Balay needH = 0; 143a7e14dcfSSatish Balay } 144a7e14dcfSSatish Balay 145a7e14dcfSSatish Balay for (i = 0; i < i_max; ++i) { 146a7e14dcfSSatish Balay ierr = VecCopy(tao->solution,nlsP->W);CHKERRQ(ierr); 147a7e14dcfSSatish Balay ierr = VecAXPY(nlsP->W,-tao->trust/gnorm,tao->gradient);CHKERRQ(ierr); 148a7e14dcfSSatish Balay ierr = TaoComputeObjective(tao, nlsP->W, &ftrial);CHKERRQ(ierr); 149a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(ftrial)) { 150a7e14dcfSSatish Balay tau = nlsP->gamma1_i; 15187f595a5SBarry Smith } else { 152a7e14dcfSSatish Balay if (ftrial < fmin) { 153a7e14dcfSSatish Balay fmin = ftrial; 154a7e14dcfSSatish Balay sigma = -tao->trust / gnorm; 155a7e14dcfSSatish Balay } 156a7e14dcfSSatish Balay 157a7e14dcfSSatish Balay ierr = MatMult(tao->hessian, tao->gradient, nlsP->D);CHKERRQ(ierr); 158a7e14dcfSSatish Balay ierr = VecDot(tao->gradient, nlsP->D, &prered);CHKERRQ(ierr); 159a7e14dcfSSatish Balay 160a7e14dcfSSatish Balay prered = tao->trust * (gnorm - 0.5 * tao->trust * prered / (gnorm * gnorm)); 161a7e14dcfSSatish Balay actred = f - ftrial; 16287f595a5SBarry Smith if ((PetscAbsScalar(actred) <= nlsP->epsilon) && (PetscAbsScalar(prered) <= nlsP->epsilon)) { 163a7e14dcfSSatish Balay kappa = 1.0; 16487f595a5SBarry Smith } else { 165a7e14dcfSSatish Balay kappa = actred / prered; 166a7e14dcfSSatish Balay } 167a7e14dcfSSatish Balay 168a7e14dcfSSatish Balay tau_1 = nlsP->theta_i * gnorm * tao->trust / (nlsP->theta_i * gnorm * tao->trust + (1.0 - nlsP->theta_i) * prered - actred); 169a7e14dcfSSatish Balay tau_2 = nlsP->theta_i * gnorm * tao->trust / (nlsP->theta_i * gnorm * tao->trust - (1.0 + nlsP->theta_i) * prered + actred); 170a7e14dcfSSatish Balay tau_min = PetscMin(tau_1, tau_2); 171a7e14dcfSSatish Balay tau_max = PetscMax(tau_1, tau_2); 172a7e14dcfSSatish Balay 173a7e14dcfSSatish Balay if (PetscAbsScalar(kappa - 1.0) <= nlsP->mu1_i) { 174a7e14dcfSSatish Balay /* Great agreement */ 175a7e14dcfSSatish Balay max_radius = PetscMax(max_radius, tao->trust); 176a7e14dcfSSatish Balay 177a7e14dcfSSatish Balay if (tau_max < 1.0) { 178a7e14dcfSSatish Balay tau = nlsP->gamma3_i; 17987f595a5SBarry Smith } else if (tau_max > nlsP->gamma4_i) { 180a7e14dcfSSatish Balay tau = nlsP->gamma4_i; 18187f595a5SBarry Smith } else if (tau_1 >= 1.0 && tau_1 <= nlsP->gamma4_i && tau_2 < 1.0) { 182a7e14dcfSSatish Balay tau = tau_1; 18387f595a5SBarry Smith } else if (tau_2 >= 1.0 && tau_2 <= nlsP->gamma4_i && tau_1 < 1.0) { 184a7e14dcfSSatish Balay tau = tau_2; 18587f595a5SBarry Smith } else { 186a7e14dcfSSatish Balay tau = tau_max; 187a7e14dcfSSatish Balay } 18887f595a5SBarry Smith } else if (PetscAbsScalar(kappa - 1.0) <= nlsP->mu2_i) { 189a7e14dcfSSatish Balay /* Good agreement */ 190a7e14dcfSSatish Balay max_radius = PetscMax(max_radius, tao->trust); 191a7e14dcfSSatish Balay 192a7e14dcfSSatish Balay if (tau_max < nlsP->gamma2_i) { 193a7e14dcfSSatish Balay tau = nlsP->gamma2_i; 19487f595a5SBarry Smith } else if (tau_max > nlsP->gamma3_i) { 195a7e14dcfSSatish Balay tau = nlsP->gamma3_i; 19687f595a5SBarry Smith } else { 197a7e14dcfSSatish Balay tau = tau_max; 198a7e14dcfSSatish Balay } 19987f595a5SBarry Smith } else { 200a7e14dcfSSatish Balay /* Not good agreement */ 201a7e14dcfSSatish Balay if (tau_min > 1.0) { 202a7e14dcfSSatish Balay tau = nlsP->gamma2_i; 20387f595a5SBarry Smith } else if (tau_max < nlsP->gamma1_i) { 204a7e14dcfSSatish Balay tau = nlsP->gamma1_i; 20587f595a5SBarry Smith } else if ((tau_min < nlsP->gamma1_i) && (tau_max >= 1.0)) { 206a7e14dcfSSatish Balay tau = nlsP->gamma1_i; 20787f595a5SBarry Smith } else if ((tau_1 >= nlsP->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < nlsP->gamma1_i) || (tau_2 >= 1.0))) { 208a7e14dcfSSatish Balay tau = tau_1; 20987f595a5SBarry Smith } else if ((tau_2 >= nlsP->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < nlsP->gamma1_i) || (tau_2 >= 1.0))) { 210a7e14dcfSSatish Balay tau = tau_2; 21187f595a5SBarry Smith } else { 212a7e14dcfSSatish Balay tau = tau_max; 213a7e14dcfSSatish Balay } 214a7e14dcfSSatish Balay } 215a7e14dcfSSatish Balay } 216a7e14dcfSSatish Balay tao->trust = tau * tao->trust; 217a7e14dcfSSatish Balay } 218a7e14dcfSSatish Balay 219a7e14dcfSSatish Balay if (fmin < f) { 220a7e14dcfSSatish Balay f = fmin; 221a7e14dcfSSatish Balay ierr = VecAXPY(tao->solution,sigma,tao->gradient);CHKERRQ(ierr); 222a7e14dcfSSatish Balay ierr = TaoComputeGradient(tao,tao->solution,tao->gradient);CHKERRQ(ierr); 223a7e14dcfSSatish Balay 224a9603a14SPatrick Farrell ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 22587f595a5SBarry Smith if (PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute gradient generated Inf or NaN"); 226a7e14dcfSSatish Balay needH = 1; 227a7e14dcfSSatish Balay 2283ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 2293ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 2303ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 2313ecd9318SAlp Dener if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 232a7e14dcfSSatish Balay } 233a7e14dcfSSatish Balay } 234a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, max_radius); 235a7e14dcfSSatish Balay 236a7e14dcfSSatish Balay /* Modify the radius if it is too large or small */ 237a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->min_radius); 238a7e14dcfSSatish Balay tao->trust = PetscMin(tao->trust, nlsP->max_radius); 239a7e14dcfSSatish Balay break; 240a7e14dcfSSatish Balay 241a7e14dcfSSatish Balay default: 242a7e14dcfSSatish Balay /* Norm of the first direction will initialize radius */ 243a7e14dcfSSatish Balay tao->trust = 0.0; 244a7e14dcfSSatish Balay break; 245a7e14dcfSSatish Balay } 246a7e14dcfSSatish Balay } 247a7e14dcfSSatish Balay 248a7e14dcfSSatish Balay /* Set counter for gradient/reset steps*/ 249a7e14dcfSSatish Balay nlsP->newt = 0; 250a7e14dcfSSatish Balay nlsP->bfgs = 0; 251a7e14dcfSSatish Balay nlsP->grad = 0; 252a7e14dcfSSatish Balay 253a7e14dcfSSatish Balay /* Have not converged; continue with Newton method */ 2543ecd9318SAlp Dener while (tao->reason == TAO_CONTINUE_ITERATING) { 2558931d482SJason Sarich ++tao->niter; 256ae93cb3cSJason Sarich tao->ksp_its=0; 257a7e14dcfSSatish Balay 258a7e14dcfSSatish Balay /* Compute the Hessian */ 259a7e14dcfSSatish Balay if (needH) { 260ffad9901SBarry Smith ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 261a7e14dcfSSatish Balay } 262a7e14dcfSSatish Balay 263a7e14dcfSSatish Balay /* Shift the Hessian matrix */ 264a7e14dcfSSatish Balay if (pert > 0) { 265302440fdSBarry Smith ierr = MatShift(tao->hessian, pert);CHKERRQ(ierr); 266a7e14dcfSSatish Balay if (tao->hessian != tao->hessian_pre) { 267a7e14dcfSSatish Balay ierr = MatShift(tao->hessian_pre, pert);CHKERRQ(ierr); 268a7e14dcfSSatish Balay } 269a7e14dcfSSatish Balay } 270a7e14dcfSSatish Balay 271*0c51296cSAlp Dener if (nlsP->bfgs_pre) { 272a7e14dcfSSatish Balay ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 273a7e14dcfSSatish Balay ++bfgsUpdates; 274a7e14dcfSSatish Balay } 275a7e14dcfSSatish Balay 276a7e14dcfSSatish Balay /* Solve the Newton system of equations */ 27723ee1639SBarry Smith ierr = KSPSetOperators(tao->ksp,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 2781daac38eSTodd Munson if (is_nash || is_stcg || is_gltr) { 279ba7fe8fbSTodd Munson ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr); 280a7e14dcfSSatish Balay ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr); 281a7e14dcfSSatish Balay ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 282a7e14dcfSSatish Balay tao->ksp_its+=kspits; 283ae93cb3cSJason Sarich tao->ksp_tot_its+=kspits; 284ba7fe8fbSTodd Munson ierr = KSPCGGetNormD(tao->ksp,&norm_d);CHKERRQ(ierr); 285a7e14dcfSSatish Balay 286a7e14dcfSSatish Balay if (0.0 == tao->trust) { 287a7e14dcfSSatish Balay /* Radius was uninitialized; use the norm of the direction */ 288a7e14dcfSSatish Balay if (norm_d > 0.0) { 289a7e14dcfSSatish Balay tao->trust = norm_d; 290a7e14dcfSSatish Balay 291a7e14dcfSSatish Balay /* Modify the radius if it is too large or small */ 292a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->min_radius); 293a7e14dcfSSatish Balay tao->trust = PetscMin(tao->trust, nlsP->max_radius); 29487f595a5SBarry Smith } else { 295a7e14dcfSSatish Balay /* The direction was bad; set radius to default value and re-solve 296a7e14dcfSSatish Balay the trust-region subproblem to get a direction */ 297a7e14dcfSSatish Balay tao->trust = tao->trust0; 298a7e14dcfSSatish Balay 299a7e14dcfSSatish Balay /* Modify the radius if it is too large or small */ 300a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->min_radius); 301a7e14dcfSSatish Balay tao->trust = PetscMin(tao->trust, nlsP->max_radius); 302a7e14dcfSSatish Balay 303ba7fe8fbSTodd Munson ierr = KSPCGSetRadius(tao->ksp,nlsP->max_radius);CHKERRQ(ierr); 304a7e14dcfSSatish Balay ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr); 305a7e14dcfSSatish Balay ierr = KSPGetIterationNumber(tao->ksp,&kspits);CHKERRQ(ierr); 306a7e14dcfSSatish Balay tao->ksp_its+=kspits; 307ae93cb3cSJason Sarich tao->ksp_tot_its+=kspits; 308ba7fe8fbSTodd Munson ierr = KSPCGGetNormD(tao->ksp,&norm_d);CHKERRQ(ierr); 309a7e14dcfSSatish Balay 31087f595a5SBarry Smith if (norm_d == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 311a7e14dcfSSatish Balay } 312a7e14dcfSSatish Balay } 31387f595a5SBarry Smith } else { 314a7e14dcfSSatish Balay ierr = KSPSolve(tao->ksp, tao->gradient, nlsP->D);CHKERRQ(ierr); 315a7e14dcfSSatish Balay ierr = KSPGetIterationNumber(tao->ksp, &kspits);CHKERRQ(ierr); 316a7e14dcfSSatish Balay tao->ksp_its += kspits; 317ae93cb3cSJason Sarich tao->ksp_tot_its+=kspits; 318a7e14dcfSSatish Balay } 319a7e14dcfSSatish Balay ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr); 320a7e14dcfSSatish Balay ierr = KSPGetConvergedReason(tao->ksp, &ksp_reason);CHKERRQ(ierr); 321*0c51296cSAlp Dener if ((KSP_DIVERGED_INDEFINITE_PC == ksp_reason) && (nlsP->bfgs_pre)) { 322a7e14dcfSSatish Balay /* Preconditioner is numerically indefinite; reset the 323a7e14dcfSSatish Balay approximate if using BFGS preconditioning. */ 324cd929ea3SAlp Dener ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr); 325a7e14dcfSSatish Balay ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 326a7e14dcfSSatish Balay bfgsUpdates = 1; 327a7e14dcfSSatish Balay } 328a7e14dcfSSatish Balay 329a7e14dcfSSatish Balay if (KSP_CONVERGED_ATOL == ksp_reason) { 330a7e14dcfSSatish Balay ++nlsP->ksp_atol; 33187f595a5SBarry Smith } else if (KSP_CONVERGED_RTOL == ksp_reason) { 332a7e14dcfSSatish Balay ++nlsP->ksp_rtol; 33387f595a5SBarry Smith } else if (KSP_CONVERGED_CG_CONSTRAINED == ksp_reason) { 334a7e14dcfSSatish Balay ++nlsP->ksp_ctol; 33587f595a5SBarry Smith } else if (KSP_CONVERGED_CG_NEG_CURVE == ksp_reason) { 336a7e14dcfSSatish Balay ++nlsP->ksp_negc; 33787f595a5SBarry Smith } else if (KSP_DIVERGED_DTOL == ksp_reason) { 338a7e14dcfSSatish Balay ++nlsP->ksp_dtol; 33987f595a5SBarry Smith } else if (KSP_DIVERGED_ITS == ksp_reason) { 340a7e14dcfSSatish Balay ++nlsP->ksp_iter; 34187f595a5SBarry Smith } else { 342a7e14dcfSSatish Balay ++nlsP->ksp_othr; 343a7e14dcfSSatish Balay } 344a7e14dcfSSatish Balay 345a7e14dcfSSatish Balay /* Check for success (descent direction) */ 346a7e14dcfSSatish Balay ierr = VecDot(nlsP->D, tao->gradient, &gdx);CHKERRQ(ierr); 347a7e14dcfSSatish Balay if ((gdx >= 0.0) || PetscIsInfOrNanReal(gdx)) { 348a7e14dcfSSatish Balay /* Newton step is not descent or direction produced Inf or NaN 349a7e14dcfSSatish Balay Update the perturbation for next time */ 350a7e14dcfSSatish Balay if (pert <= 0.0) { 351a7e14dcfSSatish Balay /* Initialize the perturbation */ 352a7e14dcfSSatish Balay pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm)); 3531daac38eSTodd Munson if (is_gltr) { 354ba7fe8fbSTodd Munson ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 355a7e14dcfSSatish Balay pert = PetscMax(pert, -e_min); 356a7e14dcfSSatish Balay } 35787f595a5SBarry Smith } else { 358a7e14dcfSSatish Balay /* Increase the perturbation */ 359a7e14dcfSSatish Balay pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm)); 360a7e14dcfSSatish Balay } 361a7e14dcfSSatish Balay 362*0c51296cSAlp Dener if (!nlsP->bfgs_pre) { 363a7e14dcfSSatish Balay /* We don't have the bfgs matrix around and updated 364a7e14dcfSSatish Balay Must use gradient direction in this case */ 365a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, nlsP->D);CHKERRQ(ierr); 366a7e14dcfSSatish Balay ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr); 367a7e14dcfSSatish Balay ++nlsP->grad; 368a7e14dcfSSatish Balay stepType = NLS_GRADIENT; 36987f595a5SBarry Smith } else { 370a7e14dcfSSatish Balay /* Attempt to use the BFGS direction */ 371cd929ea3SAlp Dener ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr); 372a7e14dcfSSatish Balay ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr); 373a7e14dcfSSatish Balay 374a7e14dcfSSatish Balay /* Check for success (descent direction) */ 375a7e14dcfSSatish Balay ierr = VecDot(tao->gradient, nlsP->D, &gdx);CHKERRQ(ierr); 376a7e14dcfSSatish Balay if ((gdx >= 0) || PetscIsInfOrNanReal(gdx)) { 377a7e14dcfSSatish Balay /* BFGS direction is not descent or direction produced not a number 378a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case because 379a7e14dcfSSatish Balay the first solve produces the scaled gradient direction, 380a7e14dcfSSatish Balay which is guaranteed to be descent */ 381a7e14dcfSSatish Balay 382a7e14dcfSSatish Balay /* Use steepest descent direction (scaled) */ 383cd929ea3SAlp Dener ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr); 384a7e14dcfSSatish Balay ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 385cd929ea3SAlp Dener ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr); 386a7e14dcfSSatish Balay ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr); 387a7e14dcfSSatish Balay 388a7e14dcfSSatish Balay bfgsUpdates = 1; 389*0c51296cSAlp Dener ++nlsP->grad; 390*0c51296cSAlp Dener stepType = NLS_GRADIENT; 39187f595a5SBarry Smith } else { 392*0c51296cSAlp Dener ierr = MatLMVMGetUpdateCount(nlsP->M, &bfgsUpdates);CHKERRQ(ierr); 393a7e14dcfSSatish Balay if (1 == bfgsUpdates) { 394a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 395*0c51296cSAlp Dener ++nlsP->grad; 396*0c51296cSAlp Dener stepType = NLS_GRADIENT; 39787f595a5SBarry Smith } else { 398a7e14dcfSSatish Balay ++nlsP->bfgs; 399a7e14dcfSSatish Balay stepType = NLS_BFGS; 400a7e14dcfSSatish Balay } 401a7e14dcfSSatish Balay } 402a7e14dcfSSatish Balay } 40387f595a5SBarry Smith } else { 404a7e14dcfSSatish Balay /* Computed Newton step is descent */ 405a7e14dcfSSatish Balay switch (ksp_reason) { 406a7e14dcfSSatish Balay case KSP_DIVERGED_NANORINF: 407a7e14dcfSSatish Balay case KSP_DIVERGED_BREAKDOWN: 408a7e14dcfSSatish Balay case KSP_DIVERGED_INDEFINITE_MAT: 409a7e14dcfSSatish Balay case KSP_DIVERGED_INDEFINITE_PC: 410a7e14dcfSSatish Balay case KSP_CONVERGED_CG_NEG_CURVE: 411a7e14dcfSSatish Balay /* Matrix or preconditioner is indefinite; increase perturbation */ 412a7e14dcfSSatish Balay if (pert <= 0.0) { 413a7e14dcfSSatish Balay /* Initialize the perturbation */ 414a7e14dcfSSatish Balay pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm)); 4151daac38eSTodd Munson if (is_gltr) { 416ba7fe8fbSTodd Munson ierr = KSPCGGLTRGetMinEig(tao->ksp, &e_min);CHKERRQ(ierr); 417a7e14dcfSSatish Balay pert = PetscMax(pert, -e_min); 418a7e14dcfSSatish Balay } 41987f595a5SBarry Smith } else { 420a7e14dcfSSatish Balay /* Increase the perturbation */ 421a7e14dcfSSatish Balay pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm)); 422a7e14dcfSSatish Balay } 423a7e14dcfSSatish Balay break; 424a7e14dcfSSatish Balay 425a7e14dcfSSatish Balay default: 426a7e14dcfSSatish Balay /* Newton step computation is good; decrease perturbation */ 427a7e14dcfSSatish Balay pert = PetscMin(nlsP->psfac * pert, nlsP->pmsfac * gnorm); 428a7e14dcfSSatish Balay if (pert < nlsP->pmin) { 429a7e14dcfSSatish Balay pert = 0.0; 430a7e14dcfSSatish Balay } 431a7e14dcfSSatish Balay break; 432a7e14dcfSSatish Balay } 433a7e14dcfSSatish Balay 434a7e14dcfSSatish Balay ++nlsP->newt; 435a7e14dcfSSatish Balay stepType = NLS_NEWTON; 436a7e14dcfSSatish Balay } 437a7e14dcfSSatish Balay 438a7e14dcfSSatish Balay /* Perform the linesearch */ 439a7e14dcfSSatish Balay fold = f; 440a7e14dcfSSatish Balay ierr = VecCopy(tao->solution, nlsP->Xold);CHKERRQ(ierr); 441a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, nlsP->Gold);CHKERRQ(ierr); 442a7e14dcfSSatish Balay 443a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, nlsP->D, &step, &ls_reason);CHKERRQ(ierr); 444a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 445a7e14dcfSSatish Balay 44687f595a5SBarry Smith while (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER && stepType != NLS_GRADIENT) { /* Linesearch failed */ 447a7e14dcfSSatish Balay f = fold; 448a7e14dcfSSatish Balay ierr = VecCopy(nlsP->Xold, tao->solution);CHKERRQ(ierr); 449a7e14dcfSSatish Balay ierr = VecCopy(nlsP->Gold, tao->gradient);CHKERRQ(ierr); 450a7e14dcfSSatish Balay 451a7e14dcfSSatish Balay switch(stepType) { 452a7e14dcfSSatish Balay case NLS_NEWTON: 453a7e14dcfSSatish Balay /* Failed to obtain acceptable iterate with Newton 1step 454a7e14dcfSSatish Balay Update the perturbation for next time */ 455a7e14dcfSSatish Balay if (pert <= 0.0) { 456a7e14dcfSSatish Balay /* Initialize the perturbation */ 457a7e14dcfSSatish Balay pert = PetscMin(nlsP->imax, PetscMax(nlsP->imin, nlsP->imfac * gnorm)); 4581daac38eSTodd Munson if (is_gltr) { 459ba7fe8fbSTodd Munson ierr = KSPCGGLTRGetMinEig(tao->ksp,&e_min);CHKERRQ(ierr); 460a7e14dcfSSatish Balay pert = PetscMax(pert, -e_min); 461a7e14dcfSSatish Balay } 46287f595a5SBarry Smith } else { 463a7e14dcfSSatish Balay /* Increase the perturbation */ 464a7e14dcfSSatish Balay pert = PetscMin(nlsP->pmax, PetscMax(nlsP->pgfac * pert, nlsP->pmgfac * gnorm)); 465a7e14dcfSSatish Balay } 466a7e14dcfSSatish Balay 467*0c51296cSAlp Dener if (!nlsP->bfgs_pre) { 468a7e14dcfSSatish Balay /* We don't have the bfgs matrix around and being updated 469a7e14dcfSSatish Balay Must use gradient direction in this case */ 470a7e14dcfSSatish Balay ierr = VecCopy(tao->gradient, nlsP->D);CHKERRQ(ierr); 471a7e14dcfSSatish Balay ++nlsP->grad; 472a7e14dcfSSatish Balay stepType = NLS_GRADIENT; 47387f595a5SBarry Smith } else { 474a7e14dcfSSatish Balay /* Attempt to use the BFGS direction */ 475cd929ea3SAlp Dener ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr); 476a7e14dcfSSatish Balay /* Check for success (descent direction) */ 477a7e14dcfSSatish Balay ierr = VecDot(tao->solution, nlsP->D, &gdx);CHKERRQ(ierr); 478a7e14dcfSSatish Balay if ((gdx <= 0) || PetscIsInfOrNanReal(gdx)) { 479a7e14dcfSSatish Balay /* BFGS direction is not descent or direction produced not a number 480a7e14dcfSSatish Balay We can assert bfgsUpdates > 1 in this case 481a7e14dcfSSatish Balay Use steepest descent direction (scaled) */ 482cd929ea3SAlp Dener ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr); 483a7e14dcfSSatish Balay ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 484cd929ea3SAlp Dener ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr); 485a7e14dcfSSatish Balay 486a7e14dcfSSatish Balay bfgsUpdates = 1; 487*0c51296cSAlp Dener ++nlsP->grad; 488*0c51296cSAlp Dener stepType = NLS_GRADIENT; 48987f595a5SBarry Smith } else { 490a7e14dcfSSatish Balay if (1 == bfgsUpdates) { 491a7e14dcfSSatish Balay /* The first BFGS direction is always the scaled gradient */ 492*0c51296cSAlp Dener ++nlsP->grad; 493*0c51296cSAlp Dener stepType = NLS_GRADIENT; 49487f595a5SBarry Smith } else { 495a7e14dcfSSatish Balay ++nlsP->bfgs; 496a7e14dcfSSatish Balay stepType = NLS_BFGS; 497a7e14dcfSSatish Balay } 498a7e14dcfSSatish Balay } 499a7e14dcfSSatish Balay } 500a7e14dcfSSatish Balay break; 501a7e14dcfSSatish Balay 502a7e14dcfSSatish Balay case NLS_BFGS: 503a7e14dcfSSatish Balay /* Can only enter if pc_type == NLS_PC_BFGS 504a7e14dcfSSatish Balay Failed to obtain acceptable iterate with BFGS step 505a7e14dcfSSatish Balay Attempt to use the scaled gradient direction */ 506cd929ea3SAlp Dener ierr = MatLMVMReset(nlsP->M, PETSC_FALSE);CHKERRQ(ierr); 507a7e14dcfSSatish Balay ierr = MatLMVMUpdate(nlsP->M, tao->solution, tao->gradient);CHKERRQ(ierr); 508cd929ea3SAlp Dener ierr = MatSolve(nlsP->M, tao->gradient, nlsP->D);CHKERRQ(ierr); 509a7e14dcfSSatish Balay 510a7e14dcfSSatish Balay bfgsUpdates = 1; 511a7e14dcfSSatish Balay ++nlsP->grad; 512a7e14dcfSSatish Balay stepType = NLS_GRADIENT; 513a7e14dcfSSatish Balay break; 514a7e14dcfSSatish Balay } 515a7e14dcfSSatish Balay ierr = VecScale(nlsP->D, -1.0);CHKERRQ(ierr); 516a7e14dcfSSatish Balay 517a7e14dcfSSatish Balay ierr = TaoLineSearchApply(tao->linesearch, tao->solution, &f, tao->gradient, nlsP->D, &step, &ls_reason);CHKERRQ(ierr); 518a7e14dcfSSatish Balay ierr = TaoLineSearchGetFullStepObjective(tao->linesearch, &f_full);CHKERRQ(ierr); 519a7e14dcfSSatish Balay ierr = TaoAddLineSearchCounts(tao);CHKERRQ(ierr); 520a7e14dcfSSatish Balay } 521a7e14dcfSSatish Balay 52287f595a5SBarry Smith if (ls_reason != TAOLINESEARCH_SUCCESS && ls_reason != TAOLINESEARCH_SUCCESS_USER) { 523a7e14dcfSSatish Balay /* Failed to find an improving point */ 524a7e14dcfSSatish Balay f = fold; 525a7e14dcfSSatish Balay ierr = VecCopy(nlsP->Xold, tao->solution);CHKERRQ(ierr); 526a7e14dcfSSatish Balay ierr = VecCopy(nlsP->Gold, tao->gradient);CHKERRQ(ierr); 527a7e14dcfSSatish Balay step = 0.0; 528a7e14dcfSSatish Balay tao->reason = TAO_DIVERGED_LS_FAILURE; 529a7e14dcfSSatish Balay break; 530a7e14dcfSSatish Balay } 531a7e14dcfSSatish Balay 532a7e14dcfSSatish Balay /* Update trust region radius */ 5331daac38eSTodd Munson if (is_nash || is_stcg || is_gltr) { 534a7e14dcfSSatish Balay switch(nlsP->update_type) { 535a7e14dcfSSatish Balay case NLS_UPDATE_STEP: 536a7e14dcfSSatish Balay if (stepType == NLS_NEWTON) { 537a7e14dcfSSatish Balay if (step < nlsP->nu1) { 538a7e14dcfSSatish Balay /* Very bad step taken; reduce radius */ 539a7e14dcfSSatish Balay tao->trust = nlsP->omega1 * PetscMin(norm_d, tao->trust); 54087f595a5SBarry Smith } else if (step < nlsP->nu2) { 541a7e14dcfSSatish Balay /* Reasonably bad step taken; reduce radius */ 542a7e14dcfSSatish Balay tao->trust = nlsP->omega2 * PetscMin(norm_d, tao->trust); 54387f595a5SBarry Smith } else if (step < nlsP->nu3) { 544a7e14dcfSSatish Balay /* Reasonable step was taken; leave radius alone */ 545a7e14dcfSSatish Balay if (nlsP->omega3 < 1.0) { 546a7e14dcfSSatish Balay tao->trust = nlsP->omega3 * PetscMin(norm_d, tao->trust); 54787f595a5SBarry Smith } else if (nlsP->omega3 > 1.0) { 548a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->omega3 * norm_d, tao->trust); 549a7e14dcfSSatish Balay } 55087f595a5SBarry Smith } else if (step < nlsP->nu4) { 551a7e14dcfSSatish Balay /* Full step taken; increase the radius */ 552a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->omega4 * norm_d, tao->trust); 55387f595a5SBarry Smith } else { 554a7e14dcfSSatish Balay /* More than full step taken; increase the radius */ 555a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->omega5 * norm_d, tao->trust); 556a7e14dcfSSatish Balay } 55787f595a5SBarry Smith } else { 558a7e14dcfSSatish Balay /* Newton step was not good; reduce the radius */ 559a7e14dcfSSatish Balay tao->trust = nlsP->omega1 * PetscMin(norm_d, tao->trust); 560a7e14dcfSSatish Balay } 561a7e14dcfSSatish Balay break; 562a7e14dcfSSatish Balay 563a7e14dcfSSatish Balay case NLS_UPDATE_REDUCTION: 564a7e14dcfSSatish Balay if (stepType == NLS_NEWTON) { 565a7e14dcfSSatish Balay /* Get predicted reduction */ 566a7e14dcfSSatish Balay 567ba7fe8fbSTodd Munson ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr); 568a7e14dcfSSatish Balay if (prered >= 0.0) { 569a7e14dcfSSatish Balay /* The predicted reduction has the wrong sign. This cannot */ 570a7e14dcfSSatish Balay /* happen in infinite precision arithmetic. Step should */ 571a7e14dcfSSatish Balay /* be rejected! */ 572a7e14dcfSSatish Balay tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d); 57387f595a5SBarry Smith } else { 574a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(f_full)) { 575a7e14dcfSSatish Balay tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d); 57687f595a5SBarry Smith } else { 577a7e14dcfSSatish Balay /* Compute and actual reduction */ 578a7e14dcfSSatish Balay actred = fold - f_full; 579a7e14dcfSSatish Balay prered = -prered; 580a7e14dcfSSatish Balay if ((PetscAbsScalar(actred) <= nlsP->epsilon) && 581a7e14dcfSSatish Balay (PetscAbsScalar(prered) <= nlsP->epsilon)) { 582a7e14dcfSSatish Balay kappa = 1.0; 58387f595a5SBarry Smith } else { 584a7e14dcfSSatish Balay kappa = actred / prered; 585a7e14dcfSSatish Balay } 586a7e14dcfSSatish Balay 587a7e14dcfSSatish Balay /* Accept of reject the step and update radius */ 588a7e14dcfSSatish Balay if (kappa < nlsP->eta1) { 589a7e14dcfSSatish Balay /* Very bad step */ 590a7e14dcfSSatish Balay tao->trust = nlsP->alpha1 * PetscMin(tao->trust, norm_d); 59187f595a5SBarry Smith } else if (kappa < nlsP->eta2) { 592a7e14dcfSSatish Balay /* Marginal bad step */ 593a7e14dcfSSatish Balay tao->trust = nlsP->alpha2 * PetscMin(tao->trust, norm_d); 59487f595a5SBarry Smith } else if (kappa < nlsP->eta3) { 595a7e14dcfSSatish Balay /* Reasonable step */ 596a7e14dcfSSatish Balay if (nlsP->alpha3 < 1.0) { 597a7e14dcfSSatish Balay tao->trust = nlsP->alpha3 * PetscMin(norm_d, tao->trust); 59887f595a5SBarry Smith } else if (nlsP->alpha3 > 1.0) { 599a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->alpha3 * norm_d, tao->trust); 600a7e14dcfSSatish Balay } 60187f595a5SBarry Smith } else if (kappa < nlsP->eta4) { 602a7e14dcfSSatish Balay /* Good step */ 603a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->alpha4 * norm_d, tao->trust); 60487f595a5SBarry Smith } else { 605a7e14dcfSSatish Balay /* Very good step */ 606a7e14dcfSSatish Balay tao->trust = PetscMax(nlsP->alpha5 * norm_d, tao->trust); 607a7e14dcfSSatish Balay } 608a7e14dcfSSatish Balay } 609a7e14dcfSSatish Balay } 61087f595a5SBarry Smith } else { 611a7e14dcfSSatish Balay /* Newton step was not good; reduce the radius */ 612a7e14dcfSSatish Balay tao->trust = nlsP->alpha1 * PetscMin(norm_d, tao->trust); 613a7e14dcfSSatish Balay } 614a7e14dcfSSatish Balay break; 615a7e14dcfSSatish Balay 616a7e14dcfSSatish Balay default: 617a7e14dcfSSatish Balay if (stepType == NLS_NEWTON) { 618ba7fe8fbSTodd Munson ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr); 619a7e14dcfSSatish Balay if (prered >= 0.0) { 620a7e14dcfSSatish Balay /* The predicted reduction has the wrong sign. This cannot */ 621a7e14dcfSSatish Balay /* happen in infinite precision arithmetic. Step should */ 622a7e14dcfSSatish Balay /* be rejected! */ 623a7e14dcfSSatish Balay tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d); 62487f595a5SBarry Smith } else { 625a7e14dcfSSatish Balay if (PetscIsInfOrNanReal(f_full)) { 626a7e14dcfSSatish Balay tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d); 62787f595a5SBarry Smith } else { 628a7e14dcfSSatish Balay actred = fold - f_full; 629a7e14dcfSSatish Balay prered = -prered; 63087f595a5SBarry Smith if ((PetscAbsScalar(actred) <= nlsP->epsilon) && (PetscAbsScalar(prered) <= nlsP->epsilon)) { 631a7e14dcfSSatish Balay kappa = 1.0; 63287f595a5SBarry Smith } else { 633a7e14dcfSSatish Balay kappa = actred / prered; 634a7e14dcfSSatish Balay } 635a7e14dcfSSatish Balay 636a7e14dcfSSatish Balay tau_1 = nlsP->theta * gdx / (nlsP->theta * gdx - (1.0 - nlsP->theta) * prered + actred); 637a7e14dcfSSatish Balay tau_2 = nlsP->theta * gdx / (nlsP->theta * gdx + (1.0 + nlsP->theta) * prered - actred); 638a7e14dcfSSatish Balay tau_min = PetscMin(tau_1, tau_2); 639a7e14dcfSSatish Balay tau_max = PetscMax(tau_1, tau_2); 640a7e14dcfSSatish Balay 641a7e14dcfSSatish Balay if (kappa >= 1.0 - nlsP->mu1) { 642a7e14dcfSSatish Balay /* Great agreement */ 643a7e14dcfSSatish Balay if (tau_max < 1.0) { 644a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->gamma3 * norm_d); 64587f595a5SBarry Smith } else if (tau_max > nlsP->gamma4) { 646a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->gamma4 * norm_d); 64787f595a5SBarry Smith } else { 648a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, tau_max * norm_d); 649a7e14dcfSSatish Balay } 65087f595a5SBarry Smith } else if (kappa >= 1.0 - nlsP->mu2) { 651a7e14dcfSSatish Balay /* Good agreement */ 652a7e14dcfSSatish Balay 653a7e14dcfSSatish Balay if (tau_max < nlsP->gamma2) { 654a7e14dcfSSatish Balay tao->trust = nlsP->gamma2 * PetscMin(tao->trust, norm_d); 65587f595a5SBarry Smith } else if (tau_max > nlsP->gamma3) { 656a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, nlsP->gamma3 * norm_d); 65787f595a5SBarry Smith } else if (tau_max < 1.0) { 658a7e14dcfSSatish Balay tao->trust = tau_max * PetscMin(tao->trust, norm_d); 65987f595a5SBarry Smith } else { 660a7e14dcfSSatish Balay tao->trust = PetscMax(tao->trust, tau_max * norm_d); 661a7e14dcfSSatish Balay } 66287f595a5SBarry Smith } else { 663a7e14dcfSSatish Balay /* Not good agreement */ 664a7e14dcfSSatish Balay if (tau_min > 1.0) { 665a7e14dcfSSatish Balay tao->trust = nlsP->gamma2 * PetscMin(tao->trust, norm_d); 66687f595a5SBarry Smith } else if (tau_max < nlsP->gamma1) { 667a7e14dcfSSatish Balay tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d); 66887f595a5SBarry Smith } else if ((tau_min < nlsP->gamma1) && (tau_max >= 1.0)) { 669a7e14dcfSSatish Balay tao->trust = nlsP->gamma1 * PetscMin(tao->trust, norm_d); 67087f595a5SBarry Smith } else if ((tau_1 >= nlsP->gamma1) && (tau_1 < 1.0) && ((tau_2 < nlsP->gamma1) || (tau_2 >= 1.0))) { 671a7e14dcfSSatish Balay tao->trust = tau_1 * PetscMin(tao->trust, norm_d); 67287f595a5SBarry Smith } else if ((tau_2 >= nlsP->gamma1) && (tau_2 < 1.0) && ((tau_1 < nlsP->gamma1) || (tau_2 >= 1.0))) { 673a7e14dcfSSatish Balay tao->trust = tau_2 * PetscMin(tao->trust, norm_d); 67487f595a5SBarry Smith } else { 675a7e14dcfSSatish Balay tao->trust = tau_max * PetscMin(tao->trust, norm_d); 676a7e14dcfSSatish Balay } 677a7e14dcfSSatish Balay } 678a7e14dcfSSatish Balay } 679a7e14dcfSSatish Balay } 68087f595a5SBarry Smith } else { 681a7e14dcfSSatish Balay /* Newton step was not good; reduce the radius */ 682a7e14dcfSSatish Balay tao->trust = nlsP->gamma1 * PetscMin(norm_d, tao->trust); 683a7e14dcfSSatish Balay } 684a7e14dcfSSatish Balay break; 685a7e14dcfSSatish Balay } 686a7e14dcfSSatish Balay 687a7e14dcfSSatish Balay /* The radius may have been increased; modify if it is too large */ 688a7e14dcfSSatish Balay tao->trust = PetscMin(tao->trust, nlsP->max_radius); 689a7e14dcfSSatish Balay } 690a7e14dcfSSatish Balay 691a7e14dcfSSatish Balay /* Check for termination */ 692a9603a14SPatrick Farrell ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 69387f595a5SBarry Smith if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1,"User provided compute function generated Not-a-Number"); 694a7e14dcfSSatish Balay needH = 1; 6953ecd9318SAlp Dener ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 6963ecd9318SAlp Dener ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,step);CHKERRQ(ierr); 6973ecd9318SAlp Dener ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 698a7e14dcfSSatish Balay } 699a7e14dcfSSatish Balay PetscFunctionReturn(0); 700a7e14dcfSSatish Balay } 701a7e14dcfSSatish Balay 702a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 703441846f8SBarry Smith static PetscErrorCode TaoSetUp_NLS(Tao tao) 704a7e14dcfSSatish Balay { 705a7e14dcfSSatish Balay TAO_NLS *nlsP = (TAO_NLS *)tao->data; 706a7e14dcfSSatish Balay PetscErrorCode ierr; 707a7e14dcfSSatish Balay 708a7e14dcfSSatish Balay PetscFunctionBegin; 709a7e14dcfSSatish Balay if (!tao->gradient) {ierr = VecDuplicate(tao->solution,&tao->gradient);CHKERRQ(ierr);} 710a7e14dcfSSatish Balay if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution,&tao->stepdirection);CHKERRQ(ierr);} 711a7e14dcfSSatish Balay if (!nlsP->W) {ierr = VecDuplicate(tao->solution,&nlsP->W);CHKERRQ(ierr);} 712a7e14dcfSSatish Balay if (!nlsP->D) {ierr = VecDuplicate(tao->solution,&nlsP->D);CHKERRQ(ierr);} 713a7e14dcfSSatish Balay if (!nlsP->Xold) {ierr = VecDuplicate(tao->solution,&nlsP->Xold);CHKERRQ(ierr);} 714a7e14dcfSSatish Balay if (!nlsP->Gold) {ierr = VecDuplicate(tao->solution,&nlsP->Gold);CHKERRQ(ierr);} 715a7e14dcfSSatish Balay nlsP->M = 0; 716*0c51296cSAlp Dener nlsP->bfgs_pre = 0; 717a7e14dcfSSatish Balay PetscFunctionReturn(0); 718a7e14dcfSSatish Balay } 719a7e14dcfSSatish Balay 720a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 721441846f8SBarry Smith static PetscErrorCode TaoDestroy_NLS(Tao tao) 722a7e14dcfSSatish Balay { 723a7e14dcfSSatish Balay TAO_NLS *nlsP = (TAO_NLS *)tao->data; 724a7e14dcfSSatish Balay PetscErrorCode ierr; 725a7e14dcfSSatish Balay 726a7e14dcfSSatish Balay PetscFunctionBegin; 727a7e14dcfSSatish Balay if (tao->setupcalled) { 728a7e14dcfSSatish Balay ierr = VecDestroy(&nlsP->D);CHKERRQ(ierr); 729a7e14dcfSSatish Balay ierr = VecDestroy(&nlsP->W);CHKERRQ(ierr); 730a7e14dcfSSatish Balay ierr = VecDestroy(&nlsP->Xold);CHKERRQ(ierr); 731a7e14dcfSSatish Balay ierr = VecDestroy(&nlsP->Gold);CHKERRQ(ierr); 732a7e14dcfSSatish Balay } 733a7e14dcfSSatish Balay ierr = PetscFree(tao->data);CHKERRQ(ierr); 734a7e14dcfSSatish Balay PetscFunctionReturn(0); 735a7e14dcfSSatish Balay } 736a7e14dcfSSatish Balay 737a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 7384416b707SBarry Smith static PetscErrorCode TaoSetFromOptions_NLS(PetscOptionItems *PetscOptionsObject,Tao tao) 739a7e14dcfSSatish Balay { 740a7e14dcfSSatish Balay TAO_NLS *nlsP = (TAO_NLS *)tao->data; 741a7e14dcfSSatish Balay PetscErrorCode ierr; 742a7e14dcfSSatish Balay 743a7e14dcfSSatish Balay PetscFunctionBegin; 7441a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Newton line search method for unconstrained optimization");CHKERRQ(ierr); 745a7e14dcfSSatish Balay ierr = PetscOptionsEList("-tao_nls_init_type", "radius initialization type", "", NLS_INIT, NLS_INIT_TYPES, NLS_INIT[nlsP->init_type], &nlsP->init_type, 0);CHKERRQ(ierr); 746a7e14dcfSSatish Balay ierr = PetscOptionsEList("-tao_nls_update_type", "radius update type", "", NLS_UPDATE, NLS_UPDATE_TYPES, NLS_UPDATE[nlsP->update_type], &nlsP->update_type, 0);CHKERRQ(ierr); 74794ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_sval", "perturbation starting value", "", nlsP->sval, &nlsP->sval,NULL);CHKERRQ(ierr); 74894ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_imin", "minimum initial perturbation", "", nlsP->imin, &nlsP->imin,NULL);CHKERRQ(ierr); 74994ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_imax", "maximum initial perturbation", "", nlsP->imax, &nlsP->imax,NULL);CHKERRQ(ierr); 75094ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_imfac", "initial merit factor", "", nlsP->imfac, &nlsP->imfac,NULL);CHKERRQ(ierr); 75194ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_pmin", "minimum perturbation", "", nlsP->pmin, &nlsP->pmin,NULL);CHKERRQ(ierr); 75294ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_pmax", "maximum perturbation", "", nlsP->pmax, &nlsP->pmax,NULL);CHKERRQ(ierr); 75394ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_pgfac", "growth factor", "", nlsP->pgfac, &nlsP->pgfac,NULL);CHKERRQ(ierr); 75494ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_psfac", "shrink factor", "", nlsP->psfac, &nlsP->psfac,NULL);CHKERRQ(ierr); 75594ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_pmgfac", "merit growth factor", "", nlsP->pmgfac, &nlsP->pmgfac,NULL);CHKERRQ(ierr); 75694ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_pmsfac", "merit shrink factor", "", nlsP->pmsfac, &nlsP->pmsfac,NULL);CHKERRQ(ierr); 75794ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_eta1", "poor steplength; reduce radius", "", nlsP->eta1, &nlsP->eta1,NULL);CHKERRQ(ierr); 75894ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_eta2", "reasonable steplength; leave radius alone", "", nlsP->eta2, &nlsP->eta2,NULL);CHKERRQ(ierr); 75994ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_eta3", "good steplength; increase radius", "", nlsP->eta3, &nlsP->eta3,NULL);CHKERRQ(ierr); 76094ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_eta4", "excellent steplength; greatly increase radius", "", nlsP->eta4, &nlsP->eta4,NULL);CHKERRQ(ierr); 76194ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_alpha1", "", "", nlsP->alpha1, &nlsP->alpha1,NULL);CHKERRQ(ierr); 76294ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_alpha2", "", "", nlsP->alpha2, &nlsP->alpha2,NULL);CHKERRQ(ierr); 76394ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_alpha3", "", "", nlsP->alpha3, &nlsP->alpha3,NULL);CHKERRQ(ierr); 76494ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_alpha4", "", "", nlsP->alpha4, &nlsP->alpha4,NULL);CHKERRQ(ierr); 76594ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_alpha5", "", "", nlsP->alpha5, &nlsP->alpha5,NULL);CHKERRQ(ierr); 76694ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_nu1", "poor steplength; reduce radius", "", nlsP->nu1, &nlsP->nu1,NULL);CHKERRQ(ierr); 76794ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_nu2", "reasonable steplength; leave radius alone", "", nlsP->nu2, &nlsP->nu2,NULL);CHKERRQ(ierr); 76894ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_nu3", "good steplength; increase radius", "", nlsP->nu3, &nlsP->nu3,NULL);CHKERRQ(ierr); 76994ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_nu4", "excellent steplength; greatly increase radius", "", nlsP->nu4, &nlsP->nu4,NULL);CHKERRQ(ierr); 77094ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_omega1", "", "", nlsP->omega1, &nlsP->omega1,NULL);CHKERRQ(ierr); 77194ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_omega2", "", "", nlsP->omega2, &nlsP->omega2,NULL);CHKERRQ(ierr); 77294ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_omega3", "", "", nlsP->omega3, &nlsP->omega3,NULL);CHKERRQ(ierr); 77394ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_omega4", "", "", nlsP->omega4, &nlsP->omega4,NULL);CHKERRQ(ierr); 77494ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_omega5", "", "", nlsP->omega5, &nlsP->omega5,NULL);CHKERRQ(ierr); 77594ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_mu1_i", "", "", nlsP->mu1_i, &nlsP->mu1_i,NULL);CHKERRQ(ierr); 77694ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_mu2_i", "", "", nlsP->mu2_i, &nlsP->mu2_i,NULL);CHKERRQ(ierr); 77794ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma1_i", "", "", nlsP->gamma1_i, &nlsP->gamma1_i,NULL);CHKERRQ(ierr); 77894ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma2_i", "", "", nlsP->gamma2_i, &nlsP->gamma2_i,NULL);CHKERRQ(ierr); 77994ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma3_i", "", "", nlsP->gamma3_i, &nlsP->gamma3_i,NULL);CHKERRQ(ierr); 78094ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma4_i", "", "", nlsP->gamma4_i, &nlsP->gamma4_i,NULL);CHKERRQ(ierr); 78194ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_theta_i", "", "", nlsP->theta_i, &nlsP->theta_i,NULL);CHKERRQ(ierr); 78294ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_mu1", "", "", nlsP->mu1, &nlsP->mu1,NULL);CHKERRQ(ierr); 78394ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_mu2", "", "", nlsP->mu2, &nlsP->mu2,NULL);CHKERRQ(ierr); 78494ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma1", "", "", nlsP->gamma1, &nlsP->gamma1,NULL);CHKERRQ(ierr); 78594ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma2", "", "", nlsP->gamma2, &nlsP->gamma2,NULL);CHKERRQ(ierr); 78694ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma3", "", "", nlsP->gamma3, &nlsP->gamma3,NULL);CHKERRQ(ierr); 78794ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_gamma4", "", "", nlsP->gamma4, &nlsP->gamma4,NULL);CHKERRQ(ierr); 78894ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_theta", "", "", nlsP->theta, &nlsP->theta,NULL);CHKERRQ(ierr); 78994ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_min_radius", "lower bound on initial radius", "", nlsP->min_radius, &nlsP->min_radius,NULL);CHKERRQ(ierr); 79094ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_max_radius", "upper bound on radius", "", nlsP->max_radius, &nlsP->max_radius,NULL);CHKERRQ(ierr); 79194ae4db5SBarry Smith ierr = PetscOptionsReal("-tao_nls_epsilon", "tolerance used when computing actual and predicted reduction", "", nlsP->epsilon, &nlsP->epsilon,NULL);CHKERRQ(ierr); 792a7e14dcfSSatish Balay ierr = PetscOptionsTail();CHKERRQ(ierr); 793a7e14dcfSSatish Balay ierr = TaoLineSearchSetFromOptions(tao->linesearch);CHKERRQ(ierr); 794a7e14dcfSSatish Balay ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 795a7e14dcfSSatish Balay PetscFunctionReturn(0); 796a7e14dcfSSatish Balay } 797a7e14dcfSSatish Balay 798a7e14dcfSSatish Balay 799a7e14dcfSSatish Balay /*------------------------------------------------------------*/ 800441846f8SBarry Smith static PetscErrorCode TaoView_NLS(Tao tao, PetscViewer viewer) 801a7e14dcfSSatish Balay { 802a7e14dcfSSatish Balay TAO_NLS *nlsP = (TAO_NLS *)tao->data; 803a7e14dcfSSatish Balay PetscBool isascii; 804a7e14dcfSSatish Balay PetscErrorCode ierr; 805a7e14dcfSSatish Balay 806a7e14dcfSSatish Balay PetscFunctionBegin; 807a7e14dcfSSatish Balay ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 808a7e14dcfSSatish Balay if (isascii) { 809a7e14dcfSSatish Balay ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 810a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "Newton steps: %D\n", nlsP->newt);CHKERRQ(ierr); 811a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "BFGS steps: %D\n", nlsP->bfgs);CHKERRQ(ierr); 812a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "Gradient steps: %D\n", nlsP->grad);CHKERRQ(ierr); 813a7e14dcfSSatish Balay 814a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp atol: %D\n", nlsP->ksp_atol);CHKERRQ(ierr); 815a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp rtol: %D\n", nlsP->ksp_rtol);CHKERRQ(ierr); 816a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp ctol: %D\n", nlsP->ksp_ctol);CHKERRQ(ierr); 817a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp negc: %D\n", nlsP->ksp_negc);CHKERRQ(ierr); 818a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp dtol: %D\n", nlsP->ksp_dtol);CHKERRQ(ierr); 819a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp iter: %D\n", nlsP->ksp_iter);CHKERRQ(ierr); 820a7e14dcfSSatish Balay ierr = PetscViewerASCIIPrintf(viewer, "nls ksp othr: %D\n", nlsP->ksp_othr);CHKERRQ(ierr); 821a7e14dcfSSatish Balay ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 822a7e14dcfSSatish Balay } 823a7e14dcfSSatish Balay PetscFunctionReturn(0); 824a7e14dcfSSatish Balay } 825a7e14dcfSSatish Balay 826a7e14dcfSSatish Balay /* ---------------------------------------------------------- */ 8274aa34175SJason Sarich /*MC 8284aa34175SJason Sarich TAONLS - Newton's method with linesearch for unconstrained minimization. 8294aa34175SJason Sarich At each iteration, the Newton line search method solves the symmetric 8304aa34175SJason Sarich system of equations to obtain the step diretion dk: 8314aa34175SJason Sarich Hk dk = -gk 8324aa34175SJason Sarich a More-Thuente line search is applied on the direction dk to approximately 8334aa34175SJason Sarich solve 8344aa34175SJason Sarich min_t f(xk + t d_k) 8354aa34175SJason Sarich 8364aa34175SJason Sarich Options Database Keys: 8371daac38eSTodd Munson + -tao_nls_pc_type - "none","ahess","bfgs","petsc" 8384aa34175SJason Sarich . -tao_nls_bfgs_scale_type - "ahess","phess","bfgs" 8394aa34175SJason Sarich . -tao_nls_init_type - "constant","direction","interpolation" 8404aa34175SJason Sarich . -tao_nls_update_type - "step","direction","interpolation" 8414aa34175SJason Sarich . -tao_nls_sval - perturbation starting value 8424aa34175SJason Sarich . -tao_nls_imin - minimum initial perturbation 8434aa34175SJason Sarich . -tao_nls_imax - maximum initial perturbation 8444aa34175SJason Sarich . -tao_nls_pmin - minimum perturbation 8454aa34175SJason Sarich . -tao_nls_pmax - maximum perturbation 8464aa34175SJason Sarich . -tao_nls_pgfac - growth factor 8474aa34175SJason Sarich . -tao_nls_psfac - shrink factor 8484aa34175SJason Sarich . -tao_nls_imfac - initial merit factor 8494aa34175SJason Sarich . -tao_nls_pmgfac - merit growth factor 8504aa34175SJason Sarich . -tao_nls_pmsfac - merit shrink factor 8514aa34175SJason Sarich . -tao_nls_eta1 - poor steplength; reduce radius 8524aa34175SJason Sarich . -tao_nls_eta2 - reasonable steplength; leave radius 8534aa34175SJason Sarich . -tao_nls_eta3 - good steplength; increase readius 8544aa34175SJason Sarich . -tao_nls_eta4 - excellent steplength; greatly increase radius 8554aa34175SJason Sarich . -tao_nls_alpha1 - alpha1 reduction 8564aa34175SJason Sarich . -tao_nls_alpha2 - alpha2 reduction 8574aa34175SJason Sarich . -tao_nls_alpha3 - alpha3 reduction 8584aa34175SJason Sarich . -tao_nls_alpha4 - alpha4 reduction 8594aa34175SJason Sarich . -tao_nls_alpha - alpha5 reduction 8604aa34175SJason Sarich . -tao_nls_mu1 - mu1 interpolation update 8614aa34175SJason Sarich . -tao_nls_mu2 - mu2 interpolation update 8624aa34175SJason Sarich . -tao_nls_gamma1 - gamma1 interpolation update 8634aa34175SJason Sarich . -tao_nls_gamma2 - gamma2 interpolation update 8644aa34175SJason Sarich . -tao_nls_gamma3 - gamma3 interpolation update 8654aa34175SJason Sarich . -tao_nls_gamma4 - gamma4 interpolation update 8664aa34175SJason Sarich . -tao_nls_theta - theta interpolation update 8674aa34175SJason Sarich . -tao_nls_omega1 - omega1 step update 8684aa34175SJason Sarich . -tao_nls_omega2 - omega2 step update 8694aa34175SJason Sarich . -tao_nls_omega3 - omega3 step update 8704aa34175SJason Sarich . -tao_nls_omega4 - omega4 step update 8714aa34175SJason Sarich . -tao_nls_omega5 - omega5 step update 8721522df2eSJason Sarich . -tao_nls_mu1_i - mu1 interpolation init factor 8731522df2eSJason Sarich . -tao_nls_mu2_i - mu2 interpolation init factor 8741522df2eSJason Sarich . -tao_nls_gamma1_i - gamma1 interpolation init factor 8751522df2eSJason Sarich . -tao_nls_gamma2_i - gamma2 interpolation init factor 8761522df2eSJason Sarich . -tao_nls_gamma3_i - gamma3 interpolation init factor 8771522df2eSJason Sarich . -tao_nls_gamma4_i - gamma4 interpolation init factor 8781522df2eSJason Sarich - -tao_nls_theta_i - theta interpolation init factor 8791eb8069cSJason Sarich 8801eb8069cSJason Sarich Level: beginner 8811522df2eSJason Sarich M*/ 8824aa34175SJason Sarich 883728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoCreate_NLS(Tao tao) 884a7e14dcfSSatish Balay { 885a7e14dcfSSatish Balay TAO_NLS *nlsP; 8868caf6e8cSBarry Smith const char *morethuente_type = TAOLINESEARCHMT; 887a7e14dcfSSatish Balay PetscErrorCode ierr; 888a7e14dcfSSatish Balay 889a7e14dcfSSatish Balay PetscFunctionBegin; 8903c9e27cfSGeoffrey Irving ierr = PetscNewLog(tao,&nlsP);CHKERRQ(ierr); 891a7e14dcfSSatish Balay 892a7e14dcfSSatish Balay tao->ops->setup = TaoSetUp_NLS; 893a7e14dcfSSatish Balay tao->ops->solve = TaoSolve_NLS; 894a7e14dcfSSatish Balay tao->ops->view = TaoView_NLS; 895a7e14dcfSSatish Balay tao->ops->setfromoptions = TaoSetFromOptions_NLS; 896a7e14dcfSSatish Balay tao->ops->destroy = TaoDestroy_NLS; 897a7e14dcfSSatish Balay 8986552cf8aSJason Sarich /* Override default settings (unless already changed) */ 8996552cf8aSJason Sarich if (!tao->max_it_changed) tao->max_it = 50; 9006552cf8aSJason Sarich if (!tao->trust0_changed) tao->trust0 = 100.0; 9016552cf8aSJason Sarich 902a7e14dcfSSatish Balay tao->data = (void*)nlsP; 903a7e14dcfSSatish Balay 904a7e14dcfSSatish Balay nlsP->sval = 0.0; 905a7e14dcfSSatish Balay nlsP->imin = 1.0e-4; 906a7e14dcfSSatish Balay nlsP->imax = 1.0e+2; 907a7e14dcfSSatish Balay nlsP->imfac = 1.0e-1; 908a7e14dcfSSatish Balay 909a7e14dcfSSatish Balay nlsP->pmin = 1.0e-12; 910a7e14dcfSSatish Balay nlsP->pmax = 1.0e+2; 911a7e14dcfSSatish Balay nlsP->pgfac = 1.0e+1; 912a7e14dcfSSatish Balay nlsP->psfac = 4.0e-1; 913a7e14dcfSSatish Balay nlsP->pmgfac = 1.0e-1; 914a7e14dcfSSatish Balay nlsP->pmsfac = 1.0e-1; 915a7e14dcfSSatish Balay 916a7e14dcfSSatish Balay /* Default values for trust-region radius update based on steplength */ 917a7e14dcfSSatish Balay nlsP->nu1 = 0.25; 918a7e14dcfSSatish Balay nlsP->nu2 = 0.50; 919a7e14dcfSSatish Balay nlsP->nu3 = 1.00; 920a7e14dcfSSatish Balay nlsP->nu4 = 1.25; 921a7e14dcfSSatish Balay 922a7e14dcfSSatish Balay nlsP->omega1 = 0.25; 923a7e14dcfSSatish Balay nlsP->omega2 = 0.50; 924a7e14dcfSSatish Balay nlsP->omega3 = 1.00; 925a7e14dcfSSatish Balay nlsP->omega4 = 2.00; 926a7e14dcfSSatish Balay nlsP->omega5 = 4.00; 927a7e14dcfSSatish Balay 928a7e14dcfSSatish Balay /* Default values for trust-region radius update based on reduction */ 929a7e14dcfSSatish Balay nlsP->eta1 = 1.0e-4; 930a7e14dcfSSatish Balay nlsP->eta2 = 0.25; 931a7e14dcfSSatish Balay nlsP->eta3 = 0.50; 932a7e14dcfSSatish Balay nlsP->eta4 = 0.90; 933a7e14dcfSSatish Balay 934a7e14dcfSSatish Balay nlsP->alpha1 = 0.25; 935a7e14dcfSSatish Balay nlsP->alpha2 = 0.50; 936a7e14dcfSSatish Balay nlsP->alpha3 = 1.00; 937a7e14dcfSSatish Balay nlsP->alpha4 = 2.00; 938a7e14dcfSSatish Balay nlsP->alpha5 = 4.00; 939a7e14dcfSSatish Balay 940a7e14dcfSSatish Balay /* Default values for trust-region radius update based on interpolation */ 941a7e14dcfSSatish Balay nlsP->mu1 = 0.10; 942a7e14dcfSSatish Balay nlsP->mu2 = 0.50; 943a7e14dcfSSatish Balay 944a7e14dcfSSatish Balay nlsP->gamma1 = 0.25; 945a7e14dcfSSatish Balay nlsP->gamma2 = 0.50; 946a7e14dcfSSatish Balay nlsP->gamma3 = 2.00; 947a7e14dcfSSatish Balay nlsP->gamma4 = 4.00; 948a7e14dcfSSatish Balay 949a7e14dcfSSatish Balay nlsP->theta = 0.05; 950a7e14dcfSSatish Balay 951a7e14dcfSSatish Balay /* Default values for trust region initialization based on interpolation */ 952a7e14dcfSSatish Balay nlsP->mu1_i = 0.35; 953a7e14dcfSSatish Balay nlsP->mu2_i = 0.50; 954a7e14dcfSSatish Balay 955a7e14dcfSSatish Balay nlsP->gamma1_i = 0.0625; 956a7e14dcfSSatish Balay nlsP->gamma2_i = 0.5; 957a7e14dcfSSatish Balay nlsP->gamma3_i = 2.0; 958a7e14dcfSSatish Balay nlsP->gamma4_i = 5.0; 959a7e14dcfSSatish Balay 960a7e14dcfSSatish Balay nlsP->theta_i = 0.25; 961a7e14dcfSSatish Balay 962a7e14dcfSSatish Balay /* Remaining parameters */ 963a7e14dcfSSatish Balay nlsP->min_radius = 1.0e-10; 964a7e14dcfSSatish Balay nlsP->max_radius = 1.0e10; 965a7e14dcfSSatish Balay nlsP->epsilon = 1.0e-6; 966a7e14dcfSSatish Balay 967a7e14dcfSSatish Balay nlsP->init_type = NLS_INIT_INTERPOLATION; 968a7e14dcfSSatish Balay nlsP->update_type = NLS_UPDATE_STEP; 969a7e14dcfSSatish Balay 970a7e14dcfSSatish Balay ierr = TaoLineSearchCreate(((PetscObject)tao)->comm,&tao->linesearch);CHKERRQ(ierr); 97163b15415SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->linesearch, (PetscObject)tao, 1);CHKERRQ(ierr); 972a7e14dcfSSatish Balay ierr = TaoLineSearchSetType(tao->linesearch,morethuente_type);CHKERRQ(ierr); 973441846f8SBarry Smith ierr = TaoLineSearchUseTaoRoutines(tao->linesearch,tao);CHKERRQ(ierr); 9745d527766SPatrick Farrell ierr = TaoLineSearchSetOptionsPrefix(tao->linesearch,tao->hdr.prefix);CHKERRQ(ierr); 975a7e14dcfSSatish Balay 976a7e14dcfSSatish Balay /* Set linear solver to default for symmetric matrices */ 977a7e14dcfSSatish Balay ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 97863b15415SAlp Dener ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1);CHKERRQ(ierr); 9795d527766SPatrick Farrell ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 9801daac38eSTodd Munson ierr = KSPSetType(tao->ksp,KSPCGSTCG);CHKERRQ(ierr); 981a7e14dcfSSatish Balay PetscFunctionReturn(0); 982a7e14dcfSSatish Balay } 983