xref: /petsc/src/tao/bound/impls/bnk/bnk.h (revision eb9107154965f6d42900b472f8cc894abc73f56d)
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*);