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