1*eb910715SAlp Dener /* 2*eb910715SAlp Dener Context for bounded Newton-Krylov type optimization algorithms 3*eb910715SAlp Dener */ 4*eb910715SAlp Dener 5*eb910715SAlp Dener #if !defined(__TAO_BNK_H) 6*eb910715SAlp Dener #define __TAO_BNK_H 7*eb910715SAlp Dener #include <petsc/private/taoimpl.h> 8*eb910715SAlp Dener #include <../src/tao/matrix/lmvmmat.h> 9*eb910715SAlp Dener 10*eb910715SAlp Dener typedef struct { 11*eb910715SAlp Dener Mat M; 12*eb910715SAlp Dener 13*eb910715SAlp Dener Vec D; 14*eb910715SAlp Dener Vec W; 15*eb910715SAlp Dener 16*eb910715SAlp Dener Vec Xold; 17*eb910715SAlp Dener Vec Gold; 18*eb910715SAlp Dener Vec Diag; 19*eb910715SAlp Dener 20*eb910715SAlp Dener /* Scalar values for the solution */ 21*eb910715SAlp Dener PetscReal f, gnorm; 22*eb910715SAlp Dener 23*eb910715SAlp Dener /* Parameters when updating the perturbation added to the Hessian matrix 24*eb910715SAlp Dener according to the following scheme: 25*eb910715SAlp Dener 26*eb910715SAlp Dener pert = sval; 27*eb910715SAlp Dener 28*eb910715SAlp Dener do until convergence 29*eb910715SAlp Dener shift Hessian by pert 30*eb910715SAlp Dener solve Newton system 31*eb910715SAlp Dener 32*eb910715SAlp Dener if (linear solver failed or did not compute a descent direction) 33*eb910715SAlp Dener use steepest descent direction and increase perturbation 34*eb910715SAlp Dener 35*eb910715SAlp Dener if (0 == pert) 36*eb910715SAlp Dener initialize perturbation 37*eb910715SAlp Dener pert = min(imax, max(imin, imfac * norm(G))) 38*eb910715SAlp Dener else 39*eb910715SAlp Dener increase perturbation 40*eb910715SAlp Dener pert = min(pmax, max(pgfac * pert, pmgfac * norm(G))) 41*eb910715SAlp Dener fi 42*eb910715SAlp Dener else 43*eb910715SAlp Dener use linear solver direction and decrease perturbation 44*eb910715SAlp Dener 45*eb910715SAlp Dener pert = min(psfac * pert, pmsfac * norm(G)) 46*eb910715SAlp Dener if (pert < pmin) 47*eb910715SAlp Dener pert = 0 48*eb910715SAlp Dener fi 49*eb910715SAlp Dener fi 50*eb910715SAlp Dener 51*eb910715SAlp Dener perform line search 52*eb910715SAlp Dener function and gradient evaluation 53*eb910715SAlp Dener check convergence 54*eb910715SAlp Dener od 55*eb910715SAlp Dener */ 56*eb910715SAlp Dener PetscReal sval; /* Starting perturbation value, default zero */ 57*eb910715SAlp Dener 58*eb910715SAlp Dener PetscReal imin; /* Minimum perturbation added during initialization */ 59*eb910715SAlp Dener PetscReal imax; /* Maximum perturbation added during initialization */ 60*eb910715SAlp Dener PetscReal imfac; /* Merit function factor during initialization */ 61*eb910715SAlp Dener 62*eb910715SAlp Dener PetscReal pert; /* Current perturbation value */ 63*eb910715SAlp Dener PetscReal pmin; /* Minimim perturbation value */ 64*eb910715SAlp Dener PetscReal pmax; /* Maximum perturbation value */ 65*eb910715SAlp Dener PetscReal pgfac; /* Perturbation growth factor */ 66*eb910715SAlp Dener PetscReal psfac; /* Perturbation shrink factor */ 67*eb910715SAlp Dener PetscReal pmgfac; /* Merit function growth factor */ 68*eb910715SAlp Dener PetscReal pmsfac; /* Merit function shrink factor */ 69*eb910715SAlp Dener 70*eb910715SAlp Dener /* Parameters when updating the trust-region radius based on steplength 71*eb910715SAlp Dener if step < nu1 (very bad step) 72*eb910715SAlp Dener radius = omega1 * min(norm(d), radius) 73*eb910715SAlp Dener elif step < nu2 (bad step) 74*eb910715SAlp Dener radius = omega2 * min(norm(d), radius) 75*eb910715SAlp Dener elif step < nu3 (okay step) 76*eb910715SAlp Dener radius = omega3 * radius; 77*eb910715SAlp Dener elif step < nu4 (good step) 78*eb910715SAlp Dener radius = max(omega4 * norm(d), radius) 79*eb910715SAlp Dener else (very good step) 80*eb910715SAlp Dener radius = max(omega5 * norm(d), radius) 81*eb910715SAlp Dener fi 82*eb910715SAlp Dener */ 83*eb910715SAlp Dener PetscReal nu1; /* used to compute trust-region radius */ 84*eb910715SAlp Dener PetscReal nu2; /* used to compute trust-region radius */ 85*eb910715SAlp Dener PetscReal nu3; /* used to compute trust-region radius */ 86*eb910715SAlp Dener PetscReal nu4; /* used to compute trust-region radius */ 87*eb910715SAlp Dener 88*eb910715SAlp Dener PetscReal omega1; /* factor used for trust-region update */ 89*eb910715SAlp Dener PetscReal omega2; /* factor used for trust-region update */ 90*eb910715SAlp Dener PetscReal omega3; /* factor used for trust-region update */ 91*eb910715SAlp Dener PetscReal omega4; /* factor used for trust-region update */ 92*eb910715SAlp Dener PetscReal omega5; /* factor used for trust-region update */ 93*eb910715SAlp Dener 94*eb910715SAlp Dener /* Parameters when updating the trust-region radius based on reduction 95*eb910715SAlp Dener 96*eb910715SAlp Dener kappa = ared / pred 97*eb910715SAlp Dener if kappa < eta1 (very bad step) 98*eb910715SAlp Dener radius = alpha1 * min(norm(d), radius) 99*eb910715SAlp Dener elif kappa < eta2 (bad step) 100*eb910715SAlp Dener radius = alpha2 * min(norm(d), radius) 101*eb910715SAlp Dener elif kappa < eta3 (okay step) 102*eb910715SAlp Dener radius = alpha3 * radius; 103*eb910715SAlp Dener elif kappa < eta4 (good step) 104*eb910715SAlp Dener radius = max(alpha4 * norm(d), radius) 105*eb910715SAlp Dener else (very good step) 106*eb910715SAlp Dener radius = max(alpha5 * norm(d), radius) 107*eb910715SAlp Dener fi 108*eb910715SAlp Dener */ 109*eb910715SAlp Dener PetscReal eta1; /* used to compute trust-region radius */ 110*eb910715SAlp Dener PetscReal eta2; /* used to compute trust-region radius */ 111*eb910715SAlp Dener PetscReal eta3; /* used to compute trust-region radius */ 112*eb910715SAlp Dener PetscReal eta4; /* used to compute trust-region radius */ 113*eb910715SAlp Dener 114*eb910715SAlp Dener PetscReal alpha1; /* factor used for trust-region update */ 115*eb910715SAlp Dener PetscReal alpha2; /* factor used for trust-region update */ 116*eb910715SAlp Dener PetscReal alpha3; /* factor used for trust-region update */ 117*eb910715SAlp Dener PetscReal alpha4; /* factor used for trust-region update */ 118*eb910715SAlp Dener PetscReal alpha5; /* factor used for trust-region update */ 119*eb910715SAlp Dener 120*eb910715SAlp Dener /* Parameters when updating the trust-region radius based on interpolation 121*eb910715SAlp Dener 122*eb910715SAlp Dener kappa = ared / pred 123*eb910715SAlp Dener if kappa >= 1.0 - mu1 (very good step) 124*eb910715SAlp Dener choose tau in [gamma3, gamma4] 125*eb910715SAlp Dener radius = max(tau * norm(d), radius) 126*eb910715SAlp Dener elif kappa >= 1.0 - mu2 (good step) 127*eb910715SAlp Dener choose tau in [gamma2, gamma3] 128*eb910715SAlp Dener if (tau >= 1.0) 129*eb910715SAlp Dener radius = max(tau * norm(d), radius) 130*eb910715SAlp Dener else 131*eb910715SAlp Dener radius = tau * min(norm(d), radius) 132*eb910715SAlp Dener fi 133*eb910715SAlp Dener else (bad step) 134*eb910715SAlp Dener choose tau in [gamma1, 1.0] 135*eb910715SAlp Dener radius = tau * min(norm(d), radius) 136*eb910715SAlp Dener fi 137*eb910715SAlp Dener */ 138*eb910715SAlp Dener PetscReal mu1; /* used for model agreement in interpolation */ 139*eb910715SAlp Dener PetscReal mu2; /* used for model agreement in interpolation */ 140*eb910715SAlp Dener 141*eb910715SAlp Dener PetscReal gamma1; /* factor used for interpolation */ 142*eb910715SAlp Dener PetscReal gamma2; /* factor used for interpolation */ 143*eb910715SAlp Dener PetscReal gamma3; /* factor used for interpolation */ 144*eb910715SAlp Dener PetscReal gamma4; /* factor used for interpolation */ 145*eb910715SAlp Dener 146*eb910715SAlp Dener PetscReal theta; /* factor used for interpolation */ 147*eb910715SAlp Dener 148*eb910715SAlp Dener /* Parameters when initializing trust-region radius based on interpolation */ 149*eb910715SAlp Dener PetscReal mu1_i; /* used for model agreement in interpolation */ 150*eb910715SAlp Dener PetscReal mu2_i; /* used for model agreement in interpolation */ 151*eb910715SAlp Dener 152*eb910715SAlp Dener PetscReal gamma1_i; /* factor used for interpolation */ 153*eb910715SAlp Dener PetscReal gamma2_i; /* factor used for interpolation */ 154*eb910715SAlp Dener PetscReal gamma3_i; /* factor used for interpolation */ 155*eb910715SAlp Dener PetscReal gamma4_i; /* factor used for interpolation */ 156*eb910715SAlp Dener 157*eb910715SAlp Dener PetscReal theta_i; /* factor used for interpolation */ 158*eb910715SAlp Dener 159*eb910715SAlp Dener /* Other parameters */ 160*eb910715SAlp Dener PetscReal min_radius; /* lower bound on initial radius value */ 161*eb910715SAlp Dener PetscReal max_radius; /* upper bound on trust region radius */ 162*eb910715SAlp Dener PetscReal epsilon; /* tolerance used when computing ared/pred */ 163*eb910715SAlp Dener 164*eb910715SAlp Dener PetscInt newt; /* Newton directions attempted */ 165*eb910715SAlp Dener PetscInt bfgs; /* BFGS directions attempted */ 166*eb910715SAlp Dener PetscInt sgrad; /* Scaled gradient directions attempted */ 167*eb910715SAlp Dener PetscInt grad; /* Gradient directions attempted */ 168*eb910715SAlp Dener 169*eb910715SAlp Dener PetscInt pc_type; /* Preconditioner for the code */ 170*eb910715SAlp Dener PetscInt bfgs_scale_type; /* Scaling matrix to used for the bfgs preconditioner */ 171*eb910715SAlp Dener PetscInt init_type; /* Trust-region initialization method */ 172*eb910715SAlp Dener PetscInt update_type; /* Trust-region update method */ 173*eb910715SAlp Dener 174*eb910715SAlp Dener PetscInt ksp_atol; 175*eb910715SAlp Dener PetscInt ksp_rtol; 176*eb910715SAlp Dener PetscInt ksp_ctol; 177*eb910715SAlp Dener PetscInt ksp_negc; 178*eb910715SAlp Dener PetscInt ksp_dtol; 179*eb910715SAlp Dener PetscInt ksp_iter; 180*eb910715SAlp Dener PetscInt ksp_othr; 181*eb910715SAlp Dener PetscBool is_nash, is_stcg, is_gltr; 182*eb910715SAlp Dener } TAO_BNK; 183*eb910715SAlp Dener 184*eb910715SAlp Dener #endif /* if !defined(__TAO_BNK_H) */ 185*eb910715SAlp Dener 186*eb910715SAlp Dener #define BNK_NEWTON 0 187*eb910715SAlp Dener #define BNK_BFGS 1 188*eb910715SAlp Dener #define BNK_SCALED_GRADIENT 2 189*eb910715SAlp Dener #define BNK_GRADIENT 3 190*eb910715SAlp Dener 191*eb910715SAlp Dener #define BNK_PC_NONE 0 192*eb910715SAlp Dener #define BNK_PC_AHESS 1 193*eb910715SAlp Dener #define BNK_PC_BFGS 2 194*eb910715SAlp Dener #define BNK_PC_PETSC 3 195*eb910715SAlp Dener #define BNK_PC_TYPES 4 196*eb910715SAlp Dener 197*eb910715SAlp Dener #define BFGS_SCALE_AHESS 0 198*eb910715SAlp Dener #define BFGS_SCALE_PHESS 1 199*eb910715SAlp Dener #define BFGS_SCALE_BFGS 2 200*eb910715SAlp Dener #define BFGS_SCALE_TYPES 3 201*eb910715SAlp Dener 202*eb910715SAlp Dener #define BNK_INIT_CONSTANT 0 203*eb910715SAlp Dener #define BNK_INIT_DIRECTION 1 204*eb910715SAlp Dener #define BNK_INIT_INTERPOLATION 2 205*eb910715SAlp Dener #define BNK_INIT_TYPES 3 206*eb910715SAlp Dener 207*eb910715SAlp Dener #define BNK_UPDATE_STEP 0 208*eb910715SAlp Dener #define BNK_UPDATE_REDUCTION 1 209*eb910715SAlp Dener #define BNK_UPDATE_INTERPOLATION 2 210*eb910715SAlp Dener #define BNK_UPDATE_TYPES 3 211*eb910715SAlp Dener 212*eb910715SAlp Dener static const char *BNK_PC[64] = {"none", "ahess", "bfgs", "petsc"}; 213*eb910715SAlp Dener 214*eb910715SAlp Dener static const char *BFGS_SCALE[64] = {"ahess", "phess", "bfgs"}; 215*eb910715SAlp Dener 216*eb910715SAlp Dener static const char *BNK_INIT[64] = {"constant", "direction", "interpolation"}; 217*eb910715SAlp Dener 218*eb910715SAlp Dener static const char *BNK_UPDATE[64] = {"step", "reduction", "interpolation"}; 219*eb910715SAlp Dener 220*eb910715SAlp Dener PETSC_INTERN PetscErrorCode TaoCreate_BNK(Tao); 221*eb910715SAlp Dener 222*eb910715SAlp Dener PETSC_INTERN PetscErrorCode MatLMVMSolveShell(PC, Vec, Vec); 223*eb910715SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKInitialize(Tao); 224*eb910715SAlp Dener PETSC_INTERN PetscErrorCode TaoBNKComputeStep(Tao, PetscInt*);