1 #include <../src/tao/unconstrained/impls/ntr/ntrimpl.h> 2 3 #include <petscksp.h> 4 5 #define NTR_INIT_CONSTANT 0 6 #define NTR_INIT_DIRECTION 1 7 #define NTR_INIT_INTERPOLATION 2 8 #define NTR_INIT_TYPES 3 9 10 #define NTR_UPDATE_REDUCTION 0 11 #define NTR_UPDATE_INTERPOLATION 1 12 #define NTR_UPDATE_TYPES 2 13 14 static const char *NTR_INIT[64] = {"constant","direction","interpolation"}; 15 16 static const char *NTR_UPDATE[64] = {"reduction","interpolation"}; 17 18 /* 19 TaoSolve_NTR - Implements Newton's Method with a trust region approach 20 for solving unconstrained minimization problems. 21 22 The basic algorithm is taken from MINPACK-2 (dstrn). 23 24 TaoSolve_NTR computes a local minimizer of a twice differentiable function 25 f by applying a trust region variant of Newton's method. At each stage 26 of the algorithm, we use the prconditioned conjugate gradient method to 27 determine an approximate minimizer of the quadratic equation 28 29 q(s) = <s, Hs + g> 30 31 subject to the trust region constraint 32 33 || s ||_M <= radius, 34 35 where radius is the trust region radius and M is a symmetric positive 36 definite matrix (the preconditioner). Here g is the gradient and H 37 is the Hessian matrix. 38 39 Note: TaoSolve_NTR MUST use the iterative solver KSPNASH, KSPSTCG, 40 or KSPGLTR. Thus, we set KSPNASH, KSPSTCG, or KSPGLTR in this 41 routine regardless of what the user may have previously specified. 42 */ 43 static PetscErrorCode TaoSolve_NTR(Tao tao) 44 { 45 TAO_NTR *tr = (TAO_NTR *)tao->data; 46 KSPType ksp_type; 47 PetscBool is_nash,is_stcg,is_gltr,is_bfgs,is_jacobi,is_symmetric,sym_set; 48 KSPConvergedReason ksp_reason; 49 PC pc; 50 PetscReal fmin, ftrial, prered, actred, kappa, sigma, beta; 51 PetscReal tau, tau_1, tau_2, tau_max, tau_min, max_radius; 52 PetscReal f, gnorm; 53 54 PetscReal norm_d; 55 PetscErrorCode ierr; 56 PetscInt bfgsUpdates = 0; 57 PetscInt needH; 58 59 PetscInt i_max = 5; 60 PetscInt j_max = 1; 61 PetscInt i, j, N, n, its; 62 63 PetscFunctionBegin; 64 if (tao->XL || tao->XU || tao->ops->computebounds) { 65 ierr = PetscInfo(tao,"WARNING: Variable bounds have been set but will be ignored by ntr algorithm\n");CHKERRQ(ierr); 66 } 67 68 ierr = KSPGetType(tao->ksp,&ksp_type);CHKERRQ(ierr); 69 ierr = PetscStrcmp(ksp_type,KSPNASH,&is_nash);CHKERRQ(ierr); 70 ierr = PetscStrcmp(ksp_type,KSPSTCG,&is_stcg);CHKERRQ(ierr); 71 ierr = PetscStrcmp(ksp_type,KSPGLTR,&is_gltr);CHKERRQ(ierr); 72 if (!is_nash && !is_stcg && !is_gltr) { 73 SETERRQ(PETSC_COMM_SELF,1,"TAO_NTR requires nash, stcg, or gltr for the KSP"); 74 } 75 76 /* Initialize the radius and modify if it is too large or small */ 77 tao->trust = tao->trust0; 78 tao->trust = PetscMax(tao->trust, tr->min_radius); 79 tao->trust = PetscMin(tao->trust, tr->max_radius); 80 81 /* Allocate the vectors needed for the BFGS approximation */ 82 ierr = KSPGetPC(tao->ksp, &pc);CHKERRQ(ierr); 83 ierr = PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs);CHKERRQ(ierr); 84 ierr = PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi);CHKERRQ(ierr); 85 if (is_bfgs) { 86 tr->bfgs_pre = pc; 87 ierr = PCLMVMGetMatLMVM(tr->bfgs_pre, &tr->M);CHKERRQ(ierr); 88 ierr = VecGetLocalSize(tao->solution, &n);CHKERRQ(ierr); 89 ierr = VecGetSize(tao->solution, &N);CHKERRQ(ierr); 90 ierr = MatSetSizes(tr->M, n, n, N, N);CHKERRQ(ierr); 91 ierr = MatLMVMAllocate(tr->M, tao->solution, tao->gradient);CHKERRQ(ierr); 92 ierr = MatIsSymmetricKnown(tr->M, &sym_set, &is_symmetric);CHKERRQ(ierr); 93 if (!sym_set || !is_symmetric) SETERRQ(PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix in the LMVM preconditioner must be symmetric."); 94 } else if (is_jacobi) { 95 ierr = PCJacobiSetUseAbs(pc,PETSC_TRUE);CHKERRQ(ierr); 96 } 97 98 /* Check convergence criteria */ 99 ierr = TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient);CHKERRQ(ierr); 100 ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 101 if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1,"User provided compute function generated Inf or NaN"); 102 needH = 1; 103 104 tao->reason = TAO_CONTINUE_ITERATING; 105 ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 106 ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,1.0);CHKERRQ(ierr); 107 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 108 if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0); 109 110 /* Initialize trust-region radius */ 111 switch (tr->init_type) { 112 case NTR_INIT_CONSTANT: 113 /* Use the initial radius specified */ 114 break; 115 116 case NTR_INIT_INTERPOLATION: 117 /* Use the initial radius specified */ 118 max_radius = 0.0; 119 120 for (j = 0; j < j_max; ++j) { 121 fmin = f; 122 sigma = 0.0; 123 124 if (needH) { 125 ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 126 needH = 0; 127 } 128 129 for (i = 0; i < i_max; ++i) { 130 131 ierr = VecCopy(tao->solution, tr->W);CHKERRQ(ierr); 132 ierr = VecAXPY(tr->W, -tao->trust/gnorm, tao->gradient);CHKERRQ(ierr); 133 ierr = TaoComputeObjective(tao, tr->W, &ftrial);CHKERRQ(ierr); 134 135 if (PetscIsInfOrNanReal(ftrial)) { 136 tau = tr->gamma1_i; 137 } 138 else { 139 if (ftrial < fmin) { 140 fmin = ftrial; 141 sigma = -tao->trust / gnorm; 142 } 143 144 ierr = MatMult(tao->hessian, tao->gradient, tao->stepdirection);CHKERRQ(ierr); 145 ierr = VecDot(tao->gradient, tao->stepdirection, &prered);CHKERRQ(ierr); 146 147 prered = tao->trust * (gnorm - 0.5 * tao->trust * prered / (gnorm * gnorm)); 148 actred = f - ftrial; 149 if ((PetscAbsScalar(actred) <= tr->epsilon) && 150 (PetscAbsScalar(prered) <= tr->epsilon)) { 151 kappa = 1.0; 152 } 153 else { 154 kappa = actred / prered; 155 } 156 157 tau_1 = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust + (1.0 - tr->theta_i) * prered - actred); 158 tau_2 = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust - (1.0 + tr->theta_i) * prered + actred); 159 tau_min = PetscMin(tau_1, tau_2); 160 tau_max = PetscMax(tau_1, tau_2); 161 162 if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu1_i) { 163 /* Great agreement */ 164 max_radius = PetscMax(max_radius, tao->trust); 165 166 if (tau_max < 1.0) { 167 tau = tr->gamma3_i; 168 } 169 else if (tau_max > tr->gamma4_i) { 170 tau = tr->gamma4_i; 171 } 172 else { 173 tau = tau_max; 174 } 175 } 176 else if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu2_i) { 177 /* Good agreement */ 178 max_radius = PetscMax(max_radius, tao->trust); 179 180 if (tau_max < tr->gamma2_i) { 181 tau = tr->gamma2_i; 182 } 183 else if (tau_max > tr->gamma3_i) { 184 tau = tr->gamma3_i; 185 } 186 else { 187 tau = tau_max; 188 } 189 } 190 else { 191 /* Not good agreement */ 192 if (tau_min > 1.0) { 193 tau = tr->gamma2_i; 194 } 195 else if (tau_max < tr->gamma1_i) { 196 tau = tr->gamma1_i; 197 } 198 else if ((tau_min < tr->gamma1_i) && (tau_max >= 1.0)) { 199 tau = tr->gamma1_i; 200 } 201 else if ((tau_1 >= tr->gamma1_i) && (tau_1 < 1.0) && 202 ((tau_2 < tr->gamma1_i) || (tau_2 >= 1.0))) { 203 tau = tau_1; 204 } 205 else if ((tau_2 >= tr->gamma1_i) && (tau_2 < 1.0) && 206 ((tau_1 < tr->gamma1_i) || (tau_2 >= 1.0))) { 207 tau = tau_2; 208 } 209 else { 210 tau = tau_max; 211 } 212 } 213 } 214 tao->trust = tau * tao->trust; 215 } 216 217 if (fmin < f) { 218 f = fmin; 219 ierr = VecAXPY(tao->solution, sigma, tao->gradient);CHKERRQ(ierr); 220 ierr = TaoComputeGradient(tao,tao->solution, tao->gradient);CHKERRQ(ierr); 221 222 ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 223 224 if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 225 needH = 1; 226 227 ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 228 ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,1.0);CHKERRQ(ierr); 229 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 230 if (tao->reason != TAO_CONTINUE_ITERATING) { 231 PetscFunctionReturn(0); 232 } 233 } 234 } 235 tao->trust = PetscMax(tao->trust, max_radius); 236 237 /* Modify the radius if it is too large or small */ 238 tao->trust = PetscMax(tao->trust, tr->min_radius); 239 tao->trust = PetscMin(tao->trust, tr->max_radius); 240 break; 241 242 default: 243 /* Norm of the first direction will initialize radius */ 244 tao->trust = 0.0; 245 break; 246 } 247 248 /* Have not converged; continue with Newton method */ 249 while (tao->reason == TAO_CONTINUE_ITERATING) { 250 /* Call general purpose update function */ 251 if (tao->ops->update) { 252 ierr = (*tao->ops->update)(tao, tao->niter, tao->user_update);CHKERRQ(ierr); 253 } 254 ++tao->niter; 255 tao->ksp_its=0; 256 /* Compute the Hessian */ 257 if (needH) { 258 ierr = TaoComputeHessian(tao,tao->solution,tao->hessian,tao->hessian_pre);CHKERRQ(ierr); 259 needH = 0; 260 } 261 262 if (tr->bfgs_pre) { 263 /* Update the limited memory preconditioner */ 264 ierr = MatLMVMUpdate(tr->M, tao->solution, tao->gradient);CHKERRQ(ierr); 265 ++bfgsUpdates; 266 } 267 268 while (tao->reason == TAO_CONTINUE_ITERATING) { 269 ierr = KSPSetOperators(tao->ksp, tao->hessian, tao->hessian_pre);CHKERRQ(ierr); 270 271 /* Solve the trust region subproblem */ 272 ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 273 ierr = KSPSolve(tao->ksp, tao->gradient, tao->stepdirection);CHKERRQ(ierr); 274 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 275 tao->ksp_its+=its; 276 tao->ksp_tot_its+=its; 277 ierr = KSPCGGetNormD(tao->ksp, &norm_d);CHKERRQ(ierr); 278 279 if (0.0 == tao->trust) { 280 /* Radius was uninitialized; use the norm of the direction */ 281 if (norm_d > 0.0) { 282 tao->trust = norm_d; 283 284 /* Modify the radius if it is too large or small */ 285 tao->trust = PetscMax(tao->trust, tr->min_radius); 286 tao->trust = PetscMin(tao->trust, tr->max_radius); 287 } 288 else { 289 /* The direction was bad; set radius to default value and re-solve 290 the trust-region subproblem to get a direction */ 291 tao->trust = tao->trust0; 292 293 /* Modify the radius if it is too large or small */ 294 tao->trust = PetscMax(tao->trust, tr->min_radius); 295 tao->trust = PetscMin(tao->trust, tr->max_radius); 296 297 ierr = KSPCGSetRadius(tao->ksp,tao->trust);CHKERRQ(ierr); 298 ierr = KSPSolve(tao->ksp, tao->gradient, tao->stepdirection);CHKERRQ(ierr); 299 ierr = KSPGetIterationNumber(tao->ksp,&its);CHKERRQ(ierr); 300 tao->ksp_its+=its; 301 tao->ksp_tot_its+=its; 302 ierr = KSPCGGetNormD(tao->ksp, &norm_d);CHKERRQ(ierr); 303 304 if (norm_d == 0.0) SETERRQ(PETSC_COMM_SELF,1, "Initial direction zero"); 305 } 306 } 307 ierr = VecScale(tao->stepdirection, -1.0);CHKERRQ(ierr); 308 ierr = KSPGetConvergedReason(tao->ksp, &ksp_reason);CHKERRQ(ierr); 309 if ((KSP_DIVERGED_INDEFINITE_PC == ksp_reason) && (tr->bfgs_pre)) { 310 /* Preconditioner is numerically indefinite; reset the 311 approximate if using BFGS preconditioning. */ 312 ierr = MatLMVMReset(tr->M, PETSC_FALSE);CHKERRQ(ierr); 313 ierr = MatLMVMUpdate(tr->M, tao->solution, tao->gradient);CHKERRQ(ierr); 314 bfgsUpdates = 1; 315 } 316 317 if (NTR_UPDATE_REDUCTION == tr->update_type) { 318 /* Get predicted reduction */ 319 ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr); 320 if (prered >= 0.0) { 321 /* The predicted reduction has the wrong sign. This cannot 322 happen in infinite precision arithmetic. Step should 323 be rejected! */ 324 tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d); 325 } 326 else { 327 /* Compute trial step and function value */ 328 ierr = VecCopy(tao->solution,tr->W);CHKERRQ(ierr); 329 ierr = VecAXPY(tr->W, 1.0, tao->stepdirection);CHKERRQ(ierr); 330 ierr = TaoComputeObjective(tao, tr->W, &ftrial);CHKERRQ(ierr); 331 332 if (PetscIsInfOrNanReal(ftrial)) { 333 tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d); 334 } else { 335 /* Compute and actual reduction */ 336 actred = f - ftrial; 337 prered = -prered; 338 if ((PetscAbsScalar(actred) <= tr->epsilon) && 339 (PetscAbsScalar(prered) <= tr->epsilon)) { 340 kappa = 1.0; 341 } 342 else { 343 kappa = actred / prered; 344 } 345 346 /* Accept or reject the step and update radius */ 347 if (kappa < tr->eta1) { 348 /* Reject the step */ 349 tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d); 350 } 351 else { 352 /* Accept the step */ 353 if (kappa < tr->eta2) { 354 /* Marginal bad step */ 355 tao->trust = tr->alpha2 * PetscMin(tao->trust, norm_d); 356 } 357 else if (kappa < tr->eta3) { 358 /* Reasonable step */ 359 tao->trust = tr->alpha3 * tao->trust; 360 } 361 else if (kappa < tr->eta4) { 362 /* Good step */ 363 tao->trust = PetscMax(tr->alpha4 * norm_d, tao->trust); 364 } 365 else { 366 /* Very good step */ 367 tao->trust = PetscMax(tr->alpha5 * norm_d, tao->trust); 368 } 369 break; 370 } 371 } 372 } 373 } 374 else { 375 /* Get predicted reduction */ 376 ierr = KSPCGGetObjFcn(tao->ksp,&prered);CHKERRQ(ierr); 377 if (prered >= 0.0) { 378 /* The predicted reduction has the wrong sign. This cannot 379 happen in infinite precision arithmetic. Step should 380 be rejected! */ 381 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d); 382 } 383 else { 384 ierr = VecCopy(tao->solution, tr->W);CHKERRQ(ierr); 385 ierr = VecAXPY(tr->W, 1.0, tao->stepdirection);CHKERRQ(ierr); 386 ierr = TaoComputeObjective(tao, tr->W, &ftrial);CHKERRQ(ierr); 387 if (PetscIsInfOrNanReal(ftrial)) { 388 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d); 389 } 390 else { 391 ierr = VecDot(tao->gradient, tao->stepdirection, &beta);CHKERRQ(ierr); 392 actred = f - ftrial; 393 prered = -prered; 394 if ((PetscAbsScalar(actred) <= tr->epsilon) && 395 (PetscAbsScalar(prered) <= tr->epsilon)) { 396 kappa = 1.0; 397 } 398 else { 399 kappa = actred / prered; 400 } 401 402 tau_1 = tr->theta * beta / (tr->theta * beta - (1.0 - tr->theta) * prered + actred); 403 tau_2 = tr->theta * beta / (tr->theta * beta + (1.0 + tr->theta) * prered - actred); 404 tau_min = PetscMin(tau_1, tau_2); 405 tau_max = PetscMax(tau_1, tau_2); 406 407 if (kappa >= 1.0 - tr->mu1) { 408 /* Great agreement; accept step and update radius */ 409 if (tau_max < 1.0) { 410 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d); 411 } 412 else if (tau_max > tr->gamma4) { 413 tao->trust = PetscMax(tao->trust, tr->gamma4 * norm_d); 414 } 415 else { 416 tao->trust = PetscMax(tao->trust, tau_max * norm_d); 417 } 418 break; 419 } 420 else if (kappa >= 1.0 - tr->mu2) { 421 /* Good agreement */ 422 423 if (tau_max < tr->gamma2) { 424 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d); 425 } 426 else if (tau_max > tr->gamma3) { 427 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d); 428 } 429 else if (tau_max < 1.0) { 430 tao->trust = tau_max * PetscMin(tao->trust, norm_d); 431 } 432 else { 433 tao->trust = PetscMax(tao->trust, tau_max * norm_d); 434 } 435 break; 436 } 437 else { 438 /* Not good agreement */ 439 if (tau_min > 1.0) { 440 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d); 441 } 442 else if (tau_max < tr->gamma1) { 443 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d); 444 } 445 else if ((tau_min < tr->gamma1) && (tau_max >= 1.0)) { 446 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d); 447 } 448 else if ((tau_1 >= tr->gamma1) && (tau_1 < 1.0) && 449 ((tau_2 < tr->gamma1) || (tau_2 >= 1.0))) { 450 tao->trust = tau_1 * PetscMin(tao->trust, norm_d); 451 } 452 else if ((tau_2 >= tr->gamma1) && (tau_2 < 1.0) && 453 ((tau_1 < tr->gamma1) || (tau_2 >= 1.0))) { 454 tao->trust = tau_2 * PetscMin(tao->trust, norm_d); 455 } 456 else { 457 tao->trust = tau_max * PetscMin(tao->trust, norm_d); 458 } 459 } 460 } 461 } 462 } 463 464 /* The step computed was not good and the radius was decreased. 465 Monitor the radius to terminate. */ 466 ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 467 ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,tao->trust);CHKERRQ(ierr); 468 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 469 } 470 471 /* The radius may have been increased; modify if it is too large */ 472 tao->trust = PetscMin(tao->trust, tr->max_radius); 473 474 if (tao->reason == TAO_CONTINUE_ITERATING) { 475 ierr = VecCopy(tr->W, tao->solution);CHKERRQ(ierr); 476 f = ftrial; 477 ierr = TaoComputeGradient(tao, tao->solution, tao->gradient);CHKERRQ(ierr); 478 ierr = TaoGradientNorm(tao, tao->gradient,NORM_2,&gnorm);CHKERRQ(ierr); 479 if (PetscIsInfOrNanReal(f) || PetscIsInfOrNanReal(gnorm)) SETERRQ(PETSC_COMM_SELF,1, "User provided compute function generated Inf or NaN"); 480 needH = 1; 481 ierr = TaoLogConvergenceHistory(tao,f,gnorm,0.0,tao->ksp_its);CHKERRQ(ierr); 482 ierr = TaoMonitor(tao,tao->niter,f,gnorm,0.0,tao->trust);CHKERRQ(ierr); 483 ierr = (*tao->ops->convergencetest)(tao,tao->cnvP);CHKERRQ(ierr); 484 } 485 } 486 PetscFunctionReturn(0); 487 } 488 489 /*------------------------------------------------------------*/ 490 static PetscErrorCode TaoSetUp_NTR(Tao tao) 491 { 492 TAO_NTR *tr = (TAO_NTR *)tao->data; 493 PetscErrorCode ierr; 494 495 PetscFunctionBegin; 496 if (!tao->gradient) {ierr = VecDuplicate(tao->solution, &tao->gradient);CHKERRQ(ierr);} 497 if (!tao->stepdirection) {ierr = VecDuplicate(tao->solution, &tao->stepdirection);CHKERRQ(ierr);} 498 if (!tr->W) {ierr = VecDuplicate(tao->solution, &tr->W);CHKERRQ(ierr);} 499 500 tr->bfgs_pre = 0; 501 tr->M = 0; 502 PetscFunctionReturn(0); 503 } 504 505 /*------------------------------------------------------------*/ 506 static PetscErrorCode TaoDestroy_NTR(Tao tao) 507 { 508 TAO_NTR *tr = (TAO_NTR *)tao->data; 509 PetscErrorCode ierr; 510 511 PetscFunctionBegin; 512 if (tao->setupcalled) { 513 ierr = VecDestroy(&tr->W);CHKERRQ(ierr); 514 } 515 ierr = PetscFree(tao->data);CHKERRQ(ierr); 516 PetscFunctionReturn(0); 517 } 518 519 /*------------------------------------------------------------*/ 520 static PetscErrorCode TaoSetFromOptions_NTR(PetscOptionItems *PetscOptionsObject,Tao tao) 521 { 522 TAO_NTR *tr = (TAO_NTR *)tao->data; 523 PetscErrorCode ierr; 524 525 PetscFunctionBegin; 526 ierr = PetscOptionsHead(PetscOptionsObject,"Newton trust region method for unconstrained optimization");CHKERRQ(ierr); 527 ierr = PetscOptionsEList("-tao_ntr_init_type", "tao->trust initialization type", "", NTR_INIT, NTR_INIT_TYPES, NTR_INIT[tr->init_type], &tr->init_type,NULL);CHKERRQ(ierr); 528 ierr = PetscOptionsEList("-tao_ntr_update_type", "radius update type", "", NTR_UPDATE, NTR_UPDATE_TYPES, NTR_UPDATE[tr->update_type], &tr->update_type,NULL);CHKERRQ(ierr); 529 ierr = PetscOptionsReal("-tao_ntr_eta1", "step is unsuccessful if actual reduction < eta1 * predicted reduction", "", tr->eta1, &tr->eta1,NULL);CHKERRQ(ierr); 530 ierr = PetscOptionsReal("-tao_ntr_eta2", "", "", tr->eta2, &tr->eta2,NULL);CHKERRQ(ierr); 531 ierr = PetscOptionsReal("-tao_ntr_eta3", "", "", tr->eta3, &tr->eta3,NULL);CHKERRQ(ierr); 532 ierr = PetscOptionsReal("-tao_ntr_eta4", "", "", tr->eta4, &tr->eta4,NULL);CHKERRQ(ierr); 533 ierr = PetscOptionsReal("-tao_ntr_alpha1", "", "", tr->alpha1, &tr->alpha1,NULL);CHKERRQ(ierr); 534 ierr = PetscOptionsReal("-tao_ntr_alpha2", "", "", tr->alpha2, &tr->alpha2,NULL);CHKERRQ(ierr); 535 ierr = PetscOptionsReal("-tao_ntr_alpha3", "", "", tr->alpha3, &tr->alpha3,NULL);CHKERRQ(ierr); 536 ierr = PetscOptionsReal("-tao_ntr_alpha4", "", "", tr->alpha4, &tr->alpha4,NULL);CHKERRQ(ierr); 537 ierr = PetscOptionsReal("-tao_ntr_alpha5", "", "", tr->alpha5, &tr->alpha5,NULL);CHKERRQ(ierr); 538 ierr = PetscOptionsReal("-tao_ntr_mu1", "", "", tr->mu1, &tr->mu1,NULL);CHKERRQ(ierr); 539 ierr = PetscOptionsReal("-tao_ntr_mu2", "", "", tr->mu2, &tr->mu2,NULL);CHKERRQ(ierr); 540 ierr = PetscOptionsReal("-tao_ntr_gamma1", "", "", tr->gamma1, &tr->gamma1,NULL);CHKERRQ(ierr); 541 ierr = PetscOptionsReal("-tao_ntr_gamma2", "", "", tr->gamma2, &tr->gamma2,NULL);CHKERRQ(ierr); 542 ierr = PetscOptionsReal("-tao_ntr_gamma3", "", "", tr->gamma3, &tr->gamma3,NULL);CHKERRQ(ierr); 543 ierr = PetscOptionsReal("-tao_ntr_gamma4", "", "", tr->gamma4, &tr->gamma4,NULL);CHKERRQ(ierr); 544 ierr = PetscOptionsReal("-tao_ntr_theta", "", "", tr->theta, &tr->theta,NULL);CHKERRQ(ierr); 545 ierr = PetscOptionsReal("-tao_ntr_mu1_i", "", "", tr->mu1_i, &tr->mu1_i,NULL);CHKERRQ(ierr); 546 ierr = PetscOptionsReal("-tao_ntr_mu2_i", "", "", tr->mu2_i, &tr->mu2_i,NULL);CHKERRQ(ierr); 547 ierr = PetscOptionsReal("-tao_ntr_gamma1_i", "", "", tr->gamma1_i, &tr->gamma1_i,NULL);CHKERRQ(ierr); 548 ierr = PetscOptionsReal("-tao_ntr_gamma2_i", "", "", tr->gamma2_i, &tr->gamma2_i,NULL);CHKERRQ(ierr); 549 ierr = PetscOptionsReal("-tao_ntr_gamma3_i", "", "", tr->gamma3_i, &tr->gamma3_i,NULL);CHKERRQ(ierr); 550 ierr = PetscOptionsReal("-tao_ntr_gamma4_i", "", "", tr->gamma4_i, &tr->gamma4_i,NULL);CHKERRQ(ierr); 551 ierr = PetscOptionsReal("-tao_ntr_theta_i", "", "", tr->theta_i, &tr->theta_i,NULL);CHKERRQ(ierr); 552 ierr = PetscOptionsReal("-tao_ntr_min_radius", "lower bound on initial trust-region radius", "", tr->min_radius, &tr->min_radius,NULL);CHKERRQ(ierr); 553 ierr = PetscOptionsReal("-tao_ntr_max_radius", "upper bound on trust-region radius", "", tr->max_radius, &tr->max_radius,NULL);CHKERRQ(ierr); 554 ierr = PetscOptionsReal("-tao_ntr_epsilon", "tolerance used when computing actual and predicted reduction", "", tr->epsilon, &tr->epsilon,NULL);CHKERRQ(ierr); 555 ierr = PetscOptionsTail();CHKERRQ(ierr); 556 ierr = KSPSetFromOptions(tao->ksp);CHKERRQ(ierr); 557 PetscFunctionReturn(0); 558 } 559 560 /*------------------------------------------------------------*/ 561 /*MC 562 TAONTR - Newton's method with trust region for unconstrained minimization. 563 At each iteration, the Newton trust region method solves the system. 564 NTR expects a KSP solver with a trust region radius. 565 min_d .5 dT Hk d + gkT d, s.t. ||d|| < Delta_k 566 567 Options Database Keys: 568 + -tao_ntr_init_type - "constant","direction","interpolation" 569 . -tao_ntr_update_type - "reduction","interpolation" 570 . -tao_ntr_min_radius - lower bound on trust region radius 571 . -tao_ntr_max_radius - upper bound on trust region radius 572 . -tao_ntr_epsilon - tolerance for accepting actual / predicted reduction 573 . -tao_ntr_mu1_i - mu1 interpolation init factor 574 . -tao_ntr_mu2_i - mu2 interpolation init factor 575 . -tao_ntr_gamma1_i - gamma1 interpolation init factor 576 . -tao_ntr_gamma2_i - gamma2 interpolation init factor 577 . -tao_ntr_gamma3_i - gamma3 interpolation init factor 578 . -tao_ntr_gamma4_i - gamma4 interpolation init factor 579 . -tao_ntr_theta_i - theta1 interpolation init factor 580 . -tao_ntr_eta1 - eta1 reduction update factor 581 . -tao_ntr_eta2 - eta2 reduction update factor 582 . -tao_ntr_eta3 - eta3 reduction update factor 583 . -tao_ntr_eta4 - eta4 reduction update factor 584 . -tao_ntr_alpha1 - alpha1 reduction update factor 585 . -tao_ntr_alpha2 - alpha2 reduction update factor 586 . -tao_ntr_alpha3 - alpha3 reduction update factor 587 . -tao_ntr_alpha4 - alpha4 reduction update factor 588 . -tao_ntr_alpha4 - alpha4 reduction update factor 589 . -tao_ntr_mu1 - mu1 interpolation update 590 . -tao_ntr_mu2 - mu2 interpolation update 591 . -tao_ntr_gamma1 - gamma1 interpolcation update 592 . -tao_ntr_gamma2 - gamma2 interpolcation update 593 . -tao_ntr_gamma3 - gamma3 interpolcation update 594 . -tao_ntr_gamma4 - gamma4 interpolation update 595 - -tao_ntr_theta - theta interpolation update 596 597 Level: beginner 598 M*/ 599 600 PETSC_EXTERN PetscErrorCode TaoCreate_NTR(Tao tao) 601 { 602 TAO_NTR *tr; 603 PetscErrorCode ierr; 604 605 PetscFunctionBegin; 606 607 ierr = PetscNewLog(tao,&tr);CHKERRQ(ierr); 608 609 tao->ops->setup = TaoSetUp_NTR; 610 tao->ops->solve = TaoSolve_NTR; 611 tao->ops->setfromoptions = TaoSetFromOptions_NTR; 612 tao->ops->destroy = TaoDestroy_NTR; 613 614 /* Override default settings (unless already changed) */ 615 if (!tao->max_it_changed) tao->max_it = 50; 616 if (!tao->trust0_changed) tao->trust0 = 100.0; 617 tao->data = (void*)tr; 618 619 /* Standard trust region update parameters */ 620 tr->eta1 = 1.0e-4; 621 tr->eta2 = 0.25; 622 tr->eta3 = 0.50; 623 tr->eta4 = 0.90; 624 625 tr->alpha1 = 0.25; 626 tr->alpha2 = 0.50; 627 tr->alpha3 = 1.00; 628 tr->alpha4 = 2.00; 629 tr->alpha5 = 4.00; 630 631 /* Interpolation trust region update parameters */ 632 tr->mu1 = 0.10; 633 tr->mu2 = 0.50; 634 635 tr->gamma1 = 0.25; 636 tr->gamma2 = 0.50; 637 tr->gamma3 = 2.00; 638 tr->gamma4 = 4.00; 639 640 tr->theta = 0.05; 641 642 /* Interpolation parameters for initialization */ 643 tr->mu1_i = 0.35; 644 tr->mu2_i = 0.50; 645 646 tr->gamma1_i = 0.0625; 647 tr->gamma2_i = 0.50; 648 tr->gamma3_i = 2.00; 649 tr->gamma4_i = 5.00; 650 651 tr->theta_i = 0.25; 652 653 tr->min_radius = 1.0e-10; 654 tr->max_radius = 1.0e10; 655 tr->epsilon = 1.0e-6; 656 657 tr->init_type = NTR_INIT_INTERPOLATION; 658 tr->update_type = NTR_UPDATE_REDUCTION; 659 660 /* Set linear solver to default for trust region */ 661 ierr = KSPCreate(((PetscObject)tao)->comm,&tao->ksp);CHKERRQ(ierr); 662 ierr = PetscObjectIncrementTabLevel((PetscObject)tao->ksp,(PetscObject)tao,1);CHKERRQ(ierr); 663 ierr = KSPSetOptionsPrefix(tao->ksp,tao->hdr.prefix);CHKERRQ(ierr); 664 ierr = KSPAppendOptionsPrefix(tao->ksp,"tao_ntr_");CHKERRQ(ierr); 665 ierr = KSPSetType(tao->ksp,KSPSTCG);CHKERRQ(ierr); 666 PetscFunctionReturn(0); 667 } 668