xref: /petsc/src/tao/unconstrained/impls/neldermead/neldermead.c (revision a7e14dcfba0d07adf6226a919460249440ec94c7)
1*a7e14dcfSSatish Balay #include "neldermead.h"
2*a7e14dcfSSatish Balay #include "petscvec.h"
3*a7e14dcfSSatish Balay 
4*a7e14dcfSSatish Balay static PetscErrorCode NelderMeadSort(TAO_NelderMead *nm);
5*a7e14dcfSSatish Balay static PetscErrorCode NelderMeadReplace(TAO_NelderMead *nm, PetscInt index, Vec Xmu, PetscReal f);
6*a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
7*a7e14dcfSSatish Balay #undef __FUNCT__
8*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetUp_NM"
9*a7e14dcfSSatish Balay static PetscErrorCode TaoSetUp_NM(TaoSolver tao)
10*a7e14dcfSSatish Balay {
11*a7e14dcfSSatish Balay   PetscErrorCode ierr;
12*a7e14dcfSSatish Balay   TAO_NelderMead *nm = (TAO_NelderMead *)tao->data;
13*a7e14dcfSSatish Balay   PetscInt size;
14*a7e14dcfSSatish Balay 
15*a7e14dcfSSatish Balay   PetscFunctionBegin;
16*a7e14dcfSSatish Balay   ierr = VecGetSize(tao->solution,&size); CHKERRQ(ierr);
17*a7e14dcfSSatish Balay   nm->N = size;
18*a7e14dcfSSatish Balay   nm->oneOverN = 1.0/size;
19*a7e14dcfSSatish Balay   ierr = VecDuplicateVecs(tao->solution,nm->N+1,&nm->simplex); CHKERRQ(ierr);
20*a7e14dcfSSatish Balay   ierr = PetscMalloc((nm->N+1)*sizeof(PetscReal),&nm->f_values); CHKERRQ(ierr);
21*a7e14dcfSSatish Balay   ierr = PetscMalloc((nm->N+1)*sizeof(PetscInt),&nm->indices); CHKERRQ(ierr);
22*a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&nm->Xbar); CHKERRQ(ierr);
23*a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&nm->Xmur); CHKERRQ(ierr);
24*a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&nm->Xmue); CHKERRQ(ierr);
25*a7e14dcfSSatish Balay   ierr = VecDuplicate(tao->solution,&nm->Xmuc); CHKERRQ(ierr);
26*a7e14dcfSSatish Balay 
27*a7e14dcfSSatish Balay   tao->gradient=0;
28*a7e14dcfSSatish Balay   tao->step=0;
29*a7e14dcfSSatish Balay 
30*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
31*a7e14dcfSSatish Balay }
32*a7e14dcfSSatish Balay 
33*a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
34*a7e14dcfSSatish Balay #undef __FUNCT__
35*a7e14dcfSSatish Balay #define __FUNCT__ "TaoDestroy_NM"
36*a7e14dcfSSatish Balay PetscErrorCode TaoDestroy_NM(TaoSolver tao)
37*a7e14dcfSSatish Balay {
38*a7e14dcfSSatish Balay   TAO_NelderMead *nm = (TAO_NelderMead*)tao->data;
39*a7e14dcfSSatish Balay   PetscErrorCode ierr;
40*a7e14dcfSSatish Balay   PetscFunctionBegin;
41*a7e14dcfSSatish Balay   if (tao->setupcalled) {
42*a7e14dcfSSatish Balay     ierr = VecDestroyVecs(nm->N+1,&nm->simplex); CHKERRQ(ierr);
43*a7e14dcfSSatish Balay     ierr = VecDestroy(&nm->Xmuc); CHKERRQ(ierr);
44*a7e14dcfSSatish Balay     ierr = VecDestroy(&nm->Xmue); CHKERRQ(ierr);
45*a7e14dcfSSatish Balay     ierr = VecDestroy(&nm->Xmur); CHKERRQ(ierr);
46*a7e14dcfSSatish Balay     ierr = VecDestroy(&nm->Xbar); CHKERRQ(ierr);
47*a7e14dcfSSatish Balay   }
48*a7e14dcfSSatish Balay   ierr = PetscFree(nm->indices); CHKERRQ(ierr);
49*a7e14dcfSSatish Balay   ierr = PetscFree(nm->f_values); CHKERRQ(ierr);
50*a7e14dcfSSatish Balay   ierr = PetscFree(tao->data);
51*a7e14dcfSSatish Balay   tao->data = 0;
52*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
53*a7e14dcfSSatish Balay }
54*a7e14dcfSSatish Balay 
55*a7e14dcfSSatish Balay /*------------------------------------------------------------*/
56*a7e14dcfSSatish Balay #undef __FUNCT__
57*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSetFromOptions_NM"
58*a7e14dcfSSatish Balay PetscErrorCode TaoSetFromOptions_NM(TaoSolver tao)
59*a7e14dcfSSatish Balay {
60*a7e14dcfSSatish Balay 
61*a7e14dcfSSatish Balay   TAO_NelderMead *nm = (TAO_NelderMead*)tao->data;
62*a7e14dcfSSatish Balay   PetscBool flg;
63*a7e14dcfSSatish Balay   PetscErrorCode ierr;
64*a7e14dcfSSatish Balay 
65*a7e14dcfSSatish Balay   PetscFunctionBegin;
66*a7e14dcfSSatish Balay   ierr = PetscOptionsHead("Nelder-Mead options"); CHKERRQ(ierr);
67*a7e14dcfSSatish Balay 
68*a7e14dcfSSatish Balay   ierr = PetscOptionsReal("-tao_nm_lamda","initial step length","",nm->lamda,&nm->lamda,&flg);  CHKERRQ(ierr);
69*a7e14dcfSSatish Balay 
70*a7e14dcfSSatish Balay   ierr = PetscOptionsReal("-tao_nm_mu","mu","",nm->mu_oc,&nm->mu_oc,&flg); CHKERRQ(ierr);
71*a7e14dcfSSatish Balay   nm->mu_ic = -nm->mu_oc;
72*a7e14dcfSSatish Balay   nm->mu_r = nm->mu_oc*2.0;
73*a7e14dcfSSatish Balay   nm->mu_e = nm->mu_oc*4.0;
74*a7e14dcfSSatish Balay 
75*a7e14dcfSSatish Balay   ierr = PetscOptionsTail(); CHKERRQ(ierr);
76*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
77*a7e14dcfSSatish Balay }
78*a7e14dcfSSatish Balay 
79*a7e14dcfSSatish Balay /*------------------------------------------------------------*/
80*a7e14dcfSSatish Balay #undef __FUNCT__
81*a7e14dcfSSatish Balay #define __FUNCT__ "TaoView_NM"
82*a7e14dcfSSatish Balay PetscErrorCode TaoView_NM(TaoSolver tao,PetscViewer viewer)
83*a7e14dcfSSatish Balay {
84*a7e14dcfSSatish Balay   TAO_NelderMead *nm = (TAO_NelderMead*)tao->data;
85*a7e14dcfSSatish Balay   PetscBool isascii;
86*a7e14dcfSSatish Balay   PetscErrorCode ierr;
87*a7e14dcfSSatish Balay 
88*a7e14dcfSSatish Balay   PetscFunctionBegin;
89*a7e14dcfSSatish Balay   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
90*a7e14dcfSSatish Balay   if (isascii) {
91*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPushTab(viewer); CHKERRQ(ierr);
92*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"expansions: %D\n",nm->nexpand); CHKERRQ(ierr);
93*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"reflections: %D\n",nm->nreflect); CHKERRQ(ierr);
94*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"inside contractions: %D\n",nm->nincontract); CHKERRQ(ierr);
95*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"outside contractionss: %D\n",nm->noutcontract); CHKERRQ(ierr);
96*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPrintf(viewer,"Shrink steps: %D\n",nm->nshrink); CHKERRQ(ierr);
97*a7e14dcfSSatish Balay     ierr = PetscViewerASCIIPopTab(viewer); CHKERRQ(ierr);
98*a7e14dcfSSatish Balay   } else {
99*a7e14dcfSSatish Balay     SETERRQ1(((PetscObject)tao)->comm,PETSC_ERR_SUP,"Viewer type %s not supported for TAO NelderMead",((PetscObject)viewer)->type_name);
100*a7e14dcfSSatish Balay   }
101*a7e14dcfSSatish Balay 
102*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
103*a7e14dcfSSatish Balay }
104*a7e14dcfSSatish Balay 
105*a7e14dcfSSatish Balay /*------------------------------------------------------------*/
106*a7e14dcfSSatish Balay #undef __FUNCT__
107*a7e14dcfSSatish Balay #define __FUNCT__ "TaoSolve_NM"
108*a7e14dcfSSatish Balay PetscErrorCode TaoSolve_NM(TaoSolver tao)
109*a7e14dcfSSatish Balay {
110*a7e14dcfSSatish Balay   PetscErrorCode ierr;
111*a7e14dcfSSatish Balay   TAO_NelderMead *nm = (TAO_NelderMead*)tao->data;
112*a7e14dcfSSatish Balay   TaoSolverTerminationReason reason;
113*a7e14dcfSSatish Balay   PetscReal *x;
114*a7e14dcfSSatish Balay   PetscInt iter=0,i;
115*a7e14dcfSSatish Balay   Vec Xmur=nm->Xmur, Xmue=nm->Xmue, Xmuc=nm->Xmuc, Xbar=nm->Xbar;
116*a7e14dcfSSatish Balay   PetscReal fr,fe,fc;
117*a7e14dcfSSatish Balay   PetscInt shrink;
118*a7e14dcfSSatish Balay   PetscInt low,high;
119*a7e14dcfSSatish Balay 
120*a7e14dcfSSatish Balay 
121*a7e14dcfSSatish Balay   PetscFunctionBegin;
122*a7e14dcfSSatish Balay   nm->nshrink =      0;
123*a7e14dcfSSatish Balay   nm->nreflect =     0;
124*a7e14dcfSSatish Balay   nm->nincontract =  0;
125*a7e14dcfSSatish Balay   nm->noutcontract = 0;
126*a7e14dcfSSatish Balay   nm->nexpand =      0;
127*a7e14dcfSSatish Balay 
128*a7e14dcfSSatish Balay   if (tao->XL || tao->XU || tao->ops->computebounds) {
129*a7e14dcfSSatish Balay     ierr = PetscPrintf(((PetscObject)tao)->comm,"WARNING: Variable bounds have been set but will be ignored by NelderMead algorithm\n"); CHKERRQ(ierr);
130*a7e14dcfSSatish Balay   }
131*a7e14dcfSSatish Balay 
132*a7e14dcfSSatish Balay   ierr = VecCopy(tao->solution,nm->simplex[0]); CHKERRQ(ierr);
133*a7e14dcfSSatish Balay   ierr = TaoComputeObjective(tao,nm->simplex[0],&nm->f_values[0]); CHKERRQ(ierr);
134*a7e14dcfSSatish Balay   nm->indices[0]=0;
135*a7e14dcfSSatish Balay   for (i=1;i<nm->N+1;i++){
136*a7e14dcfSSatish Balay     ierr = VecCopy(tao->solution,nm->simplex[i]); CHKERRQ(ierr);
137*a7e14dcfSSatish Balay     ierr = VecGetOwnershipRange(nm->simplex[i],&low,&high); CHKERRQ(ierr);
138*a7e14dcfSSatish Balay     if (i-1 >= low && i-1 < high) {
139*a7e14dcfSSatish Balay       ierr = VecGetArray(nm->simplex[i],&x); CHKERRQ(ierr);
140*a7e14dcfSSatish Balay       x[i-1-low] += nm->lamda;
141*a7e14dcfSSatish Balay       ierr = VecRestoreArray(nm->simplex[i],&x); CHKERRQ(ierr);
142*a7e14dcfSSatish Balay     }
143*a7e14dcfSSatish Balay 
144*a7e14dcfSSatish Balay     ierr = TaoComputeObjective(tao,nm->simplex[i],&nm->f_values[i]); CHKERRQ(ierr);
145*a7e14dcfSSatish Balay     nm->indices[i] = i;
146*a7e14dcfSSatish Balay   }
147*a7e14dcfSSatish Balay 
148*a7e14dcfSSatish Balay   /*  Xbar  = (Sum of all simplex vectors - worst vector)/N */
149*a7e14dcfSSatish Balay   ierr = NelderMeadSort(nm); CHKERRQ(ierr);
150*a7e14dcfSSatish Balay   ierr = VecSet(Xbar,0.0); CHKERRQ(ierr);
151*a7e14dcfSSatish Balay   for (i=0;i<nm->N;i++) {
152*a7e14dcfSSatish Balay     ierr = VecAXPY(Xbar,1.0,nm->simplex[nm->indices[i]]);
153*a7e14dcfSSatish Balay   }
154*a7e14dcfSSatish Balay   ierr = VecScale(Xbar,nm->oneOverN);
155*a7e14dcfSSatish Balay   reason = TAO_CONTINUE_ITERATING;
156*a7e14dcfSSatish Balay   while (1) {
157*a7e14dcfSSatish Balay     shrink = 0;
158*a7e14dcfSSatish Balay     ierr = VecCopy(nm->simplex[nm->indices[0]],tao->solution); CHKERRQ(ierr);
159*a7e14dcfSSatish Balay     ierr = TaoMonitor(tao,iter++,nm->f_values[nm->indices[0]],nm->f_values[nm->indices[nm->N]]-nm->f_values[nm->indices[0]],0.0,1.0,&reason); CHKERRQ(ierr);
160*a7e14dcfSSatish Balay     if (reason != TAO_CONTINUE_ITERATING) break;
161*a7e14dcfSSatish Balay 
162*a7e14dcfSSatish Balay 
163*a7e14dcfSSatish Balay 
164*a7e14dcfSSatish Balay     /* x(mu) = (1 + mu)Xbar - mu*X_N+1 */
165*a7e14dcfSSatish Balay     ierr = VecAXPBYPCZ(Xmur,1+nm->mu_r,-nm->mu_r,0,Xbar,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
166*a7e14dcfSSatish Balay     ierr = TaoComputeObjective(tao,Xmur,&fr); CHKERRQ(ierr);
167*a7e14dcfSSatish Balay 
168*a7e14dcfSSatish Balay 
169*a7e14dcfSSatish Balay     if (nm->f_values[nm->indices[0]] <= fr && fr < nm->f_values[nm->indices[nm->N-1]]) {
170*a7e14dcfSSatish Balay       /*  reflect */
171*a7e14dcfSSatish Balay       nm->nreflect++;
172*a7e14dcfSSatish Balay       ierr = PetscInfo(0,"Reflect\n"); CHKERRQ(ierr);
173*a7e14dcfSSatish Balay       ierr = NelderMeadReplace(nm,nm->indices[nm->N],Xmur,fr); CHKERRQ(ierr);
174*a7e14dcfSSatish Balay     }
175*a7e14dcfSSatish Balay 
176*a7e14dcfSSatish Balay     else if (fr < nm->f_values[nm->indices[0]]) {
177*a7e14dcfSSatish Balay       /*  expand */
178*a7e14dcfSSatish Balay       nm->nexpand++;
179*a7e14dcfSSatish Balay       ierr = PetscInfo(0,"Expand\n"); CHKERRQ(ierr);
180*a7e14dcfSSatish Balay       ierr = VecAXPBYPCZ(Xmue,1+nm->mu_e,-nm->mu_e,0,Xbar,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
181*a7e14dcfSSatish Balay       ierr = TaoComputeObjective(tao,Xmue,&fe); CHKERRQ(ierr);
182*a7e14dcfSSatish Balay       if (fe < fr) {
183*a7e14dcfSSatish Balay 	ierr = NelderMeadReplace(nm,nm->indices[nm->N],Xmue,fe); CHKERRQ(ierr);
184*a7e14dcfSSatish Balay       } else {
185*a7e14dcfSSatish Balay 	ierr = NelderMeadReplace(nm,nm->indices[nm->N],Xmur,fr); CHKERRQ(ierr);
186*a7e14dcfSSatish Balay       }
187*a7e14dcfSSatish Balay 
188*a7e14dcfSSatish Balay     } else if (nm->f_values[nm->indices[nm->N-1]] <= fr && fr < nm->f_values[nm->indices[nm->N]]) {
189*a7e14dcfSSatish Balay       /* outside contraction */
190*a7e14dcfSSatish Balay       nm->noutcontract++;
191*a7e14dcfSSatish Balay       ierr = PetscInfo(0,"Outside Contraction\n"); CHKERRQ(ierr);
192*a7e14dcfSSatish Balay       ierr = VecAXPBYPCZ(Xmuc,1+nm->mu_oc,-nm->mu_oc,0,Xbar,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
193*a7e14dcfSSatish Balay 
194*a7e14dcfSSatish Balay       ierr = TaoComputeObjective(tao,Xmuc,&fc); CHKERRQ(ierr);
195*a7e14dcfSSatish Balay       if (fc <= fr) {
196*a7e14dcfSSatish Balay 	ierr = NelderMeadReplace(nm,nm->indices[nm->N],Xmuc,fc); CHKERRQ(ierr);
197*a7e14dcfSSatish Balay       }	else
198*a7e14dcfSSatish Balay 	shrink=1;
199*a7e14dcfSSatish Balay     } else {
200*a7e14dcfSSatish Balay       /* inside contraction */
201*a7e14dcfSSatish Balay       nm->nincontract++;
202*a7e14dcfSSatish Balay       ierr = PetscInfo(0,"Inside Contraction\n"); CHKERRQ(ierr);
203*a7e14dcfSSatish Balay       ierr = VecAXPBYPCZ(Xmuc,1+nm->mu_ic,-nm->mu_ic,0,Xbar,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
204*a7e14dcfSSatish Balay       ierr = TaoComputeObjective(tao,Xmuc,&fc); CHKERRQ(ierr);
205*a7e14dcfSSatish Balay       if (fc < nm->f_values[nm->indices[nm->N]]) {
206*a7e14dcfSSatish Balay 	ierr = NelderMeadReplace(nm,nm->indices[nm->N],Xmuc,fc); CHKERRQ(ierr);
207*a7e14dcfSSatish Balay       } else
208*a7e14dcfSSatish Balay 	shrink = 1;
209*a7e14dcfSSatish Balay     }
210*a7e14dcfSSatish Balay 
211*a7e14dcfSSatish Balay     if (shrink) {
212*a7e14dcfSSatish Balay       nm->nshrink++;
213*a7e14dcfSSatish Balay       ierr = PetscInfo(0,"Shrink\n"); CHKERRQ(ierr);
214*a7e14dcfSSatish Balay 
215*a7e14dcfSSatish Balay       for (i=1;i<nm->N+1;i++) {
216*a7e14dcfSSatish Balay 	  ierr = VecAXPBY(nm->simplex[nm->indices[i]],1.5,-0.5,nm->simplex[nm->indices[0]]);
217*a7e14dcfSSatish Balay 	ierr = TaoComputeObjective(tao,nm->simplex[nm->indices[i]],
218*a7e14dcfSSatish Balay 				 &nm->f_values[nm->indices[i]]); CHKERRQ(ierr);
219*a7e14dcfSSatish Balay       }
220*a7e14dcfSSatish Balay       ierr = VecAXPBY(Xbar,1.5*nm->oneOverN,-0.5,nm->simplex[nm->indices[0]]); CHKERRQ(ierr);
221*a7e14dcfSSatish Balay 
222*a7e14dcfSSatish Balay       /*  Add last vector's fraction of average */
223*a7e14dcfSSatish Balay       ierr = VecAXPY(Xbar,nm->oneOverN,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
224*a7e14dcfSSatish Balay       ierr = NelderMeadSort(nm);
225*a7e14dcfSSatish Balay       /*  Subtract new last vector from average */
226*a7e14dcfSSatish Balay       ierr = VecAXPY(Xbar,-nm->oneOverN,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
227*a7e14dcfSSatish Balay     }
228*a7e14dcfSSatish Balay 
229*a7e14dcfSSatish Balay 
230*a7e14dcfSSatish Balay   }
231*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
232*a7e14dcfSSatish Balay }
233*a7e14dcfSSatish Balay 
234*a7e14dcfSSatish Balay /* ---------------------------------------------------------- */
235*a7e14dcfSSatish Balay EXTERN_C_BEGIN
236*a7e14dcfSSatish Balay #undef __FUNCT__
237*a7e14dcfSSatish Balay #define __FUNCT__ "TaoCreate_NM"
238*a7e14dcfSSatish Balay PetscErrorCode TaoCreate_NM(TaoSolver tao)
239*a7e14dcfSSatish Balay {
240*a7e14dcfSSatish Balay   TAO_NelderMead *nm;
241*a7e14dcfSSatish Balay   PetscErrorCode ierr;
242*a7e14dcfSSatish Balay 
243*a7e14dcfSSatish Balay   PetscFunctionBegin;
244*a7e14dcfSSatish Balay   ierr = PetscNewLog(tao,TAO_NelderMead,&nm); CHKERRQ(ierr);
245*a7e14dcfSSatish Balay   tao->data = (void*)nm;
246*a7e14dcfSSatish Balay 
247*a7e14dcfSSatish Balay   tao->ops->setup = TaoSetUp_NM;
248*a7e14dcfSSatish Balay   tao->ops->solve = TaoSolve_NM;
249*a7e14dcfSSatish Balay   tao->ops->view = TaoView_NM;
250*a7e14dcfSSatish Balay   tao->ops->setfromoptions = TaoSetFromOptions_NM;
251*a7e14dcfSSatish Balay   tao->ops->destroy = TaoDestroy_NM;
252*a7e14dcfSSatish Balay 
253*a7e14dcfSSatish Balay   tao->max_it = 2000;
254*a7e14dcfSSatish Balay   tao->max_funcs = 4000;
255*a7e14dcfSSatish Balay   tao->fatol = 1e-8;
256*a7e14dcfSSatish Balay   tao->frtol = 1e-8;
257*a7e14dcfSSatish Balay 
258*a7e14dcfSSatish Balay   nm->simplex = 0;
259*a7e14dcfSSatish Balay   nm->lamda = 1;
260*a7e14dcfSSatish Balay 
261*a7e14dcfSSatish Balay   nm->mu_ic = -0.5;
262*a7e14dcfSSatish Balay   nm->mu_oc = 0.5;
263*a7e14dcfSSatish Balay   nm->mu_r = 1.0;
264*a7e14dcfSSatish Balay   nm->mu_e = 2.0;
265*a7e14dcfSSatish Balay 
266*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
267*a7e14dcfSSatish Balay }
268*a7e14dcfSSatish Balay EXTERN_C_END
269*a7e14dcfSSatish Balay 
270*a7e14dcfSSatish Balay 
271*a7e14dcfSSatish Balay /*------------------------------------------------------------*/
272*a7e14dcfSSatish Balay #undef __FUNCT__
273*a7e14dcfSSatish Balay #define __FUNCT__ "NelderMeadSort"
274*a7e14dcfSSatish Balay PetscErrorCode NelderMeadSort(TAO_NelderMead *nm) {
275*a7e14dcfSSatish Balay   PetscReal *values = nm->f_values;
276*a7e14dcfSSatish Balay   PetscInt *indices = nm->indices;
277*a7e14dcfSSatish Balay   PetscInt dim = nm->N+1;
278*a7e14dcfSSatish Balay 
279*a7e14dcfSSatish Balay   PetscInt i,j,index;
280*a7e14dcfSSatish Balay   PetscReal val;
281*a7e14dcfSSatish Balay   PetscFunctionBegin;
282*a7e14dcfSSatish Balay   for (i=1;i<dim;i++) {
283*a7e14dcfSSatish Balay     index = indices[i];
284*a7e14dcfSSatish Balay     val = values[index];
285*a7e14dcfSSatish Balay     for (j=i-1; j>=0 && values[indices[j]] > val; j--) {
286*a7e14dcfSSatish Balay       indices[j+1] = indices[j];
287*a7e14dcfSSatish Balay     }
288*a7e14dcfSSatish Balay     indices[j+1] = index;
289*a7e14dcfSSatish Balay   }
290*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
291*a7e14dcfSSatish Balay }
292*a7e14dcfSSatish Balay 
293*a7e14dcfSSatish Balay 
294*a7e14dcfSSatish Balay /*------------------------------------------------------------*/
295*a7e14dcfSSatish Balay #undef __FUNCT__
296*a7e14dcfSSatish Balay #define __FUNCT__ "NelderMeadReplace"
297*a7e14dcfSSatish Balay PetscErrorCode NelderMeadReplace(TAO_NelderMead *nm, PetscInt index, Vec Xmu, PetscReal f)
298*a7e14dcfSSatish Balay {
299*a7e14dcfSSatish Balay   PetscErrorCode ierr;
300*a7e14dcfSSatish Balay   PetscFunctionBegin;
301*a7e14dcfSSatish Balay   /*  Add new vector's fraction of average */
302*a7e14dcfSSatish Balay   ierr = VecAXPY(nm->Xbar,nm->oneOverN,Xmu); CHKERRQ(ierr);
303*a7e14dcfSSatish Balay   ierr = VecCopy(Xmu,nm->simplex[index]); CHKERRQ(ierr);
304*a7e14dcfSSatish Balay   nm->f_values[index] = f;
305*a7e14dcfSSatish Balay 
306*a7e14dcfSSatish Balay   ierr = NelderMeadSort(nm);
307*a7e14dcfSSatish Balay 
308*a7e14dcfSSatish Balay   /*  Subtract last vector from average */
309*a7e14dcfSSatish Balay   ierr = VecAXPY(nm->Xbar,-nm->oneOverN,nm->simplex[nm->indices[nm->N]]); CHKERRQ(ierr);
310*a7e14dcfSSatish Balay   PetscFunctionReturn(0);
311*a7e14dcfSSatish Balay }
312