xref: /petsc/src/tao/linesearch/impls/owarmijo/owarmijo.c (revision 1a1499c8e13c12f02cf4c59cfd6b0cfcce01ae9b)
1f273b952SBarry Smith 
2aaa7dc30SBarry Smith #include <petsc-private/taolinesearchimpl.h>
3aaa7dc30SBarry Smith #include <../src/tao/linesearch/impls/owarmijo/owarmijo.h>
4a7e14dcfSSatish Balay 
5a7e14dcfSSatish Balay #define REPLACE_FIFO 1
6a7e14dcfSSatish Balay #define REPLACE_MRU  2
7a7e14dcfSSatish Balay 
8a7e14dcfSSatish Balay #define REFERENCE_MAX  1
9a7e14dcfSSatish Balay #define REFERENCE_AVE  2
10a7e14dcfSSatish Balay #define REFERENCE_MEAN 3
11a7e14dcfSSatish Balay 
12a7e14dcfSSatish Balay static PetscErrorCode ProjWork_OWLQN(Vec w,Vec x,Vec gv,PetscReal *gdx)
13a7e14dcfSSatish Balay {
145e081366SBarry Smith   const PetscReal *xptr,*gptr;
155e081366SBarry Smith   PetscReal       *wptr;
16a7e14dcfSSatish Balay   PetscErrorCode  ierr;
17a7e14dcfSSatish Balay   PetscInt        low,high,low1,high1,low2,high2,i;
18a7e14dcfSSatish Balay 
19a7e14dcfSSatish Balay   PetscFunctionBegin;
20a7e14dcfSSatish Balay   ierr=VecGetOwnershipRange(w,&low,&high);CHKERRQ(ierr);
21a7e14dcfSSatish Balay   ierr=VecGetOwnershipRange(x,&low1,&high1);CHKERRQ(ierr);
22a7e14dcfSSatish Balay   ierr=VecGetOwnershipRange(gv,&low2,&high2);CHKERRQ(ierr);
23a7e14dcfSSatish Balay 
24a7e14dcfSSatish Balay   *gdx=0.0;
25a7e14dcfSSatish Balay   ierr = VecGetArray(w,&wptr);CHKERRQ(ierr);
265e081366SBarry Smith   ierr = VecGetArrayRead(x,&xptr);CHKERRQ(ierr);
275e081366SBarry Smith   ierr = VecGetArrayRead(gv,&gptr);CHKERRQ(ierr);
28a7e14dcfSSatish Balay 
2953506e15SBarry Smith   for (i=0;i<high-low;i++) {
305e081366SBarry Smith     if (xptr[i]*wptr[i]<0.0) wptr[i]=0.0;
31a7e14dcfSSatish Balay     *gdx = *gdx + gptr[i]*(wptr[i]-xptr[i]);
32a7e14dcfSSatish Balay   }
33a7e14dcfSSatish Balay   ierr = VecRestoreArray(w,&wptr);CHKERRQ(ierr);
345e081366SBarry Smith   ierr = VecRestoreArrayRead(x,&xptr);CHKERRQ(ierr);
355e081366SBarry Smith   ierr = VecRestoreArrayRead(gv,&gptr);CHKERRQ(ierr);
36a7e14dcfSSatish Balay   PetscFunctionReturn(0);
37a7e14dcfSSatish Balay }
38a7e14dcfSSatish Balay 
39a7e14dcfSSatish Balay #undef __FUNCT__
40a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchDestroy_OWArmijo"
41a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchDestroy_OWArmijo(TaoLineSearch ls)
42a7e14dcfSSatish Balay {
438caf6e8cSBarry Smith   TaoLineSearch_OWARMIJO *armP = (TaoLineSearch_OWARMIJO *)ls->data;
44a7e14dcfSSatish Balay   PetscErrorCode         ierr;
45a7e14dcfSSatish Balay 
46a7e14dcfSSatish Balay   PetscFunctionBegin;
47a7e14dcfSSatish Balay   ierr = PetscFree(armP->memory);CHKERRQ(ierr);
48a7e14dcfSSatish Balay   if (armP->x) {
49a7e14dcfSSatish Balay     ierr = PetscObjectDereference((PetscObject)armP->x);CHKERRQ(ierr);
50a7e14dcfSSatish Balay   }
51a7e14dcfSSatish Balay   ierr = VecDestroy(&armP->work);CHKERRQ(ierr);
52a7e14dcfSSatish Balay   ierr = PetscFree(ls->data);CHKERRQ(ierr);
53a7e14dcfSSatish Balay   PetscFunctionReturn(0);
54a7e14dcfSSatish Balay }
55a7e14dcfSSatish Balay 
56a7e14dcfSSatish Balay #undef __FUNCT__
57a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchSetFromOptions_OWArmijo"
58*1a1499c8SBarry Smith static PetscErrorCode TaoLineSearchSetFromOptions_OWArmijo(PetscOptionsObjectType *PetscOptionsObject,TaoLineSearch ls)
59a7e14dcfSSatish Balay {
608caf6e8cSBarry Smith   TaoLineSearch_OWARMIJO *armP = (TaoLineSearch_OWARMIJO *)ls->data;
61a7e14dcfSSatish Balay   PetscErrorCode         ierr;
62a7e14dcfSSatish Balay 
63a7e14dcfSSatish Balay   PetscFunctionBegin;
64*1a1499c8SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"OWArmijo linesearch options");CHKERRQ(ierr);
6594ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_ls_OWArmijo_alpha", "initial reference constant", "", armP->alpha, &armP->alpha,NULL);CHKERRQ(ierr);
6694ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_ls_OWArmijo_beta_inf", "decrease constant one", "", armP->beta_inf, &armP->beta_inf,NULL);CHKERRQ(ierr);
6794ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_ls_OWArmijo_beta", "decrease constant", "", armP->beta, &armP->beta,NULL);CHKERRQ(ierr);
6894ae4db5SBarry Smith   ierr = PetscOptionsReal("-tao_ls_OWArmijo_sigma", "acceptance constant", "", armP->sigma, &armP->sigma,NULL);CHKERRQ(ierr);
6994ae4db5SBarry Smith   ierr = PetscOptionsInt("-tao_ls_OWArmijo_memory_size", "number of historical elements", "", armP->memorySize, &armP->memorySize,NULL);CHKERRQ(ierr);
7094ae4db5SBarry Smith   ierr = PetscOptionsInt("-tao_ls_OWArmijo_reference_policy", "policy for updating reference value", "", armP->referencePolicy, &armP->referencePolicy,NULL);CHKERRQ(ierr);
7194ae4db5SBarry Smith   ierr = PetscOptionsInt("-tao_ls_OWArmijo_replacement_policy", "policy for updating memory", "", armP->replacementPolicy, &armP->replacementPolicy,NULL);CHKERRQ(ierr);
7294ae4db5SBarry Smith   ierr = PetscOptionsBool("-tao_ls_OWArmijo_nondescending","Use nondescending OWArmijo algorithm","",armP->nondescending,&armP->nondescending,NULL);CHKERRQ(ierr);
73a7e14dcfSSatish Balay   ierr = PetscOptionsTail();CHKERRQ(ierr);
74a7e14dcfSSatish Balay   PetscFunctionReturn(0);
75a7e14dcfSSatish Balay }
76a7e14dcfSSatish Balay 
77a7e14dcfSSatish Balay #undef __FUNCT__
78a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchView_OWArmijo"
79a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchView_OWArmijo(TaoLineSearch ls, PetscViewer pv)
80a7e14dcfSSatish Balay {
818caf6e8cSBarry Smith   TaoLineSearch_OWARMIJO *armP = (TaoLineSearch_OWARMIJO *)ls->data;
82a7e14dcfSSatish Balay   PetscBool              isascii;
83a7e14dcfSSatish Balay   PetscErrorCode         ierr;
84a7e14dcfSSatish Balay 
85a7e14dcfSSatish Balay   PetscFunctionBegin;
86a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)pv, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
87a7e14dcfSSatish Balay   if (isascii) {
886f4723b1SBarry Smith     ierr = PetscViewerASCIIPrintf(pv,"  maxf=%D, ftol=%g, gtol=%g\n",ls->max_funcs, (double)ls->rtol, (double)ls->ftol);CHKERRQ(ierr);
89a7e14dcfSSatish Balay     ierr=PetscViewerASCIIPrintf(pv,"  OWArmijo linesearch",armP->alpha);CHKERRQ(ierr);
90a7e14dcfSSatish Balay     if (armP->nondescending) {
91a7e14dcfSSatish Balay       ierr = PetscViewerASCIIPrintf(pv, " (nondescending)");CHKERRQ(ierr);
92a7e14dcfSSatish Balay     }
936f4723b1SBarry Smith     ierr=PetscViewerASCIIPrintf(pv,": alpha=%g beta=%g ",(double)armP->alpha,(double)armP->beta);CHKERRQ(ierr);
946f4723b1SBarry Smith     ierr=PetscViewerASCIIPrintf(pv,"sigma=%g ",(double)armP->sigma);CHKERRQ(ierr);
956f4723b1SBarry Smith     ierr=PetscViewerASCIIPrintf(pv,"memsize=%D\n",armP->memorySize);CHKERRQ(ierr);
96a7e14dcfSSatish Balay   }
97a7e14dcfSSatish Balay   PetscFunctionReturn(0);
98a7e14dcfSSatish Balay }
99a7e14dcfSSatish Balay 
100a7e14dcfSSatish Balay #undef __FUNCT__
101a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchApply_OWArmijo"
102a7e14dcfSSatish Balay /* @ TaoApply_OWArmijo - This routine performs a linesearch. It
103a7e14dcfSSatish Balay    backtracks until the (nonmonotone) OWArmijo conditions are satisfied.
104a7e14dcfSSatish Balay 
105a7e14dcfSSatish Balay    Input Parameters:
106a7e14dcfSSatish Balay +  tao - TAO_SOLVER context
107a7e14dcfSSatish Balay .  X - current iterate (on output X contains new iterate, X + step*S)
108a7e14dcfSSatish Balay .  S - search direction
109a7e14dcfSSatish Balay .  f - merit function evaluated at X
110a7e14dcfSSatish Balay .  G - gradient of merit function evaluated at X
111a7e14dcfSSatish Balay .  W - work vector
112a7e14dcfSSatish Balay -  step - initial estimate of step length
113a7e14dcfSSatish Balay 
114a7e14dcfSSatish Balay    Output parameters:
115a7e14dcfSSatish Balay +  f - merit function evaluated at new iterate, X + step*S
116a7e14dcfSSatish Balay .  G - gradient of merit function evaluated at new iterate, X + step*S
117a7e14dcfSSatish Balay .  X - new iterate
118a7e14dcfSSatish Balay -  step - final step length
119a7e14dcfSSatish Balay 
120a7e14dcfSSatish Balay    Info is set to one of:
121a7e14dcfSSatish Balay .   0 - the line search succeeds; the sufficient decrease
122a7e14dcfSSatish Balay    condition and the directional derivative condition hold
123a7e14dcfSSatish Balay 
124a7e14dcfSSatish Balay    negative number if an input parameter is invalid
125a7e14dcfSSatish Balay -   -1 -  step < 0
126a7e14dcfSSatish Balay 
127a7e14dcfSSatish Balay    positive number > 1 if the line search otherwise terminates
128a7e14dcfSSatish Balay +    1 -  Step is at the lower bound, stepmin.
129a7e14dcfSSatish Balay @ */
130a7e14dcfSSatish Balay static PetscErrorCode TaoLineSearchApply_OWArmijo(TaoLineSearch ls, Vec x, PetscReal *f, Vec g, Vec s)
131a7e14dcfSSatish Balay {
1328caf6e8cSBarry Smith   TaoLineSearch_OWARMIJO *armP = (TaoLineSearch_OWARMIJO *)ls->data;
133a7e14dcfSSatish Balay   PetscErrorCode         ierr;
134a7e14dcfSSatish Balay   PetscInt               i;
135a7e14dcfSSatish Balay   PetscReal              fact, ref, gdx;
136a7e14dcfSSatish Balay   PetscInt               idx;
137a7e14dcfSSatish Balay   PetscBool              g_computed=PETSC_FALSE; /* to prevent extra gradient computation */
138a7e14dcfSSatish Balay   Vec                    g_old;
139a7e14dcfSSatish Balay   PetscReal              owlqn_minstep=0.005;
140a7e14dcfSSatish Balay   PetscReal              partgdx;
141ba4b436cSBarry Smith   MPI_Comm               comm;
142a7e14dcfSSatish Balay 
143a7e14dcfSSatish Balay   PetscFunctionBegin;
144ba4b436cSBarry Smith   ierr = PetscObjectGetComm((PetscObject)ls,&comm);CHKERRQ(ierr);
145a7e14dcfSSatish Balay   fact = 0.0;
146a7e14dcfSSatish Balay   ls->nfeval=0;
147a7e14dcfSSatish Balay   ls->reason = TAOLINESEARCH_CONTINUE_ITERATING;
148a7e14dcfSSatish Balay   if (!armP->work) {
149a7e14dcfSSatish Balay     ierr = VecDuplicate(x,&armP->work);CHKERRQ(ierr);
150a7e14dcfSSatish Balay     armP->x = x;
151a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)armP->x);CHKERRQ(ierr);
15253506e15SBarry Smith   } else if (x != armP->x) {
153a7e14dcfSSatish Balay     ierr = VecDestroy(&armP->work);CHKERRQ(ierr);
154a7e14dcfSSatish Balay     ierr = VecDuplicate(x,&armP->work);CHKERRQ(ierr);
155a7e14dcfSSatish Balay     ierr = PetscObjectDereference((PetscObject)armP->x);CHKERRQ(ierr);
156a7e14dcfSSatish Balay     armP->x = x;
157a7e14dcfSSatish Balay     ierr = PetscObjectReference((PetscObject)armP->x);CHKERRQ(ierr);
158a7e14dcfSSatish Balay   }
159a7e14dcfSSatish Balay 
160a7e14dcfSSatish Balay   /* Check linesearch parameters */
161a7e14dcfSSatish Balay   if (armP->alpha < 1) {
162335036cbSBarry Smith     ierr = PetscInfo1(ls,"OWArmijo line search error: alpha (%g) < 1\n", (double)armP->alpha);CHKERRQ(ierr);
163a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
16453506e15SBarry Smith   } else if ((armP->beta <= 0) || (armP->beta >= 1)) {
165335036cbSBarry Smith     ierr = PetscInfo1(ls,"OWArmijo line search error: beta (%g) invalid\n", (double)armP->beta);CHKERRQ(ierr);
166a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
16753506e15SBarry Smith   } else if ((armP->beta_inf <= 0) || (armP->beta_inf >= 1)) {
168335036cbSBarry Smith     ierr = PetscInfo1(ls,"OWArmijo line search error: beta_inf (%g) invalid\n", (double)armP->beta_inf);CHKERRQ(ierr);
169a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
17053506e15SBarry Smith   } else if ((armP->sigma <= 0) || (armP->sigma >= 0.5)) {
171335036cbSBarry Smith     ierr = PetscInfo1(ls,"OWArmijo line search error: sigma (%g) invalid\n", (double)armP->sigma);CHKERRQ(ierr);
172a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
17353506e15SBarry Smith   } else if (armP->memorySize < 1) {
174335036cbSBarry Smith     ierr = PetscInfo1(ls,"OWArmijo line search error: memory_size (%D) < 1\n", armP->memorySize);CHKERRQ(ierr);
175a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
17653506e15SBarry Smith   }  else if ((armP->referencePolicy != REFERENCE_MAX) && (armP->referencePolicy != REFERENCE_AVE) && (armP->referencePolicy != REFERENCE_MEAN)) {
177a7e14dcfSSatish Balay     ierr = PetscInfo(ls,"OWArmijo line search error: reference_policy invalid\n");CHKERRQ(ierr);
178a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
17953506e15SBarry Smith   } else if ((armP->replacementPolicy != REPLACE_FIFO) && (armP->replacementPolicy != REPLACE_MRU)) {
180a7e14dcfSSatish Balay     ierr = PetscInfo(ls,"OWArmijo line search error: replacement_policy invalid\n");CHKERRQ(ierr);
181a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
18253506e15SBarry Smith   } else if (PetscIsInfOrNanReal(*f)) {
183a7e14dcfSSatish Balay     ierr = PetscInfo(ls,"OWArmijo line search error: initial function inf or nan\n");CHKERRQ(ierr);
184a7e14dcfSSatish Balay     ls->reason=TAOLINESEARCH_FAILED_BADPARAMETER;
185a7e14dcfSSatish Balay   }
186a7e14dcfSSatish Balay 
18753506e15SBarry Smith   if (ls->reason != TAOLINESEARCH_CONTINUE_ITERATING) PetscFunctionReturn(0);
188a7e14dcfSSatish Balay 
189a7e14dcfSSatish Balay   /* Check to see of the memory has been allocated.  If not, allocate
190a7e14dcfSSatish Balay      the historical array and populate it with the initial function
191a7e14dcfSSatish Balay      values. */
1926c23d075SBarry Smith   if (!armP->memory) {
1930e660641SBarry Smith     ierr = PetscMalloc1(armP->memorySize, &armP->memory );CHKERRQ(ierr);
194a7e14dcfSSatish Balay   }
195a7e14dcfSSatish Balay 
196a7e14dcfSSatish Balay   if (!armP->memorySetup) {
197a7e14dcfSSatish Balay     for (i = 0; i < armP->memorySize; i++) {
198a7e14dcfSSatish Balay       armP->memory[i] = armP->alpha*(*f);
199a7e14dcfSSatish Balay     }
200a7e14dcfSSatish Balay     armP->current = 0;
201a7e14dcfSSatish Balay     armP->lastReference = armP->memory[0];
202a7e14dcfSSatish Balay     armP->memorySetup=PETSC_TRUE;
203a7e14dcfSSatish Balay   }
204a7e14dcfSSatish Balay 
205a7e14dcfSSatish Balay   /* Calculate reference value (MAX) */
206a7e14dcfSSatish Balay   ref = armP->memory[0];
207a7e14dcfSSatish Balay   idx = 0;
208a7e14dcfSSatish Balay 
209a7e14dcfSSatish Balay   for (i = 1; i < armP->memorySize; i++) {
210a7e14dcfSSatish Balay     if (armP->memory[i] > ref) {
211a7e14dcfSSatish Balay       ref = armP->memory[i];
212a7e14dcfSSatish Balay       idx = i;
213a7e14dcfSSatish Balay     }
214a7e14dcfSSatish Balay   }
215a7e14dcfSSatish Balay 
216a7e14dcfSSatish Balay   if (armP->referencePolicy == REFERENCE_AVE) {
217a7e14dcfSSatish Balay     ref = 0;
218a7e14dcfSSatish Balay     for (i = 0; i < armP->memorySize; i++) {
219a7e14dcfSSatish Balay       ref += armP->memory[i];
220a7e14dcfSSatish Balay     }
221a7e14dcfSSatish Balay     ref = ref / armP->memorySize;
222a7e14dcfSSatish Balay     ref = PetscMax(ref, armP->memory[armP->current]);
22353506e15SBarry Smith   } else if (armP->referencePolicy == REFERENCE_MEAN) {
224a7e14dcfSSatish Balay     ref = PetscMin(ref, 0.5*(armP->lastReference + armP->memory[armP->current]));
225a7e14dcfSSatish Balay   }
226a7e14dcfSSatish Balay 
227a7e14dcfSSatish Balay   if (armP->nondescending) {
228a7e14dcfSSatish Balay     fact = armP->sigma;
229a7e14dcfSSatish Balay   }
230a7e14dcfSSatish Balay 
23153506e15SBarry Smith   ierr = VecDuplicate(g,&g_old);CHKERRQ(ierr);
23253506e15SBarry Smith   ierr = VecCopy(g,g_old);CHKERRQ(ierr);
233a7e14dcfSSatish Balay 
234a7e14dcfSSatish Balay   ls->step = ls->initstep;
235a7e14dcfSSatish Balay   while (ls->step >= owlqn_minstep && ls->nfeval < ls->max_funcs) {
236a7e14dcfSSatish Balay     /* Calculate iterate */
237a7e14dcfSSatish Balay     ierr = VecCopy(x,armP->work);CHKERRQ(ierr);
238a7e14dcfSSatish Balay     ierr = VecAXPY(armP->work,ls->step,s);CHKERRQ(ierr);
239a7e14dcfSSatish Balay 
240a7e14dcfSSatish Balay     partgdx=0.0;
241a7e14dcfSSatish Balay     ierr = ProjWork_OWLQN(armP->work,x,g_old,&partgdx);
242ba4b436cSBarry Smith     ierr = MPI_Allreduce(&partgdx,&gdx,1,MPIU_REAL,MPIU_SUM,comm);CHKERRQ(ierr);
243a7e14dcfSSatish Balay 
244a7e14dcfSSatish Balay     /* Check the condition of gdx */
245a7e14dcfSSatish Balay     if (PetscIsInfOrNanReal(gdx)) {
246335036cbSBarry Smith       ierr = PetscInfo1(ls,"Initial Line Search step * g is Inf or Nan (%g)\n",(double)gdx);CHKERRQ(ierr);
247a7e14dcfSSatish Balay       ls->reason=TAOLINESEARCH_FAILED_INFORNAN;
248a7e14dcfSSatish Balay       PetscFunctionReturn(0);
249a7e14dcfSSatish Balay     }
250a7e14dcfSSatish Balay     if (gdx >= 0.0) {
251335036cbSBarry Smith       ierr = PetscInfo1(ls,"Initial Line Search step is not descent direction (g's=%g)\n",(double)gdx);CHKERRQ(ierr);
252a7e14dcfSSatish Balay       ls->reason = TAOLINESEARCH_FAILED_ASCENT;
253a7e14dcfSSatish Balay       PetscFunctionReturn(0);
254a7e14dcfSSatish Balay     }
255a7e14dcfSSatish Balay 
256a7e14dcfSSatish Balay     /* Calculate function at new iterate */
257a7e14dcfSSatish Balay     ierr = TaoLineSearchComputeObjectiveAndGradient(ls,armP->work,f,g);CHKERRQ(ierr);
258a7e14dcfSSatish Balay     g_computed=PETSC_TRUE;
259a7e14dcfSSatish Balay 
260a7e14dcfSSatish Balay     if (ls->step == ls->initstep) {
261a7e14dcfSSatish Balay       ls->f_fullstep = *f;
262a7e14dcfSSatish Balay     }
263a7e14dcfSSatish Balay 
264a7e14dcfSSatish Balay     if (PetscIsInfOrNanReal(*f)) {
265a7e14dcfSSatish Balay       ls->step *= armP->beta_inf;
26653506e15SBarry Smith     } else {
267a7e14dcfSSatish Balay       /* Check descent condition */
26853506e15SBarry Smith       if (armP->nondescending && *f <= ref - ls->step*fact*ref) break;
26953506e15SBarry Smith       if (!armP->nondescending && *f <= ref + armP->sigma * gdx) break;
270a7e14dcfSSatish Balay       ls->step *= armP->beta;
271a7e14dcfSSatish Balay     }
272a7e14dcfSSatish Balay   }
27353506e15SBarry Smith   ierr = VecDestroy(&g_old);CHKERRQ(ierr);
274a7e14dcfSSatish Balay 
275a7e14dcfSSatish Balay   /* Check termination */
276a7e14dcfSSatish Balay   if (PetscIsInfOrNanReal(*f)) {
277a7e14dcfSSatish Balay     ierr = PetscInfo(ls, "Function is inf or nan.\n");CHKERRQ(ierr);
278a7e14dcfSSatish Balay     ls->reason = TAOLINESEARCH_FAILED_BADPARAMETER;
279a7e14dcfSSatish Balay   } else if (ls->step < owlqn_minstep) {
280a7e14dcfSSatish Balay     ierr = PetscInfo(ls, "Step length is below tolerance.\n");CHKERRQ(ierr);
281a7e14dcfSSatish Balay     ls->reason = TAOLINESEARCH_HALTED_RTOL;
282a7e14dcfSSatish Balay   } else if (ls->nfeval >= ls->max_funcs) {
2836f4723b1SBarry Smith     ierr = PetscInfo2(ls, "Number of line search function evals (%D) > maximum allowed (%D)\n",ls->nfeval, ls->max_funcs);CHKERRQ(ierr);
284a7e14dcfSSatish Balay     ls->reason = TAOLINESEARCH_HALTED_MAXFCN;
285a7e14dcfSSatish Balay   }
28653506e15SBarry Smith   if (ls->reason) PetscFunctionReturn(0);
287a7e14dcfSSatish Balay 
288a7e14dcfSSatish Balay   /* Successful termination, update memory */
289a7e14dcfSSatish Balay   armP->lastReference = ref;
290a7e14dcfSSatish Balay   if (armP->replacementPolicy == REPLACE_FIFO) {
291a7e14dcfSSatish Balay     armP->memory[armP->current++] = *f;
292a7e14dcfSSatish Balay     if (armP->current >= armP->memorySize) {
293a7e14dcfSSatish Balay       armP->current = 0;
294a7e14dcfSSatish Balay     }
295a7e14dcfSSatish Balay   } else {
296a7e14dcfSSatish Balay     armP->current = idx;
297a7e14dcfSSatish Balay     armP->memory[idx] = *f;
298a7e14dcfSSatish Balay   }
299a7e14dcfSSatish Balay 
300a7e14dcfSSatish Balay   /* Update iterate and compute gradient */
301a7e14dcfSSatish Balay   ierr = VecCopy(armP->work,x);CHKERRQ(ierr);
302a7e14dcfSSatish Balay   if (!g_computed) {
303a7e14dcfSSatish Balay     ierr = TaoLineSearchComputeGradient(ls, x, g);CHKERRQ(ierr);
304a7e14dcfSSatish Balay   }
305335036cbSBarry Smith   ierr = PetscInfo2(ls, "%D function evals in line search, step = %10.4f\n",ls->nfeval, (double)ls->step);CHKERRQ(ierr);
306a7e14dcfSSatish Balay   PetscFunctionReturn(0);
307a7e14dcfSSatish Balay }
308a7e14dcfSSatish Balay 
309a7e14dcfSSatish Balay #undef __FUNCT__
310a7e14dcfSSatish Balay #define __FUNCT__ "TaoLineSearchCreate_OWArmijo"
311728e0ed0SBarry Smith PETSC_EXTERN PetscErrorCode TaoLineSearchCreate_OWArmijo(TaoLineSearch ls)
312a7e14dcfSSatish Balay {
3138caf6e8cSBarry Smith   TaoLineSearch_OWARMIJO *armP;
314a7e14dcfSSatish Balay   PetscErrorCode         ierr;
315a7e14dcfSSatish Balay 
316a7e14dcfSSatish Balay   PetscFunctionBegin;
317a7e14dcfSSatish Balay   PetscValidHeaderSpecific(ls,TAOLINESEARCH_CLASSID,1);
3183c9e27cfSGeoffrey Irving   ierr = PetscNewLog(ls,&armP);CHKERRQ(ierr);
319a7e14dcfSSatish Balay 
3206c23d075SBarry Smith   armP->memory = NULL;
321a7e14dcfSSatish Balay   armP->alpha = 1.0;
322a7e14dcfSSatish Balay   armP->beta = 0.25;
323a7e14dcfSSatish Balay   armP->beta_inf = 0.25;
324a7e14dcfSSatish Balay   armP->sigma = 1e-4;
325a7e14dcfSSatish Balay   armP->memorySize = 1;
326a7e14dcfSSatish Balay   armP->referencePolicy = REFERENCE_MAX;
327a7e14dcfSSatish Balay   armP->replacementPolicy = REPLACE_MRU;
328a7e14dcfSSatish Balay   armP->nondescending=PETSC_FALSE;
329a7e14dcfSSatish Balay   ls->data = (void*)armP;
330a7e14dcfSSatish Balay   ls->initstep=0.1;
331a7e14dcfSSatish Balay   ls->ops->setup=0;
33224517cd3SJason Sarich   ls->ops->reset=0;
333a7e14dcfSSatish Balay   ls->ops->apply=TaoLineSearchApply_OWArmijo;
334a7e14dcfSSatish Balay   ls->ops->view = TaoLineSearchView_OWArmijo;
335a7e14dcfSSatish Balay   ls->ops->destroy = TaoLineSearchDestroy_OWArmijo;
336a7e14dcfSSatish Balay   ls->ops->setfromoptions = TaoLineSearchSetFromOptions_OWArmijo;
337a7e14dcfSSatish Balay   PetscFunctionReturn(0);
338a7e14dcfSSatish Balay }
339728e0ed0SBarry Smith 
340