xref: /petsc/src/tao/unconstrained/impls/ntr/ntr.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
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 */
439371c9d4SSatish Balay static PetscErrorCode TaoSolve_NTR(Tao tao) {
44a7e14dcfSSatish Balay   TAO_NTR           *tr = (TAO_NTR *)tao->data;
45fb90e4d1STodd Munson   KSPType            ksp_type;
460ad3a497SAlp Dener   PetscBool          is_nash, is_stcg, is_gltr, is_bfgs, is_jacobi, is_symmetric, sym_set;
47a7e14dcfSSatish Balay   KSPConvergedReason ksp_reason;
48fb90e4d1STodd Munson   PC                 pc;
49a7e14dcfSSatish Balay   PetscReal          fmin, ftrial, prered, actred, kappa, sigma, beta;
50a7e14dcfSSatish Balay   PetscReal          tau, tau_1, tau_2, tau_max, tau_min, max_radius;
51a7e14dcfSSatish Balay   PetscReal          f, gnorm;
52a7e14dcfSSatish Balay 
53a7e14dcfSSatish Balay   PetscReal norm_d;
54a7e14dcfSSatish Balay   PetscInt  needH;
55a7e14dcfSSatish Balay 
56a7e14dcfSSatish Balay   PetscInt i_max = 5;
57a7e14dcfSSatish Balay   PetscInt j_max = 1;
58a7e14dcfSSatish Balay   PetscInt i, j, N, n, its;
59a7e14dcfSSatish Balay 
60a7e14dcfSSatish Balay   PetscFunctionBegin;
6148a46eb9SPierre 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"));
62a7e14dcfSSatish Balay 
639566063dSJacob Faibussowitsch   PetscCall(KSPGetType(tao->ksp, &ksp_type));
649566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPNASH, &is_nash));
659566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPSTCG, &is_stcg));
669566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(ksp_type, KSPGLTR, &is_gltr));
673c859ba3SBarry Smith   PetscCheck(is_nash || is_stcg || is_gltr, PetscObjectComm((PetscObject)tao), PETSC_ERR_SUP, "TAO_NTR requires nash, stcg, or gltr for the KSP");
68a7e14dcfSSatish Balay 
69fb90e4d1STodd Munson   /* Initialize the radius and modify if it is too large or small */
70fb90e4d1STodd Munson   tao->trust = tao->trust0;
71a7e14dcfSSatish Balay   tao->trust = PetscMax(tao->trust, tr->min_radius);
72a7e14dcfSSatish Balay   tao->trust = PetscMin(tao->trust, tr->max_radius);
73a7e14dcfSSatish Balay 
740c51296cSAlp Dener   /* Allocate the vectors needed for the BFGS approximation */
759566063dSJacob Faibussowitsch   PetscCall(KSPGetPC(tao->ksp, &pc));
769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCLMVM, &is_bfgs));
779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCJACOBI, &is_jacobi));
780c51296cSAlp Dener   if (is_bfgs) {
790c51296cSAlp Dener     tr->bfgs_pre = pc;
809566063dSJacob Faibussowitsch     PetscCall(PCLMVMGetMatLMVM(tr->bfgs_pre, &tr->M));
819566063dSJacob Faibussowitsch     PetscCall(VecGetLocalSize(tao->solution, &n));
829566063dSJacob Faibussowitsch     PetscCall(VecGetSize(tao->solution, &N));
839566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(tr->M, n, n, N, N));
849566063dSJacob Faibussowitsch     PetscCall(MatLMVMAllocate(tr->M, tao->solution, tao->gradient));
859566063dSJacob Faibussowitsch     PetscCall(MatIsSymmetricKnown(tr->M, &sym_set, &is_symmetric));
863c859ba3SBarry Smith     PetscCheck(sym_set && is_symmetric, PetscObjectComm((PetscObject)tao), PETSC_ERR_ARG_INCOMP, "LMVM matrix in the LMVM preconditioner must be symmetric.");
871baa6e33SBarry Smith   } else if (is_jacobi) PetscCall(PCJacobiSetUseAbs(pc, PETSC_TRUE));
88a7e14dcfSSatish Balay 
89a7e14dcfSSatish Balay   /* Check convergence criteria */
909566063dSJacob Faibussowitsch   PetscCall(TaoComputeObjectiveAndGradient(tao, tao->solution, &f, tao->gradient));
919566063dSJacob Faibussowitsch   PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
923c859ba3SBarry Smith   PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
93a7e14dcfSSatish Balay   needH = 1;
94a7e14dcfSSatish Balay 
953ecd9318SAlp Dener   tao->reason = TAO_CONTINUE_ITERATING;
969566063dSJacob Faibussowitsch   PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
979566063dSJacob Faibussowitsch   PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, 1.0));
98dbbe0bcdSBarry Smith   PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
993ecd9318SAlp Dener   if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
100a7e14dcfSSatish Balay 
101a7e14dcfSSatish Balay   /*  Initialize trust-region radius */
102a7e14dcfSSatish Balay   switch (tr->init_type) {
103a7e14dcfSSatish Balay   case NTR_INIT_CONSTANT:
104a7e14dcfSSatish Balay     /*  Use the initial radius specified */
105a7e14dcfSSatish Balay     break;
106a7e14dcfSSatish Balay 
107a7e14dcfSSatish Balay   case NTR_INIT_INTERPOLATION:
108a7e14dcfSSatish Balay     /*  Use the initial radius specified */
109a7e14dcfSSatish Balay     max_radius = 0.0;
110a7e14dcfSSatish Balay 
111a7e14dcfSSatish Balay     for (j = 0; j < j_max; ++j) {
112a7e14dcfSSatish Balay       fmin  = f;
113a7e14dcfSSatish Balay       sigma = 0.0;
114a7e14dcfSSatish Balay 
115a7e14dcfSSatish Balay       if (needH) {
1169566063dSJacob Faibussowitsch         PetscCall(TaoComputeHessian(tao, tao->solution, tao->hessian, tao->hessian_pre));
117a7e14dcfSSatish Balay         needH = 0;
118a7e14dcfSSatish Balay       }
119a7e14dcfSSatish Balay 
120a7e14dcfSSatish Balay       for (i = 0; i < i_max; ++i) {
1219566063dSJacob Faibussowitsch         PetscCall(VecCopy(tao->solution, tr->W));
1229566063dSJacob Faibussowitsch         PetscCall(VecAXPY(tr->W, -tao->trust / gnorm, tao->gradient));
1239566063dSJacob Faibussowitsch         PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
124a7e14dcfSSatish Balay 
125a7e14dcfSSatish Balay         if (PetscIsInfOrNanReal(ftrial)) {
126a7e14dcfSSatish Balay           tau = tr->gamma1_i;
1279371c9d4SSatish Balay         } else {
128a7e14dcfSSatish Balay           if (ftrial < fmin) {
129a7e14dcfSSatish Balay             fmin  = ftrial;
130a7e14dcfSSatish Balay             sigma = -tao->trust / gnorm;
131a7e14dcfSSatish Balay           }
132a7e14dcfSSatish Balay 
1339566063dSJacob Faibussowitsch           PetscCall(MatMult(tao->hessian, tao->gradient, tao->stepdirection));
1349566063dSJacob Faibussowitsch           PetscCall(VecDot(tao->gradient, tao->stepdirection, &prered));
135a7e14dcfSSatish Balay 
136a7e14dcfSSatish Balay           prered = tao->trust * (gnorm - 0.5 * tao->trust * prered / (gnorm * gnorm));
137a7e14dcfSSatish Balay           actred = f - ftrial;
1389371c9d4SSatish Balay           if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
139a7e14dcfSSatish Balay             kappa = 1.0;
1409371c9d4SSatish Balay           } else {
141a7e14dcfSSatish Balay             kappa = actred / prered;
142a7e14dcfSSatish Balay           }
143a7e14dcfSSatish Balay 
144a7e14dcfSSatish Balay           tau_1   = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust + (1.0 - tr->theta_i) * prered - actred);
145a7e14dcfSSatish Balay           tau_2   = tr->theta_i * gnorm * tao->trust / (tr->theta_i * gnorm * tao->trust - (1.0 + tr->theta_i) * prered + actred);
146a7e14dcfSSatish Balay           tau_min = PetscMin(tau_1, tau_2);
147a7e14dcfSSatish Balay           tau_max = PetscMax(tau_1, tau_2);
148a7e14dcfSSatish Balay 
14918cfbf8eSSatish Balay           if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu1_i) {
150a7e14dcfSSatish Balay             /*  Great agreement */
151a7e14dcfSSatish Balay             max_radius = PetscMax(max_radius, tao->trust);
152a7e14dcfSSatish Balay 
153a7e14dcfSSatish Balay             if (tau_max < 1.0) {
154a7e14dcfSSatish Balay               tau = tr->gamma3_i;
1559371c9d4SSatish Balay             } else if (tau_max > tr->gamma4_i) {
156a7e14dcfSSatish Balay               tau = tr->gamma4_i;
1579371c9d4SSatish Balay             } else {
158a7e14dcfSSatish Balay               tau = tau_max;
159a7e14dcfSSatish Balay             }
1609371c9d4SSatish Balay           } else if (PetscAbsScalar(kappa - (PetscReal)1.0) <= tr->mu2_i) {
161a7e14dcfSSatish Balay             /*  Good agreement */
162a7e14dcfSSatish Balay             max_radius = PetscMax(max_radius, tao->trust);
163a7e14dcfSSatish Balay 
164a7e14dcfSSatish Balay             if (tau_max < tr->gamma2_i) {
165a7e14dcfSSatish Balay               tau = tr->gamma2_i;
1669371c9d4SSatish Balay             } else if (tau_max > tr->gamma3_i) {
167a7e14dcfSSatish Balay               tau = tr->gamma3_i;
1689371c9d4SSatish Balay             } else {
169a7e14dcfSSatish Balay               tau = tau_max;
170a7e14dcfSSatish Balay             }
1719371c9d4SSatish Balay           } else {
172a7e14dcfSSatish Balay             /*  Not good agreement */
173a7e14dcfSSatish Balay             if (tau_min > 1.0) {
174a7e14dcfSSatish Balay               tau = tr->gamma2_i;
1759371c9d4SSatish Balay             } else if (tau_max < tr->gamma1_i) {
176a7e14dcfSSatish Balay               tau = tr->gamma1_i;
1779371c9d4SSatish Balay             } else if ((tau_min < tr->gamma1_i) && (tau_max >= 1.0)) {
178a7e14dcfSSatish Balay               tau = tr->gamma1_i;
1799371c9d4SSatish Balay             } else if ((tau_1 >= tr->gamma1_i) && (tau_1 < 1.0) && ((tau_2 < tr->gamma1_i) || (tau_2 >= 1.0))) {
180a7e14dcfSSatish Balay               tau = tau_1;
1819371c9d4SSatish Balay             } else if ((tau_2 >= tr->gamma1_i) && (tau_2 < 1.0) && ((tau_1 < tr->gamma1_i) || (tau_2 >= 1.0))) {
182a7e14dcfSSatish Balay               tau = tau_2;
1839371c9d4SSatish Balay             } else {
184a7e14dcfSSatish Balay               tau = tau_max;
185a7e14dcfSSatish Balay             }
186a7e14dcfSSatish Balay           }
187a7e14dcfSSatish Balay         }
188a7e14dcfSSatish Balay         tao->trust = tau * tao->trust;
189a7e14dcfSSatish Balay       }
190a7e14dcfSSatish Balay 
191a7e14dcfSSatish Balay       if (fmin < f) {
192a7e14dcfSSatish Balay         f = fmin;
1939566063dSJacob Faibussowitsch         PetscCall(VecAXPY(tao->solution, sigma, tao->gradient));
1949566063dSJacob Faibussowitsch         PetscCall(TaoComputeGradient(tao, tao->solution, tao->gradient));
195a7e14dcfSSatish Balay 
1969566063dSJacob Faibussowitsch         PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
1973c859ba3SBarry Smith         PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
198a7e14dcfSSatish Balay         needH = 1;
199a7e14dcfSSatish Balay 
2009566063dSJacob Faibussowitsch         PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
2019566063dSJacob Faibussowitsch         PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, 1.0));
202dbbe0bcdSBarry Smith         PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
203ad540459SPierre Jolivet         if (tao->reason != TAO_CONTINUE_ITERATING) PetscFunctionReturn(0);
204a7e14dcfSSatish Balay       }
205a7e14dcfSSatish Balay     }
206a7e14dcfSSatish Balay     tao->trust = PetscMax(tao->trust, max_radius);
207a7e14dcfSSatish Balay 
208a7e14dcfSSatish Balay     /*  Modify the radius if it is too large or small */
209a7e14dcfSSatish Balay     tao->trust = PetscMax(tao->trust, tr->min_radius);
210a7e14dcfSSatish Balay     tao->trust = PetscMin(tao->trust, tr->max_radius);
211a7e14dcfSSatish Balay     break;
212a7e14dcfSSatish Balay 
213a7e14dcfSSatish Balay   default:
214a7e14dcfSSatish Balay     /*  Norm of the first direction will initialize radius */
215a7e14dcfSSatish Balay     tao->trust = 0.0;
216a7e14dcfSSatish Balay     break;
217a7e14dcfSSatish Balay   }
218a7e14dcfSSatish Balay 
219a7e14dcfSSatish Balay   /* Have not converged; continue with Newton method */
2203ecd9318SAlp Dener   while (tao->reason == TAO_CONTINUE_ITERATING) {
221e1e80dc8SAlp Dener     /* Call general purpose update function */
222dbbe0bcdSBarry Smith     PetscTryTypeMethod(tao, update, tao->niter, tao->user_update);
2238931d482SJason Sarich     ++tao->niter;
224ae93cb3cSJason Sarich     tao->ksp_its = 0;
225a7e14dcfSSatish Balay     /* Compute the Hessian */
226a7e14dcfSSatish Balay     if (needH) {
2279566063dSJacob Faibussowitsch       PetscCall(TaoComputeHessian(tao, tao->solution, tao->hessian, tao->hessian_pre));
228a7e14dcfSSatish Balay       needH = 0;
229a7e14dcfSSatish Balay     }
230a7e14dcfSSatish Balay 
2310c51296cSAlp Dener     if (tr->bfgs_pre) {
232a7e14dcfSSatish Balay       /* Update the limited memory preconditioner */
2339566063dSJacob Faibussowitsch       PetscCall(MatLMVMUpdate(tr->M, tao->solution, tao->gradient));
234a7e14dcfSSatish Balay     }
235a7e14dcfSSatish Balay 
2363ecd9318SAlp Dener     while (tao->reason == TAO_CONTINUE_ITERATING) {
2379566063dSJacob Faibussowitsch       PetscCall(KSPSetOperators(tao->ksp, tao->hessian, tao->hessian_pre));
238a7e14dcfSSatish Balay 
239a7e14dcfSSatish Balay       /* Solve the trust region subproblem */
2409566063dSJacob Faibussowitsch       PetscCall(KSPCGSetRadius(tao->ksp, tao->trust));
2419566063dSJacob Faibussowitsch       PetscCall(KSPSolve(tao->ksp, tao->gradient, tao->stepdirection));
2429566063dSJacob Faibussowitsch       PetscCall(KSPGetIterationNumber(tao->ksp, &its));
243a7e14dcfSSatish Balay       tao->ksp_its += its;
244ae93cb3cSJason Sarich       tao->ksp_tot_its += its;
2459566063dSJacob Faibussowitsch       PetscCall(KSPCGGetNormD(tao->ksp, &norm_d));
246a7e14dcfSSatish Balay 
247a7e14dcfSSatish Balay       if (0.0 == tao->trust) {
248a7e14dcfSSatish Balay         /* Radius was uninitialized; use the norm of the direction */
249a7e14dcfSSatish Balay         if (norm_d > 0.0) {
250a7e14dcfSSatish Balay           tao->trust = norm_d;
251a7e14dcfSSatish Balay 
252a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
253a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, tr->min_radius);
254a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, tr->max_radius);
2559371c9d4SSatish Balay         } else {
256a7e14dcfSSatish Balay           /* The direction was bad; set radius to default value and re-solve
257a7e14dcfSSatish Balay              the trust-region subproblem to get a direction */
258a7e14dcfSSatish Balay           tao->trust = tao->trust0;
259a7e14dcfSSatish Balay 
260a7e14dcfSSatish Balay           /* Modify the radius if it is too large or small */
261a7e14dcfSSatish Balay           tao->trust = PetscMax(tao->trust, tr->min_radius);
262a7e14dcfSSatish Balay           tao->trust = PetscMin(tao->trust, tr->max_radius);
263a7e14dcfSSatish Balay 
2649566063dSJacob Faibussowitsch           PetscCall(KSPCGSetRadius(tao->ksp, tao->trust));
2659566063dSJacob Faibussowitsch           PetscCall(KSPSolve(tao->ksp, tao->gradient, tao->stepdirection));
2669566063dSJacob Faibussowitsch           PetscCall(KSPGetIterationNumber(tao->ksp, &its));
267a7e14dcfSSatish Balay           tao->ksp_its += its;
2682d9aa51bSJason Sarich           tao->ksp_tot_its += its;
2699566063dSJacob Faibussowitsch           PetscCall(KSPCGGetNormD(tao->ksp, &norm_d));
270a7e14dcfSSatish Balay 
2713c859ba3SBarry Smith           PetscCheck(norm_d != 0.0, PetscObjectComm((PetscObject)tao), PETSC_ERR_PLIB, "Initial direction zero");
272a7e14dcfSSatish Balay         }
273a7e14dcfSSatish Balay       }
2749566063dSJacob Faibussowitsch       PetscCall(VecScale(tao->stepdirection, -1.0));
2759566063dSJacob Faibussowitsch       PetscCall(KSPGetConvergedReason(tao->ksp, &ksp_reason));
2760c51296cSAlp Dener       if ((KSP_DIVERGED_INDEFINITE_PC == ksp_reason) && (tr->bfgs_pre)) {
277a7e14dcfSSatish Balay         /* Preconditioner is numerically indefinite; reset the
278a7e14dcfSSatish Balay            approximate if using BFGS preconditioning. */
2799566063dSJacob Faibussowitsch         PetscCall(MatLMVMReset(tr->M, PETSC_FALSE));
2809566063dSJacob Faibussowitsch         PetscCall(MatLMVMUpdate(tr->M, tao->solution, tao->gradient));
281a7e14dcfSSatish Balay       }
282a7e14dcfSSatish Balay 
283a7e14dcfSSatish Balay       if (NTR_UPDATE_REDUCTION == tr->update_type) {
284a7e14dcfSSatish Balay         /* Get predicted reduction */
2859566063dSJacob Faibussowitsch         PetscCall(KSPCGGetObjFcn(tao->ksp, &prered));
286a7e14dcfSSatish Balay         if (prered >= 0.0) {
287a7e14dcfSSatish Balay           /* The predicted reduction has the wrong sign.  This cannot
288a7e14dcfSSatish Balay              happen in infinite precision arithmetic.  Step should
289a7e14dcfSSatish Balay              be rejected! */
290a7e14dcfSSatish Balay           tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
2919371c9d4SSatish Balay         } else {
292a7e14dcfSSatish Balay           /* Compute trial step and function value */
2939566063dSJacob Faibussowitsch           PetscCall(VecCopy(tao->solution, tr->W));
2949566063dSJacob Faibussowitsch           PetscCall(VecAXPY(tr->W, 1.0, tao->stepdirection));
2959566063dSJacob Faibussowitsch           PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
296a7e14dcfSSatish Balay 
297a7e14dcfSSatish Balay           if (PetscIsInfOrNanReal(ftrial)) {
298a7e14dcfSSatish Balay             tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
299a7e14dcfSSatish Balay           } else {
300a7e14dcfSSatish Balay             /* Compute and actual reduction */
301a7e14dcfSSatish Balay             actred = f - ftrial;
302a7e14dcfSSatish Balay             prered = -prered;
3039371c9d4SSatish Balay             if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
304a7e14dcfSSatish Balay               kappa = 1.0;
3059371c9d4SSatish Balay             } else {
306a7e14dcfSSatish Balay               kappa = actred / prered;
307a7e14dcfSSatish Balay             }
308a7e14dcfSSatish Balay 
309a7e14dcfSSatish Balay             /* Accept or reject the step and update radius */
310a7e14dcfSSatish Balay             if (kappa < tr->eta1) {
311a7e14dcfSSatish Balay               /* Reject the step */
312a7e14dcfSSatish Balay               tao->trust = tr->alpha1 * PetscMin(tao->trust, norm_d);
3139371c9d4SSatish Balay             } else {
314a7e14dcfSSatish Balay               /* Accept the step */
315a7e14dcfSSatish Balay               if (kappa < tr->eta2) {
316a7e14dcfSSatish Balay                 /* Marginal bad step */
317a7e14dcfSSatish Balay                 tao->trust = tr->alpha2 * PetscMin(tao->trust, norm_d);
3189371c9d4SSatish Balay               } else if (kappa < tr->eta3) {
319a7e14dcfSSatish Balay                 /* Reasonable step */
320a7e14dcfSSatish Balay                 tao->trust = tr->alpha3 * tao->trust;
3219371c9d4SSatish Balay               } else if (kappa < tr->eta4) {
322a7e14dcfSSatish Balay                 /* Good step */
323a7e14dcfSSatish Balay                 tao->trust = PetscMax(tr->alpha4 * norm_d, tao->trust);
3249371c9d4SSatish Balay               } else {
325a7e14dcfSSatish Balay                 /* Very good step */
326a7e14dcfSSatish Balay                 tao->trust = PetscMax(tr->alpha5 * norm_d, tao->trust);
327a7e14dcfSSatish Balay               }
328a7e14dcfSSatish Balay               break;
329a7e14dcfSSatish Balay             }
330a7e14dcfSSatish Balay           }
331a7e14dcfSSatish Balay         }
3329371c9d4SSatish Balay       } else {
333a7e14dcfSSatish Balay         /* Get predicted reduction */
3349566063dSJacob Faibussowitsch         PetscCall(KSPCGGetObjFcn(tao->ksp, &prered));
335a7e14dcfSSatish Balay         if (prered >= 0.0) {
336a7e14dcfSSatish Balay           /* The predicted reduction has the wrong sign.  This cannot
337a7e14dcfSSatish Balay              happen in infinite precision arithmetic.  Step should
338a7e14dcfSSatish Balay              be rejected! */
339a7e14dcfSSatish Balay           tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3409371c9d4SSatish Balay         } else {
3419566063dSJacob Faibussowitsch           PetscCall(VecCopy(tao->solution, tr->W));
3429566063dSJacob Faibussowitsch           PetscCall(VecAXPY(tr->W, 1.0, tao->stepdirection));
3439566063dSJacob Faibussowitsch           PetscCall(TaoComputeObjective(tao, tr->W, &ftrial));
344a7e14dcfSSatish Balay           if (PetscIsInfOrNanReal(ftrial)) {
345a7e14dcfSSatish Balay             tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3469371c9d4SSatish Balay           } else {
3479566063dSJacob Faibussowitsch             PetscCall(VecDot(tao->gradient, tao->stepdirection, &beta));
348a7e14dcfSSatish Balay             actred = f - ftrial;
349a7e14dcfSSatish Balay             prered = -prered;
3509371c9d4SSatish Balay             if ((PetscAbsScalar(actred) <= tr->epsilon) && (PetscAbsScalar(prered) <= tr->epsilon)) {
351a7e14dcfSSatish Balay               kappa = 1.0;
3529371c9d4SSatish Balay             } else {
353a7e14dcfSSatish Balay               kappa = actred / prered;
354a7e14dcfSSatish Balay             }
355a7e14dcfSSatish Balay 
356a7e14dcfSSatish Balay             tau_1   = tr->theta * beta / (tr->theta * beta - (1.0 - tr->theta) * prered + actred);
357a7e14dcfSSatish Balay             tau_2   = tr->theta * beta / (tr->theta * beta + (1.0 + tr->theta) * prered - actred);
358a7e14dcfSSatish Balay             tau_min = PetscMin(tau_1, tau_2);
359a7e14dcfSSatish Balay             tau_max = PetscMax(tau_1, tau_2);
360a7e14dcfSSatish Balay 
361a7e14dcfSSatish Balay             if (kappa >= 1.0 - tr->mu1) {
362a7e14dcfSSatish Balay               /* Great agreement; accept step and update radius */
363a7e14dcfSSatish Balay               if (tau_max < 1.0) {
364a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d);
3659371c9d4SSatish Balay               } else if (tau_max > tr->gamma4) {
366a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma4 * norm_d);
3679371c9d4SSatish Balay               } else {
368a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tau_max * norm_d);
369a7e14dcfSSatish Balay               }
370a7e14dcfSSatish Balay               break;
3719371c9d4SSatish Balay             } else if (kappa >= 1.0 - tr->mu2) {
372a7e14dcfSSatish Balay               /* Good agreement */
373a7e14dcfSSatish Balay 
374a7e14dcfSSatish Balay               if (tau_max < tr->gamma2) {
375a7e14dcfSSatish Balay                 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d);
3769371c9d4SSatish Balay               } else if (tau_max > tr->gamma3) {
377a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tr->gamma3 * norm_d);
3789371c9d4SSatish Balay               } else if (tau_max < 1.0) {
379a7e14dcfSSatish Balay                 tao->trust = tau_max * PetscMin(tao->trust, norm_d);
3809371c9d4SSatish Balay               } else {
381a7e14dcfSSatish Balay                 tao->trust = PetscMax(tao->trust, tau_max * norm_d);
382a7e14dcfSSatish Balay               }
383a7e14dcfSSatish Balay               break;
3849371c9d4SSatish Balay             } else {
385a7e14dcfSSatish Balay               /* Not good agreement */
386a7e14dcfSSatish Balay               if (tau_min > 1.0) {
387a7e14dcfSSatish Balay                 tao->trust = tr->gamma2 * PetscMin(tao->trust, norm_d);
3889371c9d4SSatish Balay               } else if (tau_max < tr->gamma1) {
389a7e14dcfSSatish Balay                 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3909371c9d4SSatish Balay               } else if ((tau_min < tr->gamma1) && (tau_max >= 1.0)) {
391a7e14dcfSSatish Balay                 tao->trust = tr->gamma1 * PetscMin(tao->trust, norm_d);
3929371c9d4SSatish Balay               } else if ((tau_1 >= tr->gamma1) && (tau_1 < 1.0) && ((tau_2 < tr->gamma1) || (tau_2 >= 1.0))) {
393a7e14dcfSSatish Balay                 tao->trust = tau_1 * PetscMin(tao->trust, norm_d);
3949371c9d4SSatish Balay               } else if ((tau_2 >= tr->gamma1) && (tau_2 < 1.0) && ((tau_1 < tr->gamma1) || (tau_2 >= 1.0))) {
395a7e14dcfSSatish Balay                 tao->trust = tau_2 * PetscMin(tao->trust, norm_d);
3969371c9d4SSatish Balay               } else {
397a7e14dcfSSatish Balay                 tao->trust = tau_max * PetscMin(tao->trust, norm_d);
398a7e14dcfSSatish Balay               }
399a7e14dcfSSatish Balay             }
400a7e14dcfSSatish Balay           }
401a7e14dcfSSatish Balay         }
402a7e14dcfSSatish Balay       }
403a7e14dcfSSatish Balay 
404a7e14dcfSSatish Balay       /* The step computed was not good and the radius was decreased.
405a7e14dcfSSatish Balay          Monitor the radius to terminate. */
4069566063dSJacob Faibussowitsch       PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
4079566063dSJacob Faibussowitsch       PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, tao->trust));
408dbbe0bcdSBarry Smith       PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
409a7e14dcfSSatish Balay     }
410a7e14dcfSSatish Balay 
411a7e14dcfSSatish Balay     /* The radius may have been increased; modify if it is too large */
412a7e14dcfSSatish Balay     tao->trust = PetscMin(tao->trust, tr->max_radius);
413a7e14dcfSSatish Balay 
4143ecd9318SAlp Dener     if (tao->reason == TAO_CONTINUE_ITERATING) {
4159566063dSJacob Faibussowitsch       PetscCall(VecCopy(tr->W, tao->solution));
416a7e14dcfSSatish Balay       f = ftrial;
4179566063dSJacob Faibussowitsch       PetscCall(TaoComputeGradient(tao, tao->solution, tao->gradient));
4189566063dSJacob Faibussowitsch       PetscCall(TaoGradientNorm(tao, tao->gradient, NORM_2, &gnorm));
4193c859ba3SBarry Smith       PetscCheck(!PetscIsInfOrNanReal(f) && !PetscIsInfOrNanReal(gnorm), PetscObjectComm((PetscObject)tao), PETSC_ERR_USER, "User provided compute function generated Inf or NaN");
420a7e14dcfSSatish Balay       needH = 1;
4219566063dSJacob Faibussowitsch       PetscCall(TaoLogConvergenceHistory(tao, f, gnorm, 0.0, tao->ksp_its));
4229566063dSJacob Faibussowitsch       PetscCall(TaoMonitor(tao, tao->niter, f, gnorm, 0.0, tao->trust));
423dbbe0bcdSBarry Smith       PetscUseTypeMethod(tao, convergencetest, tao->cnvP);
424a7e14dcfSSatish Balay     }
425a7e14dcfSSatish Balay   }
426a7e14dcfSSatish Balay   PetscFunctionReturn(0);
427a7e14dcfSSatish Balay }
428a7e14dcfSSatish Balay 
429a7e14dcfSSatish Balay /*------------------------------------------------------------*/
4309371c9d4SSatish Balay static PetscErrorCode TaoSetUp_NTR(Tao tao) {
431a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
432a7e14dcfSSatish Balay 
433a7e14dcfSSatish Balay   PetscFunctionBegin;
4349566063dSJacob Faibussowitsch   if (!tao->gradient) PetscCall(VecDuplicate(tao->solution, &tao->gradient));
4359566063dSJacob Faibussowitsch   if (!tao->stepdirection) PetscCall(VecDuplicate(tao->solution, &tao->stepdirection));
4369566063dSJacob Faibussowitsch   if (!tr->W) PetscCall(VecDuplicate(tao->solution, &tr->W));
437a7e14dcfSSatish Balay 
43883c8fe1dSLisandro Dalcin   tr->bfgs_pre = NULL;
43983c8fe1dSLisandro Dalcin   tr->M        = NULL;
440a7e14dcfSSatish Balay   PetscFunctionReturn(0);
441a7e14dcfSSatish Balay }
442a7e14dcfSSatish Balay 
443a7e14dcfSSatish Balay /*------------------------------------------------------------*/
4449371c9d4SSatish Balay static PetscErrorCode TaoDestroy_NTR(Tao tao) {
445a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
446a7e14dcfSSatish Balay 
447a7e14dcfSSatish Balay   PetscFunctionBegin;
44848a46eb9SPierre Jolivet   if (tao->setupcalled) PetscCall(VecDestroy(&tr->W));
449a958fbfcSStefano Zampini   PetscCall(KSPDestroy(&tao->ksp));
4509566063dSJacob Faibussowitsch   PetscCall(PetscFree(tao->data));
451a7e14dcfSSatish Balay   PetscFunctionReturn(0);
452a7e14dcfSSatish Balay }
453a7e14dcfSSatish Balay 
454a7e14dcfSSatish Balay /*------------------------------------------------------------*/
4559371c9d4SSatish Balay static PetscErrorCode TaoSetFromOptions_NTR(Tao tao, PetscOptionItems *PetscOptionsObject) {
456a7e14dcfSSatish Balay   TAO_NTR *tr = (TAO_NTR *)tao->data;
457a7e14dcfSSatish Balay 
458a7e14dcfSSatish Balay   PetscFunctionBegin;
459d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Newton trust region method for unconstrained optimization");
4609566063dSJacob 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));
4619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-tao_ntr_update_type", "radius update type", "", NTR_UPDATE, NTR_UPDATE_TYPES, NTR_UPDATE[tr->update_type], &tr->update_type, NULL));
4629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta1", "step is unsuccessful if actual reduction < eta1 * predicted reduction", "", tr->eta1, &tr->eta1, NULL));
4639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta2", "", "", tr->eta2, &tr->eta2, NULL));
4649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta3", "", "", tr->eta3, &tr->eta3, NULL));
4659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_eta4", "", "", tr->eta4, &tr->eta4, NULL));
4669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha1", "", "", tr->alpha1, &tr->alpha1, NULL));
4679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha2", "", "", tr->alpha2, &tr->alpha2, NULL));
4689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha3", "", "", tr->alpha3, &tr->alpha3, NULL));
4699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha4", "", "", tr->alpha4, &tr->alpha4, NULL));
4709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_alpha5", "", "", tr->alpha5, &tr->alpha5, NULL));
4719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu1", "", "", tr->mu1, &tr->mu1, NULL));
4729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu2", "", "", tr->mu2, &tr->mu2, NULL));
4739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma1", "", "", tr->gamma1, &tr->gamma1, NULL));
4749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma2", "", "", tr->gamma2, &tr->gamma2, NULL));
4759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma3", "", "", tr->gamma3, &tr->gamma3, NULL));
4769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma4", "", "", tr->gamma4, &tr->gamma4, NULL));
4779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_theta", "", "", tr->theta, &tr->theta, NULL));
4789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu1_i", "", "", tr->mu1_i, &tr->mu1_i, NULL));
4799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_mu2_i", "", "", tr->mu2_i, &tr->mu2_i, NULL));
4809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma1_i", "", "", tr->gamma1_i, &tr->gamma1_i, NULL));
4819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma2_i", "", "", tr->gamma2_i, &tr->gamma2_i, NULL));
4829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma3_i", "", "", tr->gamma3_i, &tr->gamma3_i, NULL));
4839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_gamma4_i", "", "", tr->gamma4_i, &tr->gamma4_i, NULL));
4849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_theta_i", "", "", tr->theta_i, &tr->theta_i, NULL));
4859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_min_radius", "lower bound on initial trust-region radius", "", tr->min_radius, &tr->min_radius, NULL));
4869566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_max_radius", "upper bound on trust-region radius", "", tr->max_radius, &tr->max_radius, NULL));
4879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-tao_ntr_epsilon", "tolerance used when computing actual and predicted reduction", "", tr->epsilon, &tr->epsilon, NULL));
488d0609cedSBarry Smith   PetscOptionsHeadEnd();
4899566063dSJacob Faibussowitsch   PetscCall(KSPSetFromOptions(tao->ksp));
490a7e14dcfSSatish Balay   PetscFunctionReturn(0);
491a7e14dcfSSatish Balay }
492a7e14dcfSSatish Balay 
493a7e14dcfSSatish Balay /*------------------------------------------------------------*/
4941522df2eSJason Sarich /*MC
4951522df2eSJason Sarich   TAONTR - Newton's method with trust region for unconstrained minimization.
4961522df2eSJason Sarich   At each iteration, the Newton trust region method solves the system.
4971522df2eSJason Sarich   NTR expects a KSP solver with a trust region radius.
4981522df2eSJason Sarich             min_d  .5 dT Hk d + gkT d,  s.t.   ||d|| < Delta_k
4991522df2eSJason Sarich 
5001522df2eSJason Sarich   Options Database Keys:
5019d0a60b2SAlp Dener + -tao_ntr_init_type - "constant","direction","interpolation"
5021522df2eSJason Sarich . -tao_ntr_update_type - "reduction","interpolation"
5031522df2eSJason Sarich . -tao_ntr_min_radius - lower bound on trust region radius
5041522df2eSJason Sarich . -tao_ntr_max_radius - upper bound on trust region radius
5051522df2eSJason Sarich . -tao_ntr_epsilon - tolerance for accepting actual / predicted reduction
5061522df2eSJason Sarich . -tao_ntr_mu1_i - mu1 interpolation init factor
5071522df2eSJason Sarich . -tao_ntr_mu2_i - mu2 interpolation init factor
5081522df2eSJason Sarich . -tao_ntr_gamma1_i - gamma1 interpolation init factor
5091522df2eSJason Sarich . -tao_ntr_gamma2_i - gamma2 interpolation init factor
5101522df2eSJason Sarich . -tao_ntr_gamma3_i - gamma3 interpolation init factor
5111522df2eSJason Sarich . -tao_ntr_gamma4_i - gamma4 interpolation init factor
5128966356dSPierre Jolivet . -tao_ntr_theta_i - theta1 interpolation init factor
5131522df2eSJason Sarich . -tao_ntr_eta1 - eta1 reduction update factor
5141522df2eSJason Sarich . -tao_ntr_eta2 - eta2 reduction update factor
5151522df2eSJason Sarich . -tao_ntr_eta3 - eta3 reduction update factor
5161522df2eSJason Sarich . -tao_ntr_eta4 - eta4 reduction update factor
5171522df2eSJason Sarich . -tao_ntr_alpha1 - alpha1 reduction update factor
5181522df2eSJason Sarich . -tao_ntr_alpha2 - alpha2 reduction update factor
5191522df2eSJason Sarich . -tao_ntr_alpha3 - alpha3 reduction update factor
5201522df2eSJason Sarich . -tao_ntr_alpha4 - alpha4 reduction update factor
5211522df2eSJason Sarich . -tao_ntr_alpha4 - alpha4 reduction update factor
5221522df2eSJason Sarich . -tao_ntr_mu1 - mu1 interpolation update
5231522df2eSJason Sarich . -tao_ntr_mu2 - mu2 interpolation update
5241522df2eSJason Sarich . -tao_ntr_gamma1 - gamma1 interpolcation update
5251522df2eSJason Sarich . -tao_ntr_gamma2 - gamma2 interpolcation update
5261522df2eSJason Sarich . -tao_ntr_gamma3 - gamma3 interpolcation update
5271522df2eSJason Sarich . -tao_ntr_gamma4 - gamma4 interpolation update
5281522df2eSJason Sarich - -tao_ntr_theta - theta interpolation update
5291522df2eSJason Sarich 
5301eb8069cSJason Sarich   Level: beginner
5311522df2eSJason Sarich M*/
5321522df2eSJason Sarich 
5339371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode TaoCreate_NTR(Tao tao) {
534a7e14dcfSSatish Balay   TAO_NTR *tr;
535a7e14dcfSSatish Balay 
536a7e14dcfSSatish Balay   PetscFunctionBegin;
537a7e14dcfSSatish Balay 
538*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&tr));
539a7e14dcfSSatish Balay 
540a7e14dcfSSatish Balay   tao->ops->setup          = TaoSetUp_NTR;
541a7e14dcfSSatish Balay   tao->ops->solve          = TaoSolve_NTR;
542a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_NTR;
543a7e14dcfSSatish Balay   tao->ops->destroy        = TaoDestroy_NTR;
544a7e14dcfSSatish Balay 
5456552cf8aSJason Sarich   /* Override default settings (unless already changed) */
5466552cf8aSJason Sarich   if (!tao->max_it_changed) tao->max_it = 50;
5476552cf8aSJason Sarich   if (!tao->trust0_changed) tao->trust0 = 100.0;
548a7e14dcfSSatish Balay   tao->data = (void *)tr;
549a7e14dcfSSatish Balay 
550a7e14dcfSSatish Balay   /*  Standard trust region update parameters */
551a7e14dcfSSatish Balay   tr->eta1 = 1.0e-4;
552a7e14dcfSSatish Balay   tr->eta2 = 0.25;
553a7e14dcfSSatish Balay   tr->eta3 = 0.50;
554a7e14dcfSSatish Balay   tr->eta4 = 0.90;
555a7e14dcfSSatish Balay 
556a7e14dcfSSatish Balay   tr->alpha1 = 0.25;
557a7e14dcfSSatish Balay   tr->alpha2 = 0.50;
558a7e14dcfSSatish Balay   tr->alpha3 = 1.00;
559a7e14dcfSSatish Balay   tr->alpha4 = 2.00;
560a7e14dcfSSatish Balay   tr->alpha5 = 4.00;
561a7e14dcfSSatish Balay 
562a7e14dcfSSatish Balay   /*  Interpolation trust region update parameters */
563a7e14dcfSSatish Balay   tr->mu1 = 0.10;
564a7e14dcfSSatish Balay   tr->mu2 = 0.50;
565a7e14dcfSSatish Balay 
566a7e14dcfSSatish Balay   tr->gamma1 = 0.25;
567a7e14dcfSSatish Balay   tr->gamma2 = 0.50;
568a7e14dcfSSatish Balay   tr->gamma3 = 2.00;
569a7e14dcfSSatish Balay   tr->gamma4 = 4.00;
570a7e14dcfSSatish Balay 
571a7e14dcfSSatish Balay   tr->theta = 0.05;
572a7e14dcfSSatish Balay 
573fb90e4d1STodd Munson   /*  Interpolation parameters for initialization */
574fb90e4d1STodd Munson   tr->mu1_i = 0.35;
575fb90e4d1STodd Munson   tr->mu2_i = 0.50;
576fb90e4d1STodd Munson 
577fb90e4d1STodd Munson   tr->gamma1_i = 0.0625;
578fb90e4d1STodd Munson   tr->gamma2_i = 0.50;
579fb90e4d1STodd Munson   tr->gamma3_i = 2.00;
580fb90e4d1STodd Munson   tr->gamma4_i = 5.00;
581fb90e4d1STodd Munson 
582fb90e4d1STodd Munson   tr->theta_i = 0.25;
583fb90e4d1STodd Munson 
584a7e14dcfSSatish Balay   tr->min_radius = 1.0e-10;
585a7e14dcfSSatish Balay   tr->max_radius = 1.0e10;
586a7e14dcfSSatish Balay   tr->epsilon    = 1.0e-6;
587a7e14dcfSSatish Balay 
588a7e14dcfSSatish Balay   tr->init_type   = NTR_INIT_INTERPOLATION;
589a7e14dcfSSatish Balay   tr->update_type = NTR_UPDATE_REDUCTION;
590a7e14dcfSSatish Balay 
591a7e14dcfSSatish Balay   /* Set linear solver to default for trust region */
5929566063dSJacob Faibussowitsch   PetscCall(KSPCreate(((PetscObject)tao)->comm, &tao->ksp));
5939566063dSJacob Faibussowitsch   PetscCall(PetscObjectIncrementTabLevel((PetscObject)tao->ksp, (PetscObject)tao, 1));
5949566063dSJacob Faibussowitsch   PetscCall(KSPSetOptionsPrefix(tao->ksp, tao->hdr.prefix));
5959566063dSJacob Faibussowitsch   PetscCall(KSPAppendOptionsPrefix(tao->ksp, "tao_ntr_"));
5969566063dSJacob Faibussowitsch   PetscCall(KSPSetType(tao->ksp, KSPSTCG));
597a7e14dcfSSatish Balay   PetscFunctionReturn(0);
598a7e14dcfSSatish Balay }
599