xref: /petsc/src/tao/unconstrained/impls/ntr/ntr.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
1fb90e4d1STodd Munson #include <../src/tao/unconstrained/impls/ntr/ntrimpl.h>
2a7e14dcfSSatish Balay 
3aaa7dc30SBarry Smith #include <petscksp.h>
4a7e14dcfSSatish Balay 
5a7e14dcfSSatish Balay #define NTR_INIT_CONSTANT      0
6a7e14dcfSSatish Balay #define NTR_INIT_DIRECTION     1
7a7e14dcfSSatish Balay #define NTR_INIT_INTERPOLATION 2
8a7e14dcfSSatish Balay #define NTR_INIT_TYPES         3
9a7e14dcfSSatish Balay 
10a7e14dcfSSatish Balay #define NTR_UPDATE_REDUCTION     0
11a7e14dcfSSatish Balay #define NTR_UPDATE_INTERPOLATION 1
12a7e14dcfSSatish Balay #define NTR_UPDATE_TYPES         2
13a7e14dcfSSatish Balay 
1453506e15SBarry Smith static const char *NTR_INIT[64] = {"constant", "direction", "interpolation"};
15a7e14dcfSSatish Balay 
1653506e15SBarry Smith static const char *NTR_UPDATE[64] = {"reduction", "interpolation"};
17a7e14dcfSSatish Balay 
18a7e14dcfSSatish Balay /*
19a7e14dcfSSatish Balay    TaoSolve_NTR - Implements Newton's Method with a trust region approach
20a7e14dcfSSatish Balay    for solving unconstrained minimization problems.
21a7e14dcfSSatish Balay 
22a7e14dcfSSatish Balay    The basic algorithm is taken from MINPACK-2 (dstrn).
23a7e14dcfSSatish Balay 
24a7e14dcfSSatish Balay    TaoSolve_NTR computes a local minimizer of a twice differentiable function
25a7e14dcfSSatish Balay    f by applying a trust region variant of Newton's method.  At each stage
26a7e14dcfSSatish Balay    of the algorithm, we use the prconditioned conjugate gradient method to
27a7e14dcfSSatish Balay    determine an approximate minimizer of the quadratic equation
28a7e14dcfSSatish Balay 
29a7e14dcfSSatish Balay         q(s) = <s, Hs + g>
30a7e14dcfSSatish Balay 
31a7e14dcfSSatish Balay    subject to the trust region constraint
32a7e14dcfSSatish Balay 
33a7e14dcfSSatish Balay         || s ||_M <= radius,
34a7e14dcfSSatish Balay 
35a7e14dcfSSatish Balay    where radius is the trust region radius and M is a symmetric positive
36a7e14dcfSSatish Balay    definite matrix (the preconditioner).  Here g is the gradient and H
37a7e14dcfSSatish Balay    is the Hessian matrix.
38a7e14dcfSSatish Balay 
3905de396fSBarry Smith    Note:  TaoSolve_NTR MUST use the iterative solver KSPNASH, KSPSTCG,
4005de396fSBarry Smith           or KSPGLTR.  Thus, we set KSPNASH, KSPSTCG, or KSPGLTR in this
41a7e14dcfSSatish Balay           routine regardless of what the user may have previously specified.
42a7e14dcfSSatish Balay */
43*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSolve_NTR(Tao tao)
44*d71ae5a4SJacob Faibussowitsch {
45a7e14dcfSSatish Balay   TAO_NTR           *tr = (TAO_NTR *)tao->data;
46fb90e4d1STodd Munson   KSPType            ksp_type;
470ad3a497SAlp Dener   PetscBool          is_nash, is_stcg, is_gltr, is_bfgs, is_jacobi, is_symmetric, sym_set;
48a7e14dcfSSatish Balay   KSPConvergedReason ksp_reason;
49fb90e4d1STodd Munson   PC                 pc;
50a7e14dcfSSatish Balay   PetscReal          fmin, ftrial, prered, actred, kappa, sigma, beta;
51a7e14dcfSSatish Balay   PetscReal          tau, tau_1, tau_2, tau_max, tau_min, max_radius;
52a7e14dcfSSatish Balay   PetscReal          f, gnorm;
53a7e14dcfSSatish Balay 
54a7e14dcfSSatish Balay   PetscReal norm_d;
55a7e14dcfSSatish Balay   PetscInt  needH;
56a7e14dcfSSatish Balay 
57a7e14dcfSSatish Balay   PetscInt i_max = 5;
58a7e14dcfSSatish Balay   PetscInt j_max = 1;
59a7e14dcfSSatish Balay   PetscInt i, j, N, n, its;
60a7e14dcfSSatish Balay 
61a7e14dcfSSatish Balay   PetscFunctionBegin;
6248a46eb9SPierre Jolivet   if (tao->XL || tao->XU || tao->ops->computebounds) PetscCall(PetscInfo(tao, "WARNING: Variable bounds have been set but will be ignored by ntr algorithm\n"));
63a7e14dcfSSatish Balay 
649566063dSJacob Faibussowitsch   PetscCall(KSPGetType(tao->ksp, &ksp_type));
659566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPNASH, &is_nash));
669566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPSTCG, &is_stcg));
679566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPGLTR, &is_gltr));
683c859ba3SBarry Smith   PetscCheck(is_nash || is_stcg || is_gltr, PetscObjectComm((PetscObject)tao), PETSC_ERR_SUP, "TAO_NTR requires nash, stcg, or gltr for the KSP");
69a7e14dcfSSatish Balay 
70fb90e4d1STodd Munson   /* Initialize the radius and modify if it is too large or small */
71fb90e4d1STodd Munson   tao->trust = tao->trust0;
72a7e14dcfSSatish Balay   tao->trust = PetscMax(tao->trust, tr->min_radius);
73a7e14dcfSSatish Balay   tao->trust = PetscMin(tao->trust, tr->max_radius);
74a7e14dcfSSatish Balay 
750c51296cSAlp Dener   /* Allocate the vectors needed for the BFGS approximation */
769566063dSJacob Faibussowitsch   PetscCall(KSPGetPC(tao->ksp, &pc));
779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs));
789566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi));
790c51296cSAlp Dener   if (is_bfgs) {
800c51296cSAlp Dener     tr->bfgs_pre = pc;
819566063dSJacob Faibussowitsch     PetscCall(PCLMVMGetMatLMVM(tr->bfgs_pre, &tr->M));
829566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(tao->solution, &n));
839566063dSJacob Faibussowitsch     PetscCall(VecGetSize(tao->solution, &N));
849566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(tr->M, n, n, N, N));
859566063dSJacob Faibussowitsch     PetscCall(MatLMVMAllocate(tr->M, tao->solution, tao->gradient));
869566063dSJacob Faibussowitsch     PetscCall(MatIsSymmetricKnown(tr->M, &sym_set, &is_symmetric));
873c859ba3SBarry Smith     PetscCheck(sym_set && is_symmetric, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix in the LMVM preconditioner must be symmetric.");
881baa6e33SBarry Smith   } else if (is_jacobi) PetscCall(PCJacobiSetUseAbs(pc, PETSC_TRUE));
89a7e14dcfSSatish Balay 
90a7e14dcfSSatish Balay   /* Check convergence criteria */
919566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient));
929566063dSJacob Faibussowitsch   PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
933c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
94a7e14dcfSSatish Balay   needH = 1;
95a7e14dcfSSatish Balay 
963ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
979566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
989566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, 1.0));
99dbbe0bcdSBarry Smith   PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
1003ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
101a7e14dcfSSatish Balay 
102a7e14dcfSSatish Balay   /*  Initialize trust-region radius */
103a7e14dcfSSatish Balay   switch (tr->init_type) {
104a7e14dcfSSatish Balay   case NTR_INIT_CONSTANT:
105a7e14dcfSSatish Balay     /*  Use the initial radius specified */
106a7e14dcfSSatish Balay     break;
107a7e14dcfSSatish Balay 
108a7e14dcfSSatish Balay   case NTR_INIT_INTERPOLATION:
109a7e14dcfSSatish Balay     /*  Use the initial radius specified */
110a7e14dcfSSatish Balay     max_radius = 0.0;
111a7e14dcfSSatish Balay 
112a7e14dcfSSatish Balay     for (j = 0; j < j_max; ++j) {
113a7e14dcfSSatish Balay       fmin  = f;
114a7e14dcfSSatish Balay       sigma = 0.0;
115a7e14dcfSSatish Balay 
116a7e14dcfSSatish Balay       if (needH) {
1179566063dSJacob Faibussowitsch         PetscCall(TaoComputeHessian(tao, tao->solution, tao->hessian, tao->hessian_pre));
118a7e14dcfSSatish Balay         needH = 0;
119a7e14dcfSSatish Balay       }
120a7e14dcfSSatish Balay 
121a7e14dcfSSatish Balay       for (i = 0; i < i_max; ++i) {
1229566063dSJacob Faibussowitsch         PetscCall(VecCopy(tao->solution, tr->W));
1239566063dSJacob Faibussowitsch         PetscCall(VecAXPY(tr->W, -tao->trust / gnorm, tao->gradient));
1249566063dSJacob Faibussowitsch         PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
125a7e14dcfSSatish Balay 
126a7e14dcfSSatish Balay         if (PetscIsInfOrNanReal(ftrial)) {
127a7e14dcfSSatish Balay           tau = tr->gamma1_i;
1289371c9d4SSatish Balay         } else {
129a7e14dcfSSatish Balay           if (ftrial < fmin) {
130a7e14dcfSSatish Balay             fmin  = ftrial;
131a7e14dcfSSatish Balay             sigma = -tao->trust / gnorm;
132a7e14dcfSSatish Balay           }
133a7e14dcfSSatish Balay 
1349566063dSJacob Faibussowitsch           PetscCall(MatMult(tao->hessian, tao->gradient, tao->stepdirection));
1359566063dSJacob Faibussowitsch           PetscCall(VecDot(tao->gradient, tao->stepdirection, &prered));
136a7e14dcfSSatish Balay 
137a7e14dcfSSatish Balay           prered = tao->trust * (gnorm - 0.5 * tao->trust * prered / (gnorm * gnorm));
138a7e14dcfSSatish Balay           actred = f - ftrial;
1399371c9d4SSatish Balay           if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
140a7e14dcfSSatish Balay             kappa = 1.0;
1419371c9d4SSatish Balay           } else {
142a7e14dcfSSatish Balay             kappa = actred / prered;
143a7e14dcfSSatish Balay           }
144a7e14dcfSSatish Balay 
145a7e14dcfSSatish Balay           tau_1   = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust + (1.0 - tr->theta_i) * prered - actred);
146a7e14dcfSSatish Balay           tau_2   = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust - (1.0 + tr->theta_i) * prered + actred);
147a7e14dcfSSatish Balay           tau_min = PetscMin(tau_1, tau_2);
148a7e14dcfSSatish Balay           tau_max = PetscMax(tau_1, tau_2);
149a7e14dcfSSatish Balay 
15018cfbf8eSSatish Balay           if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu1_i) {
151a7e14dcfSSatish Balay             /*  Great agreement */
152a7e14dcfSSatish Balay             max_radius = PetscMax(max_radius, tao->trust);
153a7e14dcfSSatish Balay 
154a7e14dcfSSatish Balay             if (tau_max < 1.0) {
155a7e14dcfSSatish Balay               tau = tr->gamma3_i;
1569371c9d4SSatish Balay             } else if (tau_max > tr->gamma4_i) {
157a7e14dcfSSatish Balay               tau = tr->gamma4_i;
1589371c9d4SSatish Balay             } else {
159a7e14dcfSSatish Balay               tau = tau_max;
160a7e14dcfSSatish Balay             }
1619371c9d4SSatish Balay           } else if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu2_i) {
162a7e14dcfSSatish Balay             /*  Good agreement */
163a7e14dcfSSatish Balay             max_radius = PetscMax(max_radius, tao->trust);
164a7e14dcfSSatish Balay 
165a7e14dcfSSatish Balay             if (tau_max < tr->gamma2_i) {
166a7e14dcfSSatish Balay               tau = tr->gamma2_i;
1679371c9d4SSatish Balay             } else if (tau_max > tr->gamma3_i) {
168a7e14dcfSSatish Balay               tau = tr->gamma3_i;
1699371c9d4SSatish Balay             } else {
170a7e14dcfSSatish Balay               tau = tau_max;
171a7e14dcfSSatish Balay             }
1729371c9d4SSatish Balay           } else {
173a7e14dcfSSatish Balay             /*  Not good agreement */
174a7e14dcfSSatish Balay             if (tau_min > 1.0) {
175a7e14dcfSSatish Balay               tau = tr->gamma2_i;
1769371c9d4SSatish Balay             } else if (tau_max < tr->gamma1_i) {
177a7e14dcfSSatish Balay               tau = tr->gamma1_i;
1789371c9d4SSatish Balay             } else if ((tau_min < tr->gamma1_i) && (tau_max >= 1.0)) {
179a7e14dcfSSatish Balay               tau = tr->gamma1_i;
1809371c9d4SSatish Balay             } else if ((tau_1 >= tr->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < tr->gamma1_i) || (tau_2 >= 1.0))) {
181a7e14dcfSSatish Balay               tau = tau_1;
1829371c9d4SSatish Balay             } else if ((tau_2 >= tr->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < tr->gamma1_i) || (tau_2 >= 1.0))) {
183a7e14dcfSSatish Balay               tau = tau_2;
1849371c9d4SSatish Balay             } else {
185a7e14dcfSSatish Balay               tau = tau_max;
186a7e14dcfSSatish Balay             }
187a7e14dcfSSatish Balay           }
188a7e14dcfSSatish Balay         }
189a7e14dcfSSatish Balay         tao->trust = tau * tao->trust;
190a7e14dcfSSatish Balay       }
191a7e14dcfSSatish Balay 
192a7e14dcfSSatish Balay       if (fmin < f) {
193a7e14dcfSSatish Balay         f = fmin;
1949566063dSJacob Faibussowitsch         PetscCall(VecAXPY(tao->solution, sigma, tao->gradient));
1959566063dSJacob Faibussowitsch         PetscCall(TaoComputeGradient(tao, tao->solution, tao->gradient));
196a7e14dcfSSatish Balay 
1979566063dSJacob Faibussowitsch         PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
1983c859ba3SBarry Smith         PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
199a7e14dcfSSatish Balay         needH = 1;
200a7e14dcfSSatish Balay 
2019566063dSJacob Faibussowitsch         PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
2029566063dSJacob Faibussowitsch         PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, 1.0));
203dbbe0bcdSBarry Smith         PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
204ad540459SPierre Jolivet         if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
205a7e14dcfSSatish Balay       }
206a7e14dcfSSatish Balay     }
207a7e14dcfSSatish Balay     tao->trust = PetscMax(tao->trust, max_radius);
208a7e14dcfSSatish Balay 
209a7e14dcfSSatish Balay     /*  Modify the radius if it is too large or small */
210a7e14dcfSSatish Balay     tao->trust = PetscMax(tao->trust, tr->min_radius);
211a7e14dcfSSatish Balay     tao->trust = PetscMin(tao->trust, tr->max_radius);
212a7e14dcfSSatish Balay     break;
213a7e14dcfSSatish Balay 
214a7e14dcfSSatish Balay   default:
215a7e14dcfSSatish Balay     /*  Norm of the first direction will initialize radius */
216a7e14dcfSSatish Balay     tao->trust = 0.0;
217a7e14dcfSSatish Balay     break;
218a7e14dcfSSatish Balay   }
219a7e14dcfSSatish Balay 
220a7e14dcfSSatish Balay   /* Have not converged; continue with Newton method */
2213ecd9318SAlp Dener   while (tao->reason == TAO_CONTINUE_ITERATING) {
222e1e80dc8SAlp Dener     /* Call general purpose update function */
223dbbe0bcdSBarry Smith     PetscTryTypeMethod(tao, update, tao->niter, tao->user_update);
2248931d482SJason Sarich     ++tao->niter;
225ae93cb3cSJason Sarich     tao->ksp_its = 0;
226a7e14dcfSSatish Balay     /* Compute the Hessian */
227a7e14dcfSSatish Balay     if (needH) {
2289566063dSJacob Faibussowitsch       PetscCall(TaoComputeHessian(tao, tao->solution, tao->hessian, tao->hessian_pre));
229a7e14dcfSSatish Balay       needH = 0;
230a7e14dcfSSatish Balay     }
231a7e14dcfSSatish Balay 
2320c51296cSAlp Dener     if (tr->bfgs_pre) {
233a7e14dcfSSatish Balay       /* Update the limited memory preconditioner */
2349566063dSJacob Faibussowitsch       PetscCall(MatLMVMUpdate(tr->M, tao->solution, tao->gradient));
235a7e14dcfSSatish Balay     }
236a7e14dcfSSatish Balay 
2373ecd9318SAlp Dener     while (tao->reason == TAO_CONTINUE_ITERATING) {
2389566063dSJacob Faibussowitsch       PetscCall(KSPSetOperators(tao->ksp, tao->hessian, tao->hessian_pre));
239a7e14dcfSSatish Balay 
240a7e14dcfSSatish Balay       /* Solve the trust region subproblem */
2419566063dSJacob Faibussowitsch       PetscCall(KSPCGSetRadius(tao->ksp, tao->trust));
2429566063dSJacob Faibussowitsch       PetscCall(KSPSolve(tao->ksp, tao->gradient, tao->stepdirection));
2439566063dSJacob Faibussowitsch       PetscCall(KSPGetIterationNumber(tao->ksp, &its));
244a7e14dcfSSatish Balay       tao->ksp_its += its;
245ae93cb3cSJason Sarich       tao->ksp_tot_its += its;
2469566063dSJacob Faibussowitsch       PetscCall(KSPCGGetNormD(tao->ksp, &norm_d));
247a7e14dcfSSatish Balay 
248a7e14dcfSSatish Balay       if (0.0 == tao->trust) {
249a7e14dcfSSatish Balay         /* Radius was uninitialized; use the norm of the direction */
250a7e14dcfSSatish Balay         if (norm_d > 0.0) {
251a7e14dcfSSatish Balay           tao->trust = norm_d;
252a7e14dcfSSatish Balay 
253a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
254a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, tr->min_radius);
255a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, tr->max_radius);
2569371c9d4SSatish Balay         } else {
257a7e14dcfSSatish Balay           /* The direction was bad; set radius to default value and re-solve
258a7e14dcfSSatish Balay              the trust-region subproblem to get a direction */
259a7e14dcfSSatish Balay           tao->trust = tao->trust0;
260a7e14dcfSSatish Balay 
261a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
262a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, tr->min_radius);
263a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, tr->max_radius);
264a7e14dcfSSatish Balay 
2659566063dSJacob Faibussowitsch           PetscCall(KSPCGSetRadius(tao->ksp, tao->trust));
2669566063dSJacob Faibussowitsch           PetscCall(KSPSolve(tao->ksp, tao->gradient, tao->stepdirection));
2679566063dSJacob Faibussowitsch           PetscCall(KSPGetIterationNumber(tao->ksp, &its));
268a7e14dcfSSatish Balay           tao->ksp_its += its;
2692d9aa51bSJason Sarich           tao->ksp_tot_its += its;
2709566063dSJacob Faibussowitsch           PetscCall(KSPCGGetNormD(tao->ksp, &norm_d));
271a7e14dcfSSatish Balay 
2723c859ba3SBarry Smith           PetscCheck(norm_d != 0.0, PetscObjectComm((PetscObject)tao), PETSC_ERR_PLIB, "Initial direction zero");
273a7e14dcfSSatish Balay         }
274a7e14dcfSSatish Balay       }
2759566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
2769566063dSJacob Faibussowitsch       PetscCall(KSPGetConvergedReason(tao->ksp, &ksp_reason));
2770c51296cSAlp Dener       if ((KSP_DIVERGED_INDEFINITE_PC == ksp_reason) && (tr->bfgs_pre)) {
278a7e14dcfSSatish Balay         /* Preconditioner is numerically indefinite; reset the
279a7e14dcfSSatish Balay            approximate if using BFGS preconditioning. */
2809566063dSJacob Faibussowitsch         PetscCall(MatLMVMReset(tr->M, PETSC_FALSE));
2819566063dSJacob Faibussowitsch         PetscCall(MatLMVMUpdate(tr->M, tao->solution, tao->gradient));
282a7e14dcfSSatish Balay       }
283a7e14dcfSSatish Balay 
284a7e14dcfSSatish Balay       if (NTR_UPDATE_REDUCTION == tr->update_type) {
285a7e14dcfSSatish Balay         /* Get predicted reduction */
2869566063dSJacob Faibussowitsch         PetscCall(KSPCGGetObjFcn(tao->ksp, &prered));
287a7e14dcfSSatish Balay         if (prered >= 0.0) {
288a7e14dcfSSatish Balay           /* The predicted reduction has the wrong sign.  This cannot
289a7e14dcfSSatish Balay              happen in infinite precision arithmetic.  Step should
290a7e14dcfSSatish Balay              be rejected! */
291a7e14dcfSSatish Balay           tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
2929371c9d4SSatish Balay         } else {
293a7e14dcfSSatish Balay           /* Compute trial step and function value */
2949566063dSJacob Faibussowitsch           PetscCall(VecCopy(tao->solution, tr->W));
2959566063dSJacob Faibussowitsch           PetscCall(VecAXPY(tr->W, 1.0, tao->stepdirection));
2969566063dSJacob Faibussowitsch           PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
297a7e14dcfSSatish Balay 
298a7e14dcfSSatish Balay           if (PetscIsInfOrNanReal(ftrial)) {
299a7e14dcfSSatish Balay             tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
300a7e14dcfSSatish Balay           } else {
301a7e14dcfSSatish Balay             /* Compute and actual reduction */
302a7e14dcfSSatish Balay             actred = f - ftrial;
303a7e14dcfSSatish Balay             prered = -prered;
3049371c9d4SSatish Balay             if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
305a7e14dcfSSatish Balay               kappa = 1.0;
3069371c9d4SSatish Balay             } else {
307a7e14dcfSSatish Balay               kappa = actred / prered;
308a7e14dcfSSatish Balay             }
309a7e14dcfSSatish Balay 
310a7e14dcfSSatish Balay             /* Accept or reject the step and update radius */
311a7e14dcfSSatish Balay             if (kappa < tr->eta1) {
312a7e14dcfSSatish Balay               /* Reject the step */
313a7e14dcfSSatish Balay               tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
3149371c9d4SSatish Balay             } else {
315a7e14dcfSSatish Balay               /* Accept the step */
316a7e14dcfSSatish Balay               if (kappa < tr->eta2) {
317a7e14dcfSSatish Balay                 /* Marginal bad step */
318a7e14dcfSSatish Balay                 tao->trust = tr->alpha2 * PetscMin(tao->trust, norm_d);
3199371c9d4SSatish Balay               } else if (kappa < tr->eta3) {
320a7e14dcfSSatish Balay                 /* Reasonable step */
321a7e14dcfSSatish Balay                 tao->trust = tr->alpha3 * tao->trust;
3229371c9d4SSatish Balay               } else if (kappa < tr->eta4) {
323a7e14dcfSSatish Balay                 /* Good step */
324a7e14dcfSSatish Balay                 tao->trust = PetscMax(tr->alpha4 * norm_d, tao->trust);
3259371c9d4SSatish Balay               } else {
326a7e14dcfSSatish Balay                 /* Very good step */
327a7e14dcfSSatish Balay                 tao->trust = PetscMax(tr->alpha5 * norm_d, tao->trust);
328a7e14dcfSSatish Balay               }
329a7e14dcfSSatish Balay               break;
330a7e14dcfSSatish Balay             }
331a7e14dcfSSatish Balay           }
332a7e14dcfSSatish Balay         }
3339371c9d4SSatish Balay       } else {
334a7e14dcfSSatish Balay         /* Get predicted reduction */
3359566063dSJacob Faibussowitsch         PetscCall(KSPCGGetObjFcn(tao->ksp, &prered));
336a7e14dcfSSatish Balay         if (prered >= 0.0) {
337a7e14dcfSSatish Balay           /* The predicted reduction has the wrong sign.  This cannot
338a7e14dcfSSatish Balay              happen in infinite precision arithmetic.  Step should
339a7e14dcfSSatish Balay              be rejected! */
340a7e14dcfSSatish Balay           tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3419371c9d4SSatish Balay         } else {
3429566063dSJacob Faibussowitsch           PetscCall(VecCopy(tao->solution, tr->W));
3439566063dSJacob Faibussowitsch           PetscCall(VecAXPY(tr->W, 1.0, tao->stepdirection));
3449566063dSJacob Faibussowitsch           PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
345a7e14dcfSSatish Balay           if (PetscIsInfOrNanReal(ftrial)) {
346a7e14dcfSSatish Balay             tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3479371c9d4SSatish Balay           } else {
3489566063dSJacob Faibussowitsch             PetscCall(VecDot(tao->gradient, tao->stepdirection, &beta));
349a7e14dcfSSatish Balay             actred = f - ftrial;
350a7e14dcfSSatish Balay             prered = -prered;
3519371c9d4SSatish Balay             if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
352a7e14dcfSSatish Balay               kappa = 1.0;
3539371c9d4SSatish Balay             } else {
354a7e14dcfSSatish Balay               kappa = actred / prered;
355a7e14dcfSSatish Balay             }
356a7e14dcfSSatish Balay 
357a7e14dcfSSatish Balay             tau_1   = tr->theta * beta / (tr->theta * beta - (1.0 - tr->theta) * prered + actred);
358a7e14dcfSSatish Balay             tau_2   = tr->theta * beta / (tr->theta * beta + (1.0 + tr->theta) * prered - actred);
359a7e14dcfSSatish Balay             tau_min = PetscMin(tau_1, tau_2);
360a7e14dcfSSatish Balay             tau_max = PetscMax(tau_1, tau_2);
361a7e14dcfSSatish Balay 
362a7e14dcfSSatish Balay             if (kappa >= 1.0 - tr->mu1) {
363a7e14dcfSSatish Balay               /* Great agreement; accept step and update radius */
364a7e14dcfSSatish Balay               if (tau_max < 1.0) {
365a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d);
3669371c9d4SSatish Balay               } else if (tau_max > tr->gamma4) {
367a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma4 * norm_d);
3689371c9d4SSatish Balay               } else {
369a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tau_max * norm_d);
370a7e14dcfSSatish Balay               }
371a7e14dcfSSatish Balay               break;
3729371c9d4SSatish Balay             } else if (kappa >= 1.0 - tr->mu2) {
373a7e14dcfSSatish Balay               /* Good agreement */
374a7e14dcfSSatish Balay 
375a7e14dcfSSatish Balay               if (tau_max < tr->gamma2) {
376a7e14dcfSSatish Balay                 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d);
3779371c9d4SSatish Balay               } else if (tau_max > tr->gamma3) {
378a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d);
3799371c9d4SSatish Balay               } else if (tau_max < 1.0) {
380a7e14dcfSSatish Balay                 tao->trust = tau_max * PetscMin(tao->trust, norm_d);
3819371c9d4SSatish Balay               } else {
382a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tau_max * norm_d);
383a7e14dcfSSatish Balay               }
384a7e14dcfSSatish Balay               break;
3859371c9d4SSatish Balay             } else {
386a7e14dcfSSatish Balay               /* Not good agreement */
387a7e14dcfSSatish Balay               if (tau_min > 1.0) {
388a7e14dcfSSatish Balay                 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d);
3899371c9d4SSatish Balay               } else if (tau_max < tr->gamma1) {
390a7e14dcfSSatish Balay                 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3919371c9d4SSatish Balay               } else if ((tau_min < tr->gamma1) && (tau_max >= 1.0)) {
392a7e14dcfSSatish Balay                 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3939371c9d4SSatish Balay               } else if ((tau_1 >= tr->gamma1) && (tau_1 < 1.0) && ((tau_2 < tr->gamma1) || (tau_2 >= 1.0))) {
394a7e14dcfSSatish Balay                 tao->trust = tau_1 * PetscMin(tao->trust, norm_d);
3959371c9d4SSatish Balay               } else if ((tau_2 >= tr->gamma1) && (tau_2 < 1.0) && ((tau_1 < tr->gamma1) || (tau_2 >= 1.0))) {
396a7e14dcfSSatish Balay                 tao->trust = tau_2 * PetscMin(tao->trust, norm_d);
3979371c9d4SSatish Balay               } else {
398a7e14dcfSSatish Balay                 tao->trust = tau_max * PetscMin(tao->trust, norm_d);
399a7e14dcfSSatish Balay               }
400a7e14dcfSSatish Balay             }
401a7e14dcfSSatish Balay           }
402a7e14dcfSSatish Balay         }
403a7e14dcfSSatish Balay       }
404a7e14dcfSSatish Balay 
405a7e14dcfSSatish Balay       /* The step computed was not good and the radius was decreased.
406a7e14dcfSSatish Balay          Monitor the radius to terminate. */
4079566063dSJacob Faibussowitsch       PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
4089566063dSJacob Faibussowitsch       PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, tao->trust));
409dbbe0bcdSBarry Smith       PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
410a7e14dcfSSatish Balay     }
411a7e14dcfSSatish Balay 
412a7e14dcfSSatish Balay     /* The radius may have been increased; modify if it is too large */
413a7e14dcfSSatish Balay     tao->trust = PetscMin(tao->trust, tr->max_radius);
414a7e14dcfSSatish Balay 
4153ecd9318SAlp Dener     if (tao->reason == TAO_CONTINUE_ITERATING) {
4169566063dSJacob Faibussowitsch       PetscCall(VecCopy(tr->W, tao->solution));
417a7e14dcfSSatish Balay       f = ftrial;
4189566063dSJacob Faibussowitsch       PetscCall(TaoComputeGradient(tao, tao->solution, tao->gradient));
4199566063dSJacob Faibussowitsch       PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
4203c859ba3SBarry Smith       PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
421a7e14dcfSSatish Balay       needH = 1;
4229566063dSJacob Faibussowitsch       PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
4239566063dSJacob Faibussowitsch       PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, tao->trust));
424dbbe0bcdSBarry Smith       PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
425a7e14dcfSSatish Balay     }
426a7e14dcfSSatish Balay   }
427a7e14dcfSSatish Balay   PetscFunctionReturn(0);
428a7e14dcfSSatish Balay }
429a7e14dcfSSatish Balay 
430a7e14dcfSSatish Balay /*------------------------------------------------------------*/
431*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetUp_NTR(Tao tao)
432*d71ae5a4SJacob Faibussowitsch {
433a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
434a7e14dcfSSatish Balay 
435a7e14dcfSSatish Balay   PetscFunctionBegin;
4369566063dSJacob Faibussowitsch   if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient));
4379566063dSJacob Faibussowitsch   if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection));
4389566063dSJacob Faibussowitsch   if (!tr->W) PetscCall(VecDuplicate(tao->solution, &tr->W));
439a7e14dcfSSatish Balay 
44083c8fe1dSLisandro Dalcin   tr->bfgs_pre = NULL;
44183c8fe1dSLisandro Dalcin   tr->M        = NULL;
442a7e14dcfSSatish Balay   PetscFunctionReturn(0);
443a7e14dcfSSatish Balay }
444a7e14dcfSSatish Balay 
445a7e14dcfSSatish Balay /*------------------------------------------------------------*/
446*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoDestroy_NTR(Tao tao)
447*d71ae5a4SJacob Faibussowitsch {
448a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
449a7e14dcfSSatish Balay 
450a7e14dcfSSatish Balay   PetscFunctionBegin;
45148a46eb9SPierre Jolivet   if (tao->setupcalled) PetscCall(VecDestroy(&tr->W));
452a958fbfcSStefano Zampini   PetscCall(KSPDestroy(&tao->ksp));
4539566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
454a7e14dcfSSatish Balay   PetscFunctionReturn(0);
455a7e14dcfSSatish Balay }
456a7e14dcfSSatish Balay 
457a7e14dcfSSatish Balay /*------------------------------------------------------------*/
458*d71ae5a4SJacob Faibussowitsch static PetscErrorCode TaoSetFromOptions_NTR(Tao tao, PetscOptionItems *PetscOptionsObject)
459*d71ae5a4SJacob Faibussowitsch {
460a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
461a7e14dcfSSatish Balay 
462a7e14dcfSSatish Balay   PetscFunctionBegin;
463d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Newton trust region method for unconstrained optimization");
4649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_ntr_init_type", "tao->trust initialization type", "", NTR_INIT, NTR_INIT_TYPES, NTR_INIT[tr->init_type], &tr->init_type, NULL));
4659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_ntr_update_type", "radius update type", "", NTR_UPDATE, NTR_UPDATE_TYPES, NTR_UPDATE[tr->update_type], &tr->update_type, NULL));
4669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta1", "step is unsuccessful if actual reduction < eta1 * predicted reduction", "", tr->eta1, &tr->eta1, NULL));
4679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta2", "", "", tr->eta2, &tr->eta2, NULL));
4689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta3", "", "", tr->eta3, &tr->eta3, NULL));
4699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta4", "", "", tr->eta4, &tr->eta4, NULL));
4709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha1", "", "", tr->alpha1, &tr->alpha1, NULL));
4719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha2", "", "", tr->alpha2, &tr->alpha2, NULL));
4729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha3", "", "", tr->alpha3, &tr->alpha3, NULL));
4739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha4", "", "", tr->alpha4, &tr->alpha4, NULL));
4749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha5", "", "", tr->alpha5, &tr->alpha5, NULL));
4759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu1", "", "", tr->mu1, &tr->mu1, NULL));
4769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu2", "", "", tr->mu2, &tr->mu2, NULL));
4779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma1", "", "", tr->gamma1, &tr->gamma1, NULL));
4789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma2", "", "", tr->gamma2, &tr->gamma2, NULL));
4799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma3", "", "", tr->gamma3, &tr->gamma3, NULL));
4809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma4", "", "", tr->gamma4, &tr->gamma4, NULL));
4819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_theta", "", "", tr->theta, &tr->theta, NULL));
4829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu1_i", "", "", tr->mu1_i, &tr->mu1_i, NULL));
4839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu2_i", "", "", tr->mu2_i, &tr->mu2_i, NULL));
4849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma1_i", "", "", tr->gamma1_i, &tr->gamma1_i, NULL));
4859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma2_i", "", "", tr->gamma2_i, &tr->gamma2_i, NULL));
4869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma3_i", "", "", tr->gamma3_i, &tr->gamma3_i, NULL));
4879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma4_i", "", "", tr->gamma4_i, &tr->gamma4_i, NULL));
4889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_theta_i", "", "", tr->theta_i, &tr->theta_i, NULL));
4899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_min_radius", "lower bound on initial trust-region radius", "", tr->min_radius, &tr->min_radius, NULL));
4909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_max_radius", "upper bound on trust-region radius", "", tr->max_radius, &tr->max_radius, NULL));
4919566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_epsilon", "tolerance used when computing actual and predicted reduction", "", tr->epsilon, &tr->epsilon, NULL));
492d0609cedSBarry Smith   PetscOptionsHeadEnd();
4939566063dSJacob Faibussowitsch   PetscCall(KSPSetFromOptions(tao->ksp));
494a7e14dcfSSatish Balay   PetscFunctionReturn(0);
495a7e14dcfSSatish Balay }
496a7e14dcfSSatish Balay 
497a7e14dcfSSatish Balay /*------------------------------------------------------------*/
4981522df2eSJason Sarich /*MC
4991522df2eSJason Sarich   TAONTR - Newton's method with trust region for unconstrained minimization.
5001522df2eSJason Sarich   At each iteration, the Newton trust region method solves the system.
5011522df2eSJason Sarich   NTR expects a KSP solver with a trust region radius.
5021522df2eSJason Sarich             min_d  .5 dT Hk d + gkT d,  s.t.   ||d|| < Delta_k
5031522df2eSJason Sarich 
5041522df2eSJason Sarich   Options Database Keys:
5059d0a60b2SAlp Dener + -tao_ntr_init_type - "constant","direction","interpolation"
5061522df2eSJason Sarich . -tao_ntr_update_type - "reduction","interpolation"
5071522df2eSJason Sarich . -tao_ntr_min_radius - lower bound on trust region radius
5081522df2eSJason Sarich . -tao_ntr_max_radius - upper bound on trust region radius
5091522df2eSJason Sarich . -tao_ntr_epsilon - tolerance for accepting actual / predicted reduction
5101522df2eSJason Sarich . -tao_ntr_mu1_i - mu1 interpolation init factor
5111522df2eSJason Sarich . -tao_ntr_mu2_i - mu2 interpolation init factor
5121522df2eSJason Sarich . -tao_ntr_gamma1_i - gamma1 interpolation init factor
5131522df2eSJason Sarich . -tao_ntr_gamma2_i - gamma2 interpolation init factor
5141522df2eSJason Sarich . -tao_ntr_gamma3_i - gamma3 interpolation init factor
5151522df2eSJason Sarich . -tao_ntr_gamma4_i - gamma4 interpolation init factor
5168966356dSPierre Jolivet . -tao_ntr_theta_i - theta1 interpolation init factor
5171522df2eSJason Sarich . -tao_ntr_eta1 - eta1 reduction update factor
5181522df2eSJason Sarich . -tao_ntr_eta2 - eta2 reduction update factor
5191522df2eSJason Sarich . -tao_ntr_eta3 - eta3 reduction update factor
5201522df2eSJason Sarich . -tao_ntr_eta4 - eta4 reduction update factor
5211522df2eSJason Sarich . -tao_ntr_alpha1 - alpha1 reduction update factor
5221522df2eSJason Sarich . -tao_ntr_alpha2 - alpha2 reduction update factor
5231522df2eSJason Sarich . -tao_ntr_alpha3 - alpha3 reduction update factor
5241522df2eSJason Sarich . -tao_ntr_alpha4 - alpha4 reduction update factor
5251522df2eSJason Sarich . -tao_ntr_alpha4 - alpha4 reduction update factor
5261522df2eSJason Sarich . -tao_ntr_mu1 - mu1 interpolation update
5271522df2eSJason Sarich . -tao_ntr_mu2 - mu2 interpolation update
5281522df2eSJason Sarich . -tao_ntr_gamma1 - gamma1 interpolcation update
5291522df2eSJason Sarich . -tao_ntr_gamma2 - gamma2 interpolcation update
5301522df2eSJason Sarich . -tao_ntr_gamma3 - gamma3 interpolcation update
5311522df2eSJason Sarich . -tao_ntr_gamma4 - gamma4 interpolation update
5321522df2eSJason Sarich - -tao_ntr_theta - theta interpolation update
5331522df2eSJason Sarich 
5341eb8069cSJason Sarich   Level: beginner
5351522df2eSJason Sarich M*/
5361522df2eSJason Sarich 
537*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode TaoCreate_NTR(Tao tao)
538*d71ae5a4SJacob Faibussowitsch {
539a7e14dcfSSatish Balay   TAO_NTR *tr;
540a7e14dcfSSatish Balay 
541a7e14dcfSSatish Balay   PetscFunctionBegin;
542a7e14dcfSSatish Balay 
5434dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&tr));
544a7e14dcfSSatish Balay 
545a7e14dcfSSatish Balay   tao->ops->setup          = TaoSetUp_NTR;
546a7e14dcfSSatish Balay   tao->ops->solve          = TaoSolve_NTR;
547a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_NTR;
548a7e14dcfSSatish Balay   tao->ops->destroy        = TaoDestroy_NTR;
549a7e14dcfSSatish Balay 
5506552cf8aSJason Sarich   /* Override default settings (unless already changed) */
5516552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 50;
5526552cf8aSJason Sarich   if (!tao->trust0_changed) tao->trust0 = 100.0;
553a7e14dcfSSatish Balay   tao->data = (void *)tr;
554a7e14dcfSSatish Balay 
555a7e14dcfSSatish Balay   /*  Standard trust region update parameters */
556a7e14dcfSSatish Balay   tr->eta1 = 1.0e-4;
557a7e14dcfSSatish Balay   tr->eta2 = 0.25;
558a7e14dcfSSatish Balay   tr->eta3 = 0.50;
559a7e14dcfSSatish Balay   tr->eta4 = 0.90;
560a7e14dcfSSatish Balay 
561a7e14dcfSSatish Balay   tr->alpha1 = 0.25;
562a7e14dcfSSatish Balay   tr->alpha2 = 0.50;
563a7e14dcfSSatish Balay   tr->alpha3 = 1.00;
564a7e14dcfSSatish Balay   tr->alpha4 = 2.00;
565a7e14dcfSSatish Balay   tr->alpha5 = 4.00;
566a7e14dcfSSatish Balay 
567a7e14dcfSSatish Balay   /*  Interpolation trust region update parameters */
568a7e14dcfSSatish Balay   tr->mu1 = 0.10;
569a7e14dcfSSatish Balay   tr->mu2 = 0.50;
570a7e14dcfSSatish Balay 
571a7e14dcfSSatish Balay   tr->gamma1 = 0.25;
572a7e14dcfSSatish Balay   tr->gamma2 = 0.50;
573a7e14dcfSSatish Balay   tr->gamma3 = 2.00;
574a7e14dcfSSatish Balay   tr->gamma4 = 4.00;
575a7e14dcfSSatish Balay 
576a7e14dcfSSatish Balay   tr->theta = 0.05;
577a7e14dcfSSatish Balay 
578fb90e4d1STodd Munson   /*  Interpolation parameters for initialization */
579fb90e4d1STodd Munson   tr->mu1_i = 0.35;
580fb90e4d1STodd Munson   tr->mu2_i = 0.50;
581fb90e4d1STodd Munson 
582fb90e4d1STodd Munson   tr->gamma1_i = 0.0625;
583fb90e4d1STodd Munson   tr->gamma2_i = 0.50;
584fb90e4d1STodd Munson   tr->gamma3_i = 2.00;
585fb90e4d1STodd Munson   tr->gamma4_i = 5.00;
586fb90e4d1STodd Munson 
587fb90e4d1STodd Munson   tr->theta_i = 0.25;
588fb90e4d1STodd Munson 
589a7e14dcfSSatish Balay   tr->min_radius = 1.0e-10;
590a7e14dcfSSatish Balay   tr->max_radius = 1.0e10;
591a7e14dcfSSatish Balay   tr->epsilon    = 1.0e-6;
592a7e14dcfSSatish Balay 
593a7e14dcfSSatish Balay   tr->init_type   = NTR_INIT_INTERPOLATION;
594a7e14dcfSSatish Balay   tr->update_type = NTR_UPDATE_REDUCTION;
595a7e14dcfSSatish Balay 
596a7e14dcfSSatish Balay   /* Set linear solver to default for trust region */
5979566063dSJacob Faibussowitsch   PetscCall(KSPCreate(((PetscObject)tao)->comm, &tao->ksp));
5989566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1));
5999566063dSJacob Faibussowitsch   PetscCall(KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix));
6009566063dSJacob Faibussowitsch   PetscCall(KSPAppendOptionsPrefix(tao->ksp, "tao_ntr_"));
6019566063dSJacob Faibussowitsch   PetscCall(KSPSetType(tao->ksp, KSPSTCG));
602a7e14dcfSSatish Balay   PetscFunctionReturn(0);
603a7e14dcfSSatish Balay }
604