1eb910715SAlp Dener /* 2eb910715SAlp Dener Context for bounded Newton-Krylov type optimization algorithms 3eb910715SAlp Dener */ 4eb910715SAlp Dener 5a4963045SJacob Faibussowitsch #pragma once 6eb910715SAlp Dener #include <petsc/private/taoimpl.h> 7c0f10754SAlp Dener #include <../src/tao/bound/impls/bncg/bncg.h> 8eb910715SAlp Dener 9eb910715SAlp Dener typedef struct { 10e0ed867bSAlp Dener /* Function pointer for hessian evaluation 11e0ed867bSAlp Dener NOTE: This is necessary so that quasi-Newton-Krylov methods can "evaluate" 12e0ed867bSAlp Dener a quasi-Newton approximation while full Newton-Krylov methods call-back to 13e0ed867bSAlp Dener the application's Hessian */ 14e0ed867bSAlp Dener PetscErrorCode (*computehessian)(Tao); 156b591159SAlp Dener PetscErrorCode (*computestep)(Tao, PetscBool, KSPConvergedReason *, PetscInt *); 16e0ed867bSAlp Dener 17c0f10754SAlp Dener /* Embedded TAOBNCG */ 18c0f10754SAlp Dener Tao bncg; 19c0f10754SAlp Dener TAO_BNCG *bncg_ctx; 20e031d6f5SAlp Dener PetscInt max_cg_its, tot_cg_its; 21c0f10754SAlp Dener Vec bncg_sol; 22c0f10754SAlp Dener 23c0f10754SAlp Dener /* Allocated vectors */ 24c0f10754SAlp Dener Vec W, Xwork, Gwork, Xold, Gold; 2509164190SAlp Dener Vec unprojected_gradient, unprojected_gradient_old; 26c0f10754SAlp Dener 27c0f10754SAlp Dener /* Unallocated matrices and vectors */ 28b9ac7092SAlp Dener Mat H_inactive, Hpre_inactive; 29b9ac7092SAlp Dener Vec X_inactive, G_inactive, inactive_work, active_work; 302f75a4aaSAlp Dener IS inactive_idx, active_idx, active_lower, active_upper, active_fixed; 31eb910715SAlp Dener 32080d2917SAlp Dener /* Scalar values for the solution and step */ 33080d2917SAlp Dener PetscReal fold, f, gnorm, dnorm; 34eb910715SAlp Dener 352f75a4aaSAlp Dener /* Parameters for active set estimation */ 360a4511e9SAlp Dener PetscReal as_tol; 370a4511e9SAlp Dener PetscReal as_step; 382f75a4aaSAlp Dener 39b9ac7092SAlp Dener /* BFGS preconditioner data */ 40b9ac7092SAlp Dener PC bfgs_pre; 41b9ac7092SAlp Dener Mat M; 42b9ac7092SAlp Dener Vec Diag_min, Diag_max; 43b9ac7092SAlp Dener 44eb910715SAlp Dener /* Parameters when updating the perturbation added to the Hessian matrix 45eb910715SAlp Dener according to the following scheme: 46eb910715SAlp Dener 47eb910715SAlp Dener pert = sval; 48eb910715SAlp Dener 49eb910715SAlp Dener do until convergence 50eb910715SAlp Dener shift Hessian by pert 51eb910715SAlp Dener solve Newton system 52eb910715SAlp Dener 53eb910715SAlp Dener if (linear solver failed or did not compute a descent direction) 54eb910715SAlp Dener use steepest descent direction and increase perturbation 55eb910715SAlp Dener 56eb910715SAlp Dener if (0 == pert) 57eb910715SAlp Dener initialize perturbation 58eb910715SAlp Dener pert = min(imax, max(imin, imfac * norm(G))) 59eb910715SAlp Dener else 60eb910715SAlp Dener increase perturbation 61eb910715SAlp Dener pert = min(pmax, max(pgfac * pert, pmgfac * norm(G))) 62eb910715SAlp Dener fi 63eb910715SAlp Dener else 64eb910715SAlp Dener use linear solver direction and decrease perturbation 65eb910715SAlp Dener 66eb910715SAlp Dener pert = min(psfac * pert, pmsfac * norm(G)) 67eb910715SAlp Dener if (pert < pmin) 68eb910715SAlp Dener pert = 0 69eb910715SAlp Dener fi 70eb910715SAlp Dener fi 71eb910715SAlp Dener 72eb910715SAlp Dener perform line search 73eb910715SAlp Dener function and gradient evaluation 74eb910715SAlp Dener check convergence 75eb910715SAlp Dener od 76eb910715SAlp Dener */ 77eb910715SAlp Dener PetscReal sval; /* Starting perturbation value, default zero */ 78eb910715SAlp Dener 79eb910715SAlp Dener PetscReal imin; /* Minimum perturbation added during initialization */ 80eb910715SAlp Dener PetscReal imax; /* Maximum perturbation added during initialization */ 81eb910715SAlp Dener PetscReal imfac; /* Merit function factor during initialization */ 82eb910715SAlp Dener 83eb910715SAlp Dener PetscReal pert; /* Current perturbation value */ 8435cb6cd3SPierre Jolivet PetscReal pmin; /* Minimum perturbation value */ 85eb910715SAlp Dener PetscReal pmax; /* Maximum perturbation value */ 86eb910715SAlp Dener PetscReal pgfac; /* Perturbation growth factor */ 87eb910715SAlp Dener PetscReal psfac; /* Perturbation shrink factor */ 88eb910715SAlp Dener PetscReal pmgfac; /* Merit function growth factor */ 89eb910715SAlp Dener PetscReal pmsfac; /* Merit function shrink factor */ 90eb910715SAlp Dener 91eb910715SAlp Dener /* Parameters when updating the trust-region radius based on steplength 92eb910715SAlp Dener if step < nu1 (very bad step) 93eb910715SAlp Dener radius = omega1 * min(norm(d), radius) 94eb910715SAlp Dener elif step < nu2 (bad step) 95eb910715SAlp Dener radius = omega2 * min(norm(d), radius) 96eb910715SAlp Dener elif step < nu3 (okay step) 97eb910715SAlp Dener radius = omega3 * radius; 98eb910715SAlp Dener elif step < nu4 (good step) 99eb910715SAlp Dener radius = max(omega4 * norm(d), radius) 100eb910715SAlp Dener else (very good step) 101eb910715SAlp Dener radius = max(omega5 * norm(d), radius) 102eb910715SAlp Dener fi 103eb910715SAlp Dener */ 104eb910715SAlp Dener PetscReal nu1; /* used to compute trust-region radius */ 105eb910715SAlp Dener PetscReal nu2; /* used to compute trust-region radius */ 106eb910715SAlp Dener PetscReal nu3; /* used to compute trust-region radius */ 107eb910715SAlp Dener PetscReal nu4; /* used to compute trust-region radius */ 108eb910715SAlp Dener 109eb910715SAlp Dener PetscReal omega1; /* factor used for trust-region update */ 110eb910715SAlp Dener PetscReal omega2; /* factor used for trust-region update */ 111eb910715SAlp Dener PetscReal omega3; /* factor used for trust-region update */ 112eb910715SAlp Dener PetscReal omega4; /* factor used for trust-region update */ 113eb910715SAlp Dener PetscReal omega5; /* factor used for trust-region update */ 114eb910715SAlp Dener 115eb910715SAlp Dener /* Parameters when updating the trust-region radius based on reduction 116eb910715SAlp Dener 117eb910715SAlp Dener kappa = ared / pred 118eb910715SAlp Dener if kappa < eta1 (very bad step) 119eb910715SAlp Dener radius = alpha1 * min(norm(d), radius) 120eb910715SAlp Dener elif kappa < eta2 (bad step) 121eb910715SAlp Dener radius = alpha2 * min(norm(d), radius) 122eb910715SAlp Dener elif kappa < eta3 (okay step) 123eb910715SAlp Dener radius = alpha3 * radius; 124eb910715SAlp Dener elif kappa < eta4 (good step) 125eb910715SAlp Dener radius = max(alpha4 * norm(d), radius) 126eb910715SAlp Dener else (very good step) 127eb910715SAlp Dener radius = max(alpha5 * norm(d), radius) 128eb910715SAlp Dener fi 129eb910715SAlp Dener */ 130eb910715SAlp Dener PetscReal eta1; /* used to compute trust-region radius */ 131eb910715SAlp Dener PetscReal eta2; /* used to compute trust-region radius */ 132eb910715SAlp Dener PetscReal eta3; /* used to compute trust-region radius */ 133eb910715SAlp Dener PetscReal eta4; /* used to compute trust-region radius */ 134eb910715SAlp Dener 135eb910715SAlp Dener PetscReal alpha1; /* factor used for trust-region update */ 136eb910715SAlp Dener PetscReal alpha2; /* factor used for trust-region update */ 137eb910715SAlp Dener PetscReal alpha3; /* factor used for trust-region update */ 138eb910715SAlp Dener PetscReal alpha4; /* factor used for trust-region update */ 139eb910715SAlp Dener PetscReal alpha5; /* factor used for trust-region update */ 140eb910715SAlp Dener 141eb910715SAlp Dener /* Parameters when updating the trust-region radius based on interpolation 142eb910715SAlp Dener 143eb910715SAlp Dener kappa = ared / pred 144eb910715SAlp Dener if kappa >= 1.0 - mu1 (very good step) 145eb910715SAlp Dener choose tau in [gamma3, gamma4] 146eb910715SAlp Dener radius = max(tau * norm(d), radius) 147eb910715SAlp Dener elif kappa >= 1.0 - mu2 (good step) 148eb910715SAlp Dener choose tau in [gamma2, gamma3] 149eb910715SAlp Dener if (tau >= 1.0) 150eb910715SAlp Dener radius = max(tau * norm(d), radius) 151eb910715SAlp Dener else 152eb910715SAlp Dener radius = tau * min(norm(d), radius) 153eb910715SAlp Dener fi 154eb910715SAlp Dener else (bad step) 155eb910715SAlp Dener choose tau in [gamma1, 1.0] 156eb910715SAlp Dener radius = tau * min(norm(d), radius) 157eb910715SAlp Dener fi 158eb910715SAlp Dener */ 159eb910715SAlp Dener PetscReal mu1; /* used for model agreement in interpolation */ 160eb910715SAlp Dener PetscReal mu2; /* used for model agreement in interpolation */ 161eb910715SAlp Dener 162eb910715SAlp Dener PetscReal gamma1; /* factor used for interpolation */ 163eb910715SAlp Dener PetscReal gamma2; /* factor used for interpolation */ 164eb910715SAlp Dener PetscReal gamma3; /* factor used for interpolation */ 165eb910715SAlp Dener PetscReal gamma4; /* factor used for interpolation */ 166eb910715SAlp Dener 167eb910715SAlp Dener PetscReal theta; /* factor used for interpolation */ 168eb910715SAlp Dener 169eb910715SAlp Dener /* Parameters when initializing trust-region radius based on interpolation */ 170eb910715SAlp Dener PetscReal mu1_i; /* used for model agreement in interpolation */ 171eb910715SAlp Dener PetscReal mu2_i; /* used for model agreement in interpolation */ 172eb910715SAlp Dener 173eb910715SAlp Dener PetscReal gamma1_i; /* factor used for interpolation */ 174eb910715SAlp Dener PetscReal gamma2_i; /* factor used for interpolation */ 175eb910715SAlp Dener PetscReal gamma3_i; /* factor used for interpolation */ 176eb910715SAlp Dener PetscReal gamma4_i; /* factor used for interpolation */ 177eb910715SAlp Dener 178eb910715SAlp Dener PetscReal theta_i; /* factor used for interpolation */ 179eb910715SAlp Dener 180eb910715SAlp Dener /* Other parameters */ 181eb910715SAlp Dener PetscReal min_radius; /* lower bound on initial radius value */ 182eb910715SAlp Dener PetscReal max_radius; /* upper bound on trust region radius */ 183eb910715SAlp Dener PetscReal epsilon; /* tolerance used when computing ared/pred */ 18462675beeSAlp Dener PetscReal dmin, dmax; /* upper and lower bounds for the Hessian diagonal vector */ 185eb910715SAlp Dener 186eb910715SAlp Dener PetscInt newt; /* Newton directions attempted */ 187eb910715SAlp Dener PetscInt bfgs; /* BFGS directions attempted */ 188eb910715SAlp Dener PetscInt sgrad; /* Scaled gradient directions attempted */ 189eb910715SAlp Dener PetscInt grad; /* Gradient directions attempted */ 190eb910715SAlp Dener 19162675beeSAlp Dener PetscInt as_type; /* Active set estimation method */ 192eb910715SAlp Dener PetscInt bfgs_scale_type; /* Scaling matrix to used for the bfgs preconditioner */ 193eb910715SAlp Dener PetscInt init_type; /* Trust-region initialization method */ 194eb910715SAlp Dener PetscInt update_type; /* Trust-region update method */ 195eb910715SAlp Dener 1962f75a4aaSAlp Dener /* Trackers for KSP solution type and convergence reasons */ 197eb910715SAlp Dener PetscInt ksp_atol; 198eb910715SAlp Dener PetscInt ksp_rtol; 199eb910715SAlp Dener PetscInt ksp_ctol; 200eb910715SAlp Dener PetscInt ksp_negc; 201eb910715SAlp Dener PetscInt ksp_dtol; 202eb910715SAlp Dener PetscInt ksp_iter; 203eb910715SAlp Dener PetscInt ksp_othr; 204f4db9bf7SStefano Zampini PetscBool resetksp; 205e0ed867bSAlp Dener 206e0ed867bSAlp Dener /* Implementation specific context */ 207*2a8381b2SBarry Smith PetscCtx ctx; 208eb910715SAlp Dener } TAO_BNK; 209eb910715SAlp Dener 210eb910715SAlp Dener #define BNK_NEWTON 0 211eb910715SAlp Dener #define BNK_BFGS 1 212eb910715SAlp Dener #define BNK_SCALED_GRADIENT 2 213eb910715SAlp Dener #define BNK_GRADIENT 3 214eb910715SAlp Dener 215eb910715SAlp Dener #define BNK_INIT_CONSTANT 0 216eb910715SAlp Dener #define BNK_INIT_DIRECTION 1 217eb910715SAlp Dener #define BNK_INIT_INTERPOLATION 2 218eb910715SAlp Dener #define BNK_INIT_TYPES 3 219eb910715SAlp Dener 220eb910715SAlp Dener #define BNK_UPDATE_STEP 0 221eb910715SAlp Dener #define BNK_UPDATE_REDUCTION 1 222eb910715SAlp Dener #define BNK_UPDATE_INTERPOLATION 2 223eb910715SAlp Dener #define BNK_UPDATE_TYPES 3 224eb910715SAlp Dener 2252f75a4aaSAlp Dener #define BNK_AS_NONE 0 2262f75a4aaSAlp Dener #define BNK_AS_BERTSEKAS 1 2272f75a4aaSAlp Dener #define BNK_AS_TYPES 2 2282f75a4aaSAlp Dener 229eb910715SAlp Dener PETSC_INTERN PetscErrorCode TaoCreate_BNK(Tao); 2309b6ef848SAlp Dener PETSC_INTERN PetscErrorCode TaoSetUp_BNK(Tao); 231ce78bad3SBarry Smith PETSC_INTERN PetscErrorCode TaoSetFromOptions_BNK(Tao, PetscOptionItems); 232e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoDestroy_BNK(Tao); 233e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoView_BNK(Tao, PetscViewer); 234e0ed867bSAlp Dener 235e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoSolve_BNLS(Tao); 236e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoSolve_BNTR(Tao); 237e0ed867bSAlp Dener PETSC_INTERN PetscErrorCode TaoSolve_BNTL(Tao); 238eb910715SAlp Dener 239cd929ea3SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKPreconBFGS(PC, Vec, Vec); 240c0f10754SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKInitialize(Tao, PetscInt, PetscBool *); 24108752603SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKEstimateActiveSet(Tao, PetscInt); 24262675beeSAlp Dener PETSC_INTERN PetscErrorCode TaoBNKComputeHessian(Tao); 243a1318120SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKBoundStep(Tao, PetscInt, Vec); 244c0f10754SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKTakeCGSteps(Tao, PetscBool *); 2456b591159SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKComputeStep(Tao, PetscBool, KSPConvergedReason *, PetscInt *); 2465e9b73cbSAlp Dener PETSC_INTERN PetscErrorCode TaoBNKRecomputePred(Tao, Vec, PetscReal *); 247e465cd6fSAlp Dener PETSC_INTERN PetscErrorCode TaoBNKSafeguardStep(Tao, KSPConvergedReason, PetscInt *); 248937a31a1SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKPerformLineSearch(Tao, PetscInt *, PetscReal *, TaoLineSearchConvergedReason *); 24928017e9fSAlp Dener PETSC_INTERN PetscErrorCode TaoBNKUpdateTrustRadius(Tao, PetscReal, PetscReal, PetscInt, PetscInt, PetscBool *); 25062675beeSAlp Dener PETSC_INTERN PetscErrorCode TaoBNKAddStepCounts(Tao, PetscInt); 251