45 double (*objf)(
int,
double*,
void*),
67 int i, j, k, l, IDmin, itNr, samplNr, topoNr, badNr, nevals=0, ret;
68 double *delta, temp, min, *tempp, deltaf, tol;
70 int fixed_n, fitted_n;
73 if(verbose>0) {printf(
"in tgo()\n"); fflush(stdout);}
75 if(verbose>0) printf(
"local optimization routine: bobyqa\n");
77 if(verbose>0) printf(
"local optimization routine: powell\n");
81 if(lowlim==NULL || uplim==NULL || objf==NULL || dim<=0)
return(1);
82 if(fmin==NULL || gmin==NULL)
return(1);
85 for(i=0, fixed_n=0; i<dim; i++)
if(uplim[i]<=lowlim[i]) fixed_n++;
87 if(verbose>1) printf(
"%d parameter(s) are fixed.\n", fixed_n);
88 if(fitted_n<1)
return(1);
91 if(samNr<=0) samplNr=
TGO_SAMPLNR;
else samplNr=samNr;
92 if(samplNr&1) samplNr++;
93 if(neighNr>samplNr-1) neighNr=samplNr-1;
94 if(tgoNr<1) tgoNr=fitted_n;
96 printf(
"samplNr := %d\n", samplNr);
97 printf(
"neighNr := %d\n", neighNr);
98 printf(
"tgoNr := %d\n", tgoNr);
100 printf(
"iTGO limits: [%g,%g]", lowlim[0], uplim[0]);
101 for(i=1; i<dim; i++) printf(
" [%g,%g]", lowlim[i], uplim[i]);
104#ifdef OMP_NUM_THREADS
105 printf(
"OMP_NUM_THREADS := %d\n", OMP_NUM_THREADS);
112 if(sampled_points==NULL)
return(2);
113 for(i=0; i<samplNr; i++) {
115 sampled_points[i].
fvalue=0.0;
117 delta=(
double*)malloc(dim*
sizeof(
double));
118 tempp=(
double*)malloc(samplNr*
sizeof(
double));
119 if(delta==NULL || tempp==NULL) {free(sampled_points);
return(2);}
127 for(l=0; l<tgoNr; l++) {
129 if(verbose>2) {printf(
"TGO Loop # %d: \n", l+1); fflush(stdout);}
140 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==0) {
141 sampled_points[i].
fvalue=objf(dim, sampled_points[i].par, objfData);
144 if(!isfinite(sampled_points[i].fvalue)) {
147 printf(
"this point did not give normal return value:\n");
148 for(k=0; k<dim; k++) printf(
" %10.2e", sampled_points[i].par[k]);
153 if(verbose>4 && badNr>0) printf(
"Nr of bad points: %d\n", badNr);
155 k=0;
while(k<2 && badNr>0) {
157 for(i=0; i<samplNr; i++)
158 if(sampled_points[i].topomin==0 && !isfinite(sampled_points[i].fvalue)) {
165 sampled_points[i].
fvalue=objf(dim, sampled_points[i].par, objfData);
166 if(!isfinite(sampled_points[i].fvalue)) badNr++;
168 if(verbose>4 && badNr>0) printf(
"Nr of bad points: %d\n", badNr);
172 printf(
"Sampled points:\n");
173 for(j=0; j<samplNr; j++) {
175 for(i=0; i<dim; i++) printf(
" %e ", sampled_points[j].par[i]);
176 printf(
"=>%e\n", sampled_points[j].fvalue);
181 if(l==0 && (samplNr-badNr)<=neighNr) {
183 printf(
"Error in TGO: invalid function return value from all points.\n");
186 free(sampled_points); free(delta); free(tempp);
197 for(i=0, topoNr=0; i<samplNr; i++) {
200 if(!isfinite(sampled_points[i].fvalue))
continue;
203 for(j=0; j<samplNr; j++) {
206 for(k=0, tempp[j]=0.0; k<dim; k++) {
207 deltaf=uplim[k]-lowlim[k];
if(deltaf<=0.0)
continue;
208 temp=sampled_points[i].
par[k]-sampled_points[j].
par[k];
209 if(deltaf>1.0E-20) temp/=deltaf;
210 if(isfinite(temp)) tempp[j] += temp*temp;
221 for(k=0; k<dim; k++) sampled_points[i].delta[k]=0.0;
223 for(j=0; j<neighNr; j++) {
224 min=tempp[0]; IDmin=0;
225 for(k=1; k<samplNr; k++) {
if(tempp[k]<min) {min=tempp[k]; IDmin=k;}}
230 if(isfinite(sampled_points[IDmin].fvalue) &&
231 sampled_points[IDmin].fvalue<sampled_points[i].fvalue)
break;
235 sampled_points[i].delta[k]+=
236 fabs(sampled_points[i].par[k]-sampled_points[IDmin].par[k]);
237 if(isfinite(sampled_points[IDmin].fvalue) &&
238 sampled_points[IDmin].fvalue>sampled_points[i].fvalrange)
243 if(j!=neighNr)
continue;
245 sampled_points[i].
topomin=1; topoNr++;
249 for(k=0; k<dim; k++) sampled_points[i].delta[k]/=(
double)neighNr;
254 if(verbose>2) {printf(
" %d topographical minima\n", topoNr); fflush(stdout);}
259 min=sampled_points[0].
fvalue; IDmin=0;
260 for(k=1; k<samplNr; k++)
261 if(!isfinite(min) || sampled_points[k].fvalue<min) {
262 min=sampled_points[k].
fvalue; IDmin=k;}
263 sampled_points[IDmin].
topomin=1;
265 sampled_points[IDmin].delta[k]=0.1*(uplim[k]-lowlim[k]);
266 sampled_points[i].
fvalrange+=100.0*fabs(sampled_points[i].fvalue);
268 printf(
" ; therefore minimum was set to point %d at %e\n",
269 IDmin, sampled_points[IDmin].fvalue);
275 for(i=0, min=1e+99, IDmin=0; i<samplNr; i++)
276 if(sampled_points[i].topomin==1) {
277 if(isfinite(sampled_points[i].fvalue) && sampled_points[i].fvalue<min)
279 min=sampled_points[i].
fvalue; IDmin=i;
282 printf(
" best topographical min:"); fflush(stdout);
283 for(k=0; k<dim; k++) printf(
" %e", sampled_points[IDmin].par[k]);
284 printf(
" => %e\n", sampled_points[IDmin].fvalue); fflush(stdout);
289 if(verbose>2) printf(
"local optimization for each TM\n");
290 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
293 for(k=0; k<dim; k++) delta[k]=0.1*sampled_points[i].delta[k];
294 if(verbose>3) printf(
"point %d: original fvalue=%.2e\n",
295 i+1, sampled_points[i].fvalue);
298 ret=
bobyqa(dim, 0, sampled_points[i].par, lowlim, uplim, delta, 0.0, 1.0E-03,
299 1.0E-10, tol, tol, 2000, &nevals,
300 &sampled_points[i].fvalue, objf, objfData, NULL, verbose-3);
301 if(ret<0 && verbose>0) {
302 printf(
"bobyqa error %d\n", ret); fflush(stdout);}
303 if(ret<0 && ret!=BOBYQA_ROUNDOFF_LIMITED) {
304 free(sampled_points); free(delta); free(tempp);
308 printf(
" local opt => %.2e (nr of evals=%d)\n",
309 sampled_points[i].fvalue, nevals);
316 ret=
powell(sampled_points[i].par, delta, dim, tol, &itNr,
317 &sampled_points[i].fvalue, objf, objfData, verbose-3);
318 if(ret>1 && verbose>0) {printf(
"powell error %d\n", ret); fflush(stdout);}
320 free(sampled_points); free(delta); free(tempp);
324 printf(
" local opt => %.2e (itNr=%d)\n",
325 sampled_points[i].fvalue, itNr);
335 if(verbose>2) printf(
"Final topographical minima and deltas\n");
336 else printf(
"Final topographical minima\n");
337 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
338 k=0; printf(
" %3d: %.2e", i, sampled_points[i].par[k]);
339 for(k=1; k<dim; k++) printf(
" %.2e", sampled_points[i].par[k]);
340 printf(
" => %.2e\n", sampled_points[i].fvalue); fflush(stdout);
342 k=0; printf(
" %.2e", sampled_points[i].delta[k]);
343 for(k=1; k<dim; k++) printf(
" %.2e", sampled_points[i].delta[k]);
344 printf(
" => %.2e\n", sampled_points[i].fvalrange); fflush(stdout);
354 if(verbose>2) {printf(
"Topographic minima:\n"); fflush(stdout);}
355 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
357 for(k=0; k<dim; k++) {
358 if(verbose>2) {printf(
"%e ", sampled_points[i].par[k]); fflush(stdout);}
359 delta[k]=0.1*sampled_points[i].
delta[k];
361 if(verbose>3) {printf(
"=> %e ", sampled_points[i].fvalue); fflush(stdout);}
364 ret=
bobyqa(dim, 0, sampled_points[i].par, lowlim, uplim, delta, 0.0, 1.0E-03,
365 1.0E-10, tol, tol, 2000, &nevals,
366 &sampled_points[i].fvalue, objf, objfData, NULL, verbose-3);
367 if(ret<0 && verbose>0) {
368 printf(
"bobyqa error %d\n", ret); fflush(stdout);}
369 if(ret<0 && ret!=BOBYQA_ROUNDOFF_LIMITED) {
370 free(sampled_points); free(delta); free(tempp);
374 printf(
"local opt 1st round point %d => %e (nr of evals=%d)\n",
375 i+1, sampled_points[i].fvalue, nevals);
382 ret=
powell(sampled_points[i].par, delta, dim, tol, &itNr,
383 &sampled_points[i].fvalue, objf, objfData, verbose-3);
384 if(ret>1 && verbose>0) {printf(
"powell error %d\n", ret); fflush(stdout);}
386 if(verbose>0) {printf(
"powell error %d\n", ret); fflush(stdout);}
387 free(sampled_points); free(delta); free(tempp);
391 printf(
"=> %e (itNr=%d) ", sampled_points[i].fvalue, itNr);
397 printf(
"Final topographical minima after local optimization\n");
398 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
399 k=0; printf(
" %3d: %.2e", i, sampled_points[i].par[k]);
400 for(k=1; k<dim; k++) printf(
" %.2e", sampled_points[i].par[k]);
401 printf(
" => %.2e\n", sampled_points[i].fvalue); fflush(stdout);
407 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
409 for(k=0; k<dim; k++) delta[k]=0.1*sampled_points[i].delta[k];
412 ret=
bobyqa(dim, 0, sampled_points[i].par, lowlim, uplim, delta, 0.0, 1.0E-05,
413 1.0E-10, tol, tol, 1000, &nevals,
414 &sampled_points[i].fvalue, objf, objfData, NULL, verbose-3);
415 if(ret<0 && verbose>0) {
416 printf(
"bobyqa error %d\n", ret); fflush(stdout);}
417 if(ret<0 && ret!=BOBYQA_ROUNDOFF_LIMITED) {
418 free(sampled_points); free(delta); free(tempp);
422 printf(
"local opt 2nd round point %d => %e (nr of evals=%d)\n",
423 i+1, sampled_points[i].fvalue, nevals);
430 ret=
powell(sampled_points[i].par, delta, dim, tol, &itNr,
431 &sampled_points[i].fvalue, objf, objfData, verbose-3);
432 if(ret>1 && verbose>0) {printf(
"powell error %d\n", ret); fflush(stdout);}
434 free(sampled_points); free(delta); free(tempp);
438 printf(
"=> %e (itNr=%d)\n", sampled_points[i].fvalue, itNr);
445 printf(
"Final topographical minima after 2nd local optimization\n");
446 for(i=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
447 k=0; printf(
" %3d: %.2e", i, sampled_points[i].par[k]);
448 for(k=1; k<dim; k++) printf(
" %.2e", sampled_points[i].par[k]);
449 printf(
" => %.2e\n", sampled_points[i].fvalue); fflush(stdout);
459 for(i=0, min=1e+99, IDmin=0; i<samplNr; i++)
if(sampled_points[i].topomin==1) {
460 if(isfinite(sampled_points[i].fvalue) && sampled_points[i].fvalue<min) {
461 min=sampled_points[i].
fvalue; IDmin=i;}
464 printf(
"Best topographical minimum:");
465 for(k=0; k<dim; k++) printf(
"%e ", sampled_points[IDmin].par[k]);
466 printf(
"-> %e \n", sampled_points[IDmin].fvalue); fflush(stdout);
470 deltaf=0.01; tol=5.0E-04;
472 for(k=0; k<dim; k++) delta[k]=deltaf*sampled_points[IDmin].delta[k];
475 ret=
bobyqa(dim, 0, sampled_points[IDmin].par, lowlim, uplim, delta, 0.0, tol,
476 1.0E-10, tol, tol, 5000, &nevals,
477 &sampled_points[IDmin].fvalue, objf, objfData, NULL, verbose-3);
478 if(ret<0 && verbose>0) {
479 printf(
"bobyqa error %d\n", ret); fflush(stdout);}
480 if(ret<0 && ret!=BOBYQA_ROUNDOFF_LIMITED) {
481 free(sampled_points); free(delta); free(tempp);
485 printf(
"local opt of the best point with tol=%g => %e (nr of evals=%d)\n",
486 tol, sampled_points[IDmin].fvalue, nevals);
490 deltaf*=0.5; tol*=0.1;
494 ret=
powell(sampled_points[IDmin].par, delta, dim, tol, &itNr,
495 &sampled_points[IDmin].fvalue, objf, objfData, verbose-3);
496 if(ret>1 && verbose>0) {printf(
"powell error %d\n", ret); fflush(stdout);}
498 free(sampled_points); free(delta); free(tempp);
502 printf(
" powell once more with %d iteration(s) -> WSS=%e\n",
503 itNr, sampled_points[IDmin].fvalue);
507 deltaf*=0.5; tol*=0.25;
509 }
while(itNr>1 && deltaf>1.0E-05);
514 for(k=0; k<dim; k++) gmin[k]=sampled_points[IDmin].par[k];
515 *fmin=sampled_points[IDmin].
fvalue;
516 if(!isfinite(sampled_points[IDmin].fvalue)) {
517 if(verbose>0) {printf(
"TGO error: valid minimum value was not reached.\n");
519 free(sampled_points); free(delta); free(tempp);
return(9);
523 free(sampled_points); free(delta); free(tempp);
524 if(verbose>0) {printf(
"out of tgo\n"); fflush(stdout);}