Local one-dimensional minimization by bracketing.
38 {
39 int verbose=0;
if(status!=NULL) verbose=status->
verbose;
40 if(verbose>1) {printf("%s(NLOPT, %d, status)\n", __func__, maxIter); fflush(stdout);}
41 if(nlo==NULL) {
44 }
48 }
49
50
54 }
55
57 unsigned int fpi;
58 for(fpi=0; fpi<nlo->
totalNr; fpi++) {
60 if(isfinite(nlo->
xdelta[fpi]) && fabs(nlo->
xdelta[fpi])>macheps && isfinite(r) && r>macheps)
61 break;
62 }
66 }
67 if(verbose>3) printf(" index_of_free_parameter := %u\n", fpi);
68
69
70 double pmin=nlo->
xlower[fpi];
71 double pmax=nlo->
xupper[fpi];
72 double delta=nlo->
xdelta[fpi];
73 double tol=nlo->
xtol[fpi];
74 if(verbose>2)
75 printf(
" initial_parameter := %g [%g, %g, %g]\n", nlo->
xfull[fpi], pmin, pmax, delta);
76 if(!(nlo->
xfull[fpi]>=pmin) || !(nlo->
xfull[fpi]<=pmax)) {
79 }
80
81 if(!( (pmax-pmin) > 2.0*delta)) {
84 }
85
86
87 if(maxIter<100) maxIter=200+(pmax-pmin)/delta;
88 if(verbose>1) printf(" maxIter := %u\n", maxIter);
89
90
91 double p1=0., p2=0., p3=0., f1=0., f2=0., f3=0.;
92 double minf, minp;
93
95 for(
unsigned int i=0; i<nlo->
totalNr; i++) p[i]=nlo->
xfull[i];
96
97
98 unsigned int iterNr=1;
99 p2=minp=nlo->
xfull[fpi];
if(p2<pmin+delta) p2=pmin+delta;
else if(p2>pmax-delta) p2=pmax-delta;
101 if(!isfinite(f2)) {
104 }
109 }
110
111
117 }
118 if(f1<minf) {minf=f1; minp=p1;}
119
125 }
126 if(f3<minf) {minf=f3; minp=p3;}
127
128
129
130
131 double jump_size=delta;
132 while(!(f1>f2 && f2<f3)) {
133 if(verbose>3) {
134 printf(" jump_size := %g\n", jump_size);
135 printf(" bracketing points: %g %g %g -> %g %g %g\n", p1, p2, p3, f1, f2, f3);
136 printf(" min: %g -> %g\n", minp, minf);
137 }
138
139 if(iterNr>=maxIter) break;
140 if((p3-p1)<tol) break;
141
142 if(f1<f3) {
143
144
145
146 if(p1==pmin || (fabs(f1-f2)<macheps && (pmax-pmin)<jump_size )) {
147 p3=p2; f3=f2; p2=0.5*(p1+p2);
153 }
154 if(f2<minf) {minf=f2; minp=p2;}
155 } else {
156
157 p3=p2; f3=f2; p2=p1; f2=f1;
158 p1-=jump_size; if(p1<pmin) p1=pmin;
164 }
165 if(f1<minf) {minf=f1; minp=p1;}
166 jump_size*=2.0;
167 }
168 } else {
169
170
171
172 if(p3==pmax || (fabs(f2-f3)<macheps && (pmax-pmin)<jump_size)) {
173 p1=p2; f1=f2; p2=0.5*(p3+p2);
179 }
180 if(f2<minf) {minf=f2; minp=p2;}
181 } else {
182
183 p1=p2; f1=f2; p2=p3; f2=f3;
184 p3+=jump_size; if(p3>pmax) p3=pmax;
190 }
191 if(f3<minf) {minf=f3; minp=p3;}
192 jump_size*=2.0;
193 }
194 }
195 }
196 if(verbose>3) {
197 printf(" brackets ready.\n\n");
198 if(verbose>3) {
199 printf(" bracketing points: %g %g %g -> %g %g %g\n", p1, p2, p3, f1, f2, f3);
200 printf(" min: %g -> %g\n", minp, minf);
201 }
202 }
203
204
205
206
207 const double tau=0.05;
208 while(iterNr<maxIter && (p3-p1)>tol) {
209
210
211 double d=f1*(p3*p3-p2*p2) + f2*(p1*p1-p3*p3) + f3*(p2*p2-p1*p1);
212 double e=2.0*(f1*(p3-p2) + f2*(p1-p3) + f3*(p2-p1));
213 if(fabs(e)<macheps || !isfinite(d/=e)) {
214 minp=p2;
215 } else {
216 if(p1<=d && d<=p3) {minp=d;} else {minp=d; if(p1>minp) minp=p1; if(p3<minp) minp=p3;}
217 }
218
219
220 if(minp<p2) {
221 d=(p2-p1)*tau; if(fabs(p1-minp)<d) minp=p1+d; else if(fabs(p2-minp)<d) minp=p2-d;
222 } else {
223 d=(p3-p2)*tau; if(fabs(p2-minp)<d) minp=p2+d; else if(fabs(p3-minp)<d) minp=p3-d;
224 }
225
226
227
228 double bracket_ratio=fabs(p1-p2)/fabs(p2-p3);
229 if(!(bracket_ratio<100.0 && bracket_ratio>0.01)) {
230
231 if(bracket_ratio>1.0 && minp>p2) minp=0.5*(p1+p2); else if(minp<p2) minp=0.5*(p2+p3);
232 }
233
234
240 }
241
242
243 if(minp<p2) {
244 if(f1>minf && minf<f2) {p3=p2; f3=f2; p2=minp; f2=minf;} else {p1=minp; f1=minf;}
245 } else {
246 if(f2>minf && minf<f3) {p1=p2; f1=f2; p2=minp; f2=minf;} else {p3=minp; f3=minf;}
247 }
248
249 if(verbose>3) {
250 printf(" bracketing points: %g %g %g -> %g %g %g\n", p1, p2, p3, f1, f2, f3);
251 printf(" min: %g -> %g\n", minp, minf);
252 }
253 }
254
255
257
259
262}
unsigned int nloptFixedNr(NLOPT *d)
int nloptAddP(NLOPT *nlo, double *p, double funval)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
double(* _fun)(int, double *, void *)
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_INVALID_PARNR
Invalid number of parameters.
@ TPCERROR_FAIL
General error.
@ TPCERROR_NO_DATA
File contains no data.