TPCCLIB
Loading...
Searching...
No Matches
bobyqa.c
Go to the documentation of this file.
1
21/******************************************************************************/
22#include "libtpcmodel.h"
23/******************************************************************************/
24
25/******************************************************************************/
26/* Local function definitions */
27void bobyqa_update(bobyqa_data *bdata);
29void bobyqa_altmov(bobyqa_data *bdata);
30void bobyqa_trsbox(bobyqa_data *bdata);
32/******************************************************************************/
33
34/******************************************************************************/
42 int n,
48 int npt,
51 double *x,
61 const double *xl,
71 const double *xu,
76 const double *dx,
81 const double rhoend,
83 double xtol_rel,
85 double minf_max,
87 double ftol_rel,
89 double ftol_abs,
91 int maxeval,
94 int *nevals,
96 double *minf,
101 double (*f)(int n, double *x, void *objf_data),
104 void *objf_data,
108 double *working_space,
110 int verbose
111) {
112 int i, j;
113 int fixed_n, fitted_n;
114 bobyqa_data bdata;
115 bobyqa_result ret;
116
117
118 if(verbose>0) printf("in bobyqa()\n");
119 if(verbose>4) {
120 printf("original dx={%g", dx[0]);
121 for(j=1; j<n; j++) printf(", %g", dx[j]);
122 printf("}\n");
123 }
124
125 /* Check if any of parameters is fixed:
126 Only free parameters are given to Bobyqa for fitting, therefore
127 the number is needed in allocating and setting up memory.
128 BOBYQA requires that at least two parameters are fitted, but later
129 a simple 1-D method is used instead when necessary */
130 fixed_n=fixed_params(n, xl, xu, dx);
131 fitted_n=n-fixed_n;
132 if(verbose>1) {
133 printf("%d parameter(s) are fixed.\n", fixed_n); fflush(stdout);
134 }
135 if(fitted_n<1) {
136 if(verbose>0) fprintf(stderr, "Error: no free parameters.\n");
137 return BOBYQA_INVALID_ARGS;
138 }
139 if(fitted_n==1 && verbose>0)
140 fprintf(stderr, "Warning: only one free parameter.\n");
141
142 /* Set npt, if user did not do that */
143 if(npt<=0) npt=2*fitted_n+1;
144 /* Verify that NPT is in the required interval */
145 if(npt<fitted_n+2 || npt>(fitted_n+2)*(fitted_n+1)/2) {
146 if(verbose>0) {
147 printf("npt:=%d\n", npt);
148 fprintf(stderr, "Error: bad npt.\n");
149 }
150 return(BOBYQA_INVALID_ARGS);
151 }
152
153 /* Allocate double working_space, if not done by caller */
154 i=bobyqa_working_memory_size(n, fitted_n, npt, &bdata);
155 ret=bobyqa_set_memory(n, fitted_n, npt, &bdata, working_space);
156 if(ret!=BOBYQA_SUCCESS) return(BOBYQA_OUT_OF_MEMORY);
157
158 /* Copy BOBYQA parameters to bdata struct */
159 ret=bobyqa_set_optimization(n, x, dx, xl, xu, rhoend, xtol_rel,
160 minf_max, ftol_rel, ftol_abs, maxeval,
161 f, objf_data, verbose, &bdata);
162 if(ret!=BOBYQA_SUCCESS) {
163 bobyqa_free_memory(&bdata); return(BOBYQA_INVALID_ARGS);
164 }
165 if(verbose>2) bobyqa_print(&bdata, 4, stdout);
166
167
168 /* Call BOBYQB */
169 if(bdata.n>1) { // BOBYQA works only if at least 2 parameters are fitted
170 ret = bobyqb(&bdata);
171 if(bdata.verbose>1) printf("ret := %d\n", ret);
172 if(bdata.verbose>0) {
173 if(ret<0) printf("Error in bobyqb(): %s\n", bobyqa_rc(ret));
174 else printf("Return code of bobyqb(): %s\n", bobyqa_rc(ret));
175 }
176 } else { // Simple local 1-D minimization when necessary
178 if(bdata.verbose>1) printf("ret := %d\n", ret);
179 if(bdata.verbose>0 && ret<0)
180 printf("Error %d in 1-D optimization\n", ret);
181 }
182 /* Copy fitted parameters to full parameter list */
183 bobyqa_xfull(&bdata);
184 for(i=0; i<n; i++) x[i]=bdata.xfull[i];
185 if(nevals!=NULL) *nevals=bdata.nevals;
186 /* Copy min value to argument pointer */
187 *minf=bdata.minf;
188
189 /* Quit */
190 if(verbose>1) {
191 printf("prelim() called %d time(s)\n", bdata.prelim_nr);
192 printf("rescue() called %d time(s)\n", bdata.rescue_nr);
193 printf("altmov() called %d time(s)\n", bdata.altmov_nr);
194 printf("trsbox() called %d time(s)\n", bdata.trsbox_nr);
195 printf("update() called %d time(s)\n", bdata.update_nr);
196 }
197 bobyqa_free_memory(&bdata);
198
199 if(verbose>0) printf("out of bobyqa() with return code %d\n", ret);
200 return ret;
201} /* bobyqa() */
202/*****************************************************************************/
203
204/*****************************************************************************/
211 bobyqa_data *bdata
212) {
213 if(bdata->verbose>0) {printf("bobyqa_minimize_single_parameter()\n"); fflush(stdout);}
214
215 double p1=0, p2=0, p3=0, f1=0, f2=0, f3=0, begin, end;
216 double d, d2;
217 const double tau=0.1;
218 double p_min, f_min, bracket_ratio;
219
220 /* Check the input */
221 if(bdata->n!=1) return BOBYQA_INVALID_ARGS;
222 if(bdata->rhoend<=0.0) return BOBYQA_INVALID_ARGS;
223 if(bdata->rhoend>=bdata->rhobeg) return BOBYQA_INVALID_ARGS;
224 if(bdata->maxeval<2) return BOBYQA_INVALID_ARGS;
225
226 begin=bdata->xl[0];
227 end=bdata->xu[0];
228
229 /* Update the full parameter list for objf() */
230 bdata->nevals=0;
231 f2 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
232 /* If parameter is fixed, then this was all that we can do */
233 if(bdata->xl[0]>=bdata->xu[0]) {
234 if(bdata->verbose>1) printf("Warning: the only parameter is fixed\n");
235 return BOBYQA_SUCCESS;
236 }
237
238 /* Find three bracketing points such that f1 > f2 < f3.
239 Do this by generating a sequence of points expanding away from 0.
240 Also note that, in the following code, it is always the
241 case that p1 < p2 < p3. */
242 p2=bdata->x[0];
243
244 /* Start by setting a starting set of 3 points that are inside the bounds */
245 p1=p2-bdata->rhobeg; if(p1>begin) p1=begin;
246 p3=p2+bdata->rhobeg; if(p3<end) p3=end;
247 /* Compute their function values */
248 bdata->x[0]=p1;
249 f1 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
250 bdata->x[0]=p3;
251
252 f3 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
253
254 if(p2==p1 || p2==p3) {
255 p2=0.5*(p1+p3);
256 bdata->x[0]=p2;
257 f2 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
258 }
259
260 /* Now we have 3 points on the function.
261 Start looking for a bracketing set such that f1 > f2 < f3 is the case. */
262 double jump_size=bdata->rhobeg;
263 while(!(f1>f2 && f2<f3)) {
264 /* check for hitting max_iter */
265 if(bdata->verbose>5) printf(" bracketing: nevals=%d\n", bdata->nevals);
266 if(bdata->nevals >= bdata->maxeval) {
267 bdata->x[0]=p2; bdata->minf=f2; return BOBYQA_MAXEVAL_REACHED;
268 }
269 /* check if required tolerance was reached */
270 if((p3-p1)<bdata->rhoend) { //if (p3-p1 < eps)
271 if(bdata->verbose>1)
272 printf(" max tolerance was reached during bracketing\n");
273 if(f1<f2 && f1<f3) {
274 bdata->x[0]=p1; bdata->minf=f1; return BOBYQA_XTOL_REACHED;
275 }
276 if(f2<f1 && f2<f3) {
277 bdata->x[0]=p2; bdata->minf=f2; return BOBYQA_XTOL_REACHED;
278 }
279 bdata->x[0]=p3; bdata->minf=f3; return BOBYQA_XTOL_REACHED;
280 }
281 if(bdata->verbose>6) printf(" jump_size=%g\n", jump_size);
282 /* if f1 is small then take a step to the left */
283 if(f1<f3) {
284 /* check if the minimum is colliding against the bounds. If so then pick
285 a point between p1 and p2 in the hopes that shrinking the interval will
286 be a good thing to do. Or if p1 and p2 aren't differentiated then try
287 and get them to obtain different values. */
288 if(p1==begin || (f1==f2 && (end-begin)<jump_size )) {
289 p3=p2; f3=f2; p2=0.5*(p1+p2);
290 bdata->x[0]=p2;
291 f2 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
292 } else {
293 /* pick a new point to the left of our current bracket */
294 p3=p2; f3=f2; p2=p1; f2=f1;
295 p1-=jump_size; if(p1<begin) p1=begin;
296 bdata->x[0]=p1;
297 f1 = bobyqa_x_funcval(bdata, bdata->x);
298 jump_size*=2.0;
299 }
300 } else { // otherwise f3 is small and we should take a step to the right
301 /* check if the minimum is colliding against the bounds. If so then pick
302 a point between p2 and p3 in the hopes that shrinking the interval will
303 be a good thing to do. Or if p2 and p3 aren't differentiated then
304 try and get them to obtain different values. */
305 if(p3==end || (f2==f3 && (end-begin)<jump_size)) {
306 p1=p2; f1=f2; p2=0.5*(p3+p2);
307 bdata->x[0]=p2;
308 f2 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
309 } else {
310 /* pick a new point to the right of our current bracket */
311 p1=p2; f1=f2; p2=p3; f2=f3;
312 p3+=jump_size; if(p3>end) p3=end;
313 bdata->x[0]=p3;
314 f3 = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
315 jump_size*=2.0;
316 }
317 }
318 }
319 if(bdata->verbose>4) printf(" brackets ready\n");
320
321 /* Loop until we have done the max allowable number of iterations or
322 the bracketing window is smaller than eps.
323 Within this loop we maintain the invariant that: f1 > f2 < f3 and
324 p1 < p2 < p3. */
325 while((bdata->nevals<bdata->maxeval) && (p3-p1>bdata->rhoend)) {
326 if(bdata->verbose>5) printf(" main loop: nevals=%d\n", bdata->nevals);
327
328 //p_min = lagrange_poly_min_extrap(p1,p2,p3, f1,f2,f3);
329 d=f1*(p3*p3-p2*p2) + f2*(p1*p1-p3*p3) + f3*(p2*p2-p1*p1);
330 d2=2.0*(f1*(p3-p2) + f2*(p1-p3) + f3*(p2-p1));
331 if(d2==0.0 || !isfinite(d/=d2)) { // d=d/d2
332 p_min=p2;
333 } else {
334 if(p1<=d && d<=p3) {p_min=d;}
335 else {p_min=d; if(p1>p_min) p_min=p1; if(p3<p_min) p_min=p3;}
336 }
337
338 /* make sure p_min isn't too close to the three points we already have */
339 if(p_min<p2) {
340 d=(p2-p1)*tau;
341 if(fabs(p1-p_min)<d) p_min=p1+d;
342 else if(fabs(p2-p_min)<d) p_min=p2-d;
343 } else {
344 d=(p3-p2)*tau;
345 if(fabs(p2-p_min)<d) p_min=p2+d;
346 else if(fabs(p3-p_min)<d) p_min=p3-d;
347 }
348
349 /* make sure one side of the bracket isn't super huge compared to the other
350 side. If it is then contract it. */
351 bracket_ratio=fabs(p1-p2)/fabs(p2-p3);
352 if(!(bracket_ratio<100.0 && bracket_ratio>0.01)) {
353 /* Force p_min to be on a reasonable side. */
354 if(bracket_ratio>1.0 && p_min>p2) p_min=0.5*(p1+p2);
355 else if(p_min<p2) p_min=0.5*(p2+p3);
356 }
357
358 /* Compute function value at p_min */
359 bdata->x[0]=p_min;
360 f_min = bdata->minf = bobyqa_x_funcval(bdata, bdata->x);
361
362 /* Remove one of the endpoints of our bracket depending on where the new point falls */
363 if(p_min<p2) {
364 if(f1>f_min && f_min<f2) {p3=p2; f3=f2; p2=p_min; f2=f_min;}
365 else {p1=p_min; f1 = f_min;}
366 } else {
367 if(f2>f_min && f_min<f3) {p1=p2; f1=f2; p2=p_min; f2=f_min;}
368 else {p3=p_min; f3=f_min;}
369 }
370 }
371 bdata->x[0]=p2; bdata->minf=f2;
372 if(bdata->nevals>=bdata->maxeval) return BOBYQA_MAXEVAL_REACHED;
373 return BOBYQA_XTOL_REACHED;
374}
375/*****************************************************************************/
376
377/*****************************************************************************/
383) {
384 static char *bobyqa_msg[] = {
385 /* 0 */ "failure",
386 /* 1 */ "invalid argument",
387 /* 2 */ "out of memory",
388 /* 3 */ "round-off limited",
389 /* 4 */ "success",
390 /* 5 */ "requested function value reached",
391 /* 6 */ "function value tolerance reached",
392 /* 7 */ "relative function value tolerance reached",
393 /* 8 */ "absolute function value tolerance reached",
394 /* 9 */ "parameter tolerance reached",
395 /* 10 */ "maximum number of function evaluations reached",
396 0};
397 switch(rc) {
398 case BOBYQA_FAIL: return bobyqa_msg[0];
399 case BOBYQA_INVALID_ARGS: return bobyqa_msg[1];
400 case BOBYQA_OUT_OF_MEMORY: return bobyqa_msg[2];
401 case BOBYQA_ROUNDOFF_LIMITED: return bobyqa_msg[3];
402 case BOBYQA_SUCCESS: return bobyqa_msg[4];
403 case BOBYQA_MINF_MAX_REACHED: return bobyqa_msg[5];
404 case BOBYQA_FTOL_REACHED: return bobyqa_msg[6];
405 case BOBYQA_RELFTOL_REACHED: return bobyqa_msg[7];
406 case BOBYQA_ABSFTOL_REACHED: return bobyqa_msg[8];
407 case BOBYQA_XTOL_REACHED: return bobyqa_msg[9];
408 case BOBYQA_MAXEVAL_REACHED: return bobyqa_msg[10];
409 }
410 return bobyqa_msg[0];
411}
412/*****************************************************************************/
413
414/*****************************************************************************/
420 int n,
422 const double *lower,
424 const double *upper,
426 const double *delta
427) {
428 int i, fixed_n=0;
429 for(i=0; i<n; i++) {
430 if(upper[i]<=lower[i]) {fixed_n++; continue;}
431 if(delta!=NULL && delta[i]==0.0) fixed_n++;
432 }
433 return(fixed_n);
434}
435/*****************************************************************************/
436
437/*****************************************************************************/
443 int n,
445 int fitted_n,
447 int npt,
449 bobyqa_data *bdata
450) {
451 int i=0, s, np, ndim;
452
453 np=fitted_n+1; ndim=npt+fitted_n;
454
455 s=n; i+=s; if(bdata!=NULL) bdata->nfull=s;
456
457 s=fitted_n; i+=s; if(bdata!=NULL) bdata->x_size=s;
458 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xl_size=s;
459 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xu_size=s;
460 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xbase_size=s;
461 s=fitted_n*npt; i+=s; if(bdata!=NULL) bdata->xpt_size=s;
462 s=npt; i+=s; if(bdata!=NULL) bdata->fval_size=s;
463 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xopt_size=s;
464 s=fitted_n; i+=s; if(bdata!=NULL) bdata->gopt_size=s;
465 s=fitted_n*np/2; i+=s; if(bdata!=NULL) bdata->hq_size=s;
466 s=npt; i+=s; if(bdata!=NULL) bdata->pq_size=s;
467 s=ndim*fitted_n; i+=s; if(bdata!=NULL) bdata->bmat_size=s;
468 s=npt*(npt-np); i+=s; if(bdata!=NULL) bdata->zmat_size=s;
469 s=fitted_n; i+=s; if(bdata!=NULL) bdata->sl_size=s;
470 s=fitted_n; i+=s; if(bdata!=NULL) bdata->su_size=s;
471 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xnew_size=s;
472 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xalt_size=s;
473 s=fitted_n; i+=s; if(bdata!=NULL) bdata->dtrial_size=s;
474 s=ndim; i+=s; if(bdata!=NULL) bdata->vlag_size=s;
475
476 s=2*npt; i+=s; if(bdata!=NULL) bdata->w2npt_size=s;
477 s=ndim; i+=s; if(bdata!=NULL) bdata->wndim_size=s;
478 s=fitted_n; i+=s; if(bdata!=NULL) bdata->wn_size=s;
479 s=fitted_n; i+=s; if(bdata!=NULL) bdata->gnew_size=s;
480 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xbdi_size=s;
481 s=fitted_n; i+=s; if(bdata!=NULL) bdata->s_size=s;
482 s=fitted_n; i+=s; if(bdata!=NULL) bdata->hs_size=s;
483 s=fitted_n; i+=s; if(bdata!=NULL) bdata->hred_size=s;
484 s=fitted_n; i+=s; if(bdata!=NULL) bdata->glag_size=s;
485 s=npt; i+=s; if(bdata!=NULL) bdata->hcol_size=s;
486 s=2*fitted_n; i+=s; if(bdata!=NULL) bdata->ccstep_size=s;
487
488 s=fitted_n; i+=s; if(bdata!=NULL) bdata->xscale_size=s;
489
490 //bobyqa_print(bdata, 2, stdout);
491 return(i);
492}
493/*****************************************************************************/
494
495/*****************************************************************************/
503 int n,
505 int fitted_n,
507 int npt,
509 bobyqa_data *bdata,
511 double *wm
512) {
513 int wmsize;
514 double *lwm, *wptr;
515 int *liwm;
516
517 if(n<1 || fitted_n<1 || npt<1 || bdata==NULL) return BOBYQA_INVALID_ARGS;
518
519 /* Determine the required size of working memory and set the sizes inside data struct */
520 wmsize=bobyqa_working_memory_size(n, fitted_n, npt, bdata);
521
522 /* If working memory for doubles is not preallocated, then allocate it */
523 if(wm!=NULL) {
524 lwm=wm; bdata->lwmptr=NULL;
525 } else {
526 /* Allocate working memory */
527 lwm=(double*)malloc(sizeof(double)*wmsize);
528 if(lwm==NULL) {
529 return(BOBYQA_OUT_OF_MEMORY);
530 }
531 bdata->lwmptr=lwm;
532 }
533 bdata->wmptr=lwm;
534
535 /* Working memory for integers is always allocated here */
536 liwm=(int*)malloc(sizeof(int)*fitted_n);
537 if(liwm==NULL) {
538 if(wm==NULL) bobyqa_free_memory(bdata);
539 return(BOBYQA_OUT_OF_MEMORY);
540 }
541 bdata->liwmptr=liwm;
542
543 /* Set data pointers inside bobyqa struct */
544 bdata->xplace=bdata->liwmptr;
545 wptr=bdata->wmptr;
546 bdata->xfull=wptr; wptr+=bdata->nfull;
547 bdata->x=wptr; wptr+=bdata->x_size;
548 bdata->xl=wptr; wptr+=bdata->xl_size;
549 bdata->xu=wptr; wptr+=bdata->xu_size;
550 bdata->xbase=wptr; wptr+=bdata->xbase_size;
551 bdata->xpt=wptr; wptr+=bdata->xpt_size;
552 bdata->fval=wptr; wptr+=bdata->fval_size;
553 bdata->xopt=wptr; wptr+=bdata->xopt_size;
554 bdata->gopt=wptr; wptr+=bdata->gopt_size;
555 bdata->hq=wptr; wptr+=bdata->hq_size;
556 bdata->pq=wptr; wptr+=bdata->pq_size;
557 bdata->bmat=wptr; wptr+=bdata->bmat_size;
558 bdata->zmat=wptr; wptr+=bdata->zmat_size;
559 bdata->sl=wptr; wptr+=bdata->sl_size;
560 bdata->su=wptr; wptr+=bdata->su_size;
561 bdata->xnew=wptr; wptr+=bdata->xnew_size;
562 bdata->xalt=wptr; wptr+=bdata->xalt_size;
563 bdata->dtrial=wptr; wptr+=bdata->dtrial_size;
564 bdata->vlag=wptr; wptr+=bdata->vlag_size;
565 bdata->w2npt=wptr; wptr+=bdata->w2npt_size;
566 bdata->wndim=wptr; wptr+=bdata->wndim_size;
567 bdata->wn=wptr; wptr+=bdata->wn_size;
568 bdata->gnew=wptr; wptr+=bdata->gnew_size;
569 bdata->xbdi=wptr; wptr+=bdata->xbdi_size;
570 bdata->s=wptr; wptr+=bdata->s_size;
571 bdata->hs=wptr; wptr+=bdata->hs_size;
572 bdata->hred=wptr; wptr+=bdata->hred_size;
573 bdata->glag=wptr; wptr+=bdata->glag_size;
574 bdata->hcol=wptr; wptr+=bdata->hcol_size;
575 bdata->ccstep=wptr; wptr+=bdata->ccstep_size;
576 bdata->xscale=wptr; wptr+=bdata->xscale_size;
577
578 /* Set struct contents */
579 bdata->n=fitted_n;
580 bdata->nfull=n;
581 bdata->npt=npt;
582 bdata->ndim = npt+fitted_n;
583 if(bobyqa_reset_memory(bdata)!=BOBYQA_SUCCESS) return BOBYQA_INVALID_ARGS;
584
585 return BOBYQA_SUCCESS;
586}
587/*****************************************************************************/
594 bobyqa_data *bdata
595) {
596 if(bdata==NULL) return BOBYQA_INVALID_ARGS;
597 /* Free double working memory, if it was allocated by bobyqa_set_memory() */
598 if(bdata->lwmptr!=NULL) free(bdata->lwmptr);
599 bdata->lwmptr=NULL;
600 /* Free integer working memory */
601 if(bdata->liwmptr!=NULL) free(bdata->liwmptr);
602 bdata->liwmptr=NULL;
603 return BOBYQA_SUCCESS;
604}
605/*****************************************************************************/
606
607/*****************************************************************************/
616 bobyqa_data *bdata
617) {
618
619 if(bdata==NULL) return BOBYQA_INVALID_ARGS;
620 if(bdata->npt<1 || bdata->n<1) return BOBYQA_INVALID_ARGS;
621
622 /* Initiate struct variables */
623 bdata->dsq=0.0;
624 bdata->xoptsq=0.0;
625 bdata->rc = BOBYQA_SUCCESS;
626 bdata->knew = 0;
627 bdata->scaden = 0.0;
628 bdata->biglsq = 0.0;
629 bdata->nptm = bdata->npt - (bdata->n+1);
630 bdata->nevals=0;
631 bdata->rescue_nr=bdata->altmov_nr=bdata->trsbox_nr=bdata->update_nr=0;
632 bdata->prelim_nr=0;
633
634 return BOBYQA_SUCCESS;
635}
636/*****************************************************************************/
637
638/*****************************************************************************/
642 bobyqa_data *bdata,
645 int sw,
647 FILE *fp
648) {
649 int i;
650
651 if(bdata==NULL) {
652 fprintf(fp, "bobyqa data struct not defined.\n");
653 return;
654 }
655
656 if(sw==0 || sw==1) {
657 fprintf(fp, "nfull=%d\n", bdata->nfull);
658 fprintf(fp, "n=%d\n", bdata->n);
659 fprintf(fp, "npt=%d\n", bdata->npt);
660 fprintf(fp, "ndim=%d\n", bdata->ndim);
661 }
662
663 if(sw==0 || sw==2) {
664 fprintf(fp, "nfull=%d\n", bdata->nfull);
665 fprintf(fp, "x_size=%d\n", bdata->x_size);
666 fprintf(fp, "xl_size=%d\n", bdata->xl_size);
667 fprintf(fp, "xu_size=%d\n", bdata->xu_size);
668 fprintf(fp, "xbase_size=%d\n", bdata->xbase_size);
669 fprintf(fp, "xpt_size=%d\n", bdata->xpt_size);
670 fprintf(fp, "fval_size=%d\n", bdata->fval_size);
671 fprintf(fp, "xopt_size=%d\n", bdata->xopt_size);
672 fprintf(fp, "gopt_size=%d\n", bdata->gopt_size);
673 fprintf(fp, "hq_size=%d\n", bdata->hq_size);
674 fprintf(fp, "pq_size=%d\n", bdata->pq_size);
675 fprintf(fp, "bmat_size=%d\n", bdata->bmat_size);
676 fprintf(fp, "zmat_size=%d\n", bdata->zmat_size);
677 fprintf(fp, "sl_size=%d\n", bdata->sl_size);
678 fprintf(fp, "su_size=%d\n", bdata->su_size);
679 fprintf(fp, "xnew_size=%d\n", bdata->xnew_size);
680 fprintf(fp, "xalt_size=%d\n", bdata->xalt_size);
681 fprintf(fp, "dtrial_size=%d\n", bdata->dtrial_size);
682 fprintf(fp, "vlag_size=%d\n", bdata->vlag_size);
683 fprintf(fp, "w2npt_size=%d\n", bdata->w2npt_size);
684 fprintf(fp, "wndim_size=%d\n", bdata->wndim_size);
685 fprintf(fp, "wn_size=%d\n", bdata->wn_size);
686 fprintf(fp, "gnew_size=%d\n", bdata->gnew_size);
687 fprintf(fp, "xbdi_size=%d\n", bdata->xbdi_size);
688 fprintf(fp, "s_size=%d\n", bdata->s_size);
689 fprintf(fp, "hs_size=%d\n", bdata->hs_size);
690 fprintf(fp, "hred_size=%d\n", bdata->hred_size);
691 fprintf(fp, "glag_size=%d\n", bdata->hred_size);
692 fprintf(fp, "hcol_size=%d\n", bdata->hcol_size);
693 fprintf(fp, "ccstep_size=%d\n", bdata->ccstep_size);
694 fprintf(fp, "xscale_size=%d\n", bdata->xscale_size);
695 }
696
697 if(sw==0 || sw==3) {
698 fprintf(fp, "full parameter list:\n");
699 for(i=0; i<bdata->nfull; i++) {
700 fprintf(fp, " xfull[%d] = %g\n", i, bdata->xfull[i]);
701 }
702 }
703
704 if(sw==0 || sw==4) {
705 fprintf(fp, "fitted parameter indices =");
706 for(i=0; i<bdata->n; i++) {
707 fprintf(fp, " xplace[%d] = %d\n", i, bdata->xplace[i]);
708 }
709 fprintf(fp, "fitted parameter list:\n");
710 for(i=0; i<bdata->n; i++) {
711 fprintf(fp, " x[%d] = %g\n", i, bdata->x[i]);
712 }
713 fprintf(fp, "lower limits:\n");
714 for(i=0; i<bdata->n; i++) {
715 fprintf(fp, " xl[%d] = %g\n", i, bdata->xl[i]);
716 }
717 fprintf(fp, "upper limits:\n");
718 for(i=0; i<bdata->n; i++) {
719 fprintf(fp, " xu[%d] = %g\n", i, bdata->xu[i]);
720 }
721 fprintf(fp, "rescaling factors:\n");
722 for(i=0; i<bdata->n; i++) {
723 fprintf(fp, " xscale[%d] = %g\n", i, bdata->xscale[i]);
724 }
725 fprintf(fp, "rhobeg=%g\n", bdata->rhobeg);
726 fprintf(fp, "rhoend=%g\n", bdata->rhoend);
727
728 fprintf(fp, "scaled lower bounds:\n");
729 for(i=0; i<bdata->n; i++) {
730 fprintf(fp, " sl[%d] = %g\n", i, bdata->sl[i]);
731 }
732 fprintf(fp, "scaled upper bounds:\n");
733 for(i=0; i<bdata->n; i++) {
734 fprintf(fp, " su[%d] = %g\n", i, bdata->su[i]);
735 }
736 }
737
738 return;
739}
740/*****************************************************************************/
741
742/*****************************************************************************/
752 bobyqa_data *bdata,
753 double *x
754) {
755 int j;
756 double v;
757
758 for(j=0; j<bdata->n; j++) bdata->xfull[bdata->xplace[j]]=x[j]*bdata->xscale[j];
759 v = bdata->objf(bdata->nfull, bdata->xfull, bdata->objf_data);
760 bdata->nevals++;
761 return(v);
762}
763/******************************************************************************/
764
765/******************************************************************************/
770 bobyqa_data *bdata
771) {
772 for(int j=0; j<bdata->n; j++)
773 bdata->xfull[bdata->xplace[j]]=bdata->x[j]*bdata->xscale[j];
774}
775/******************************************************************************/
776
777/******************************************************************************/
783 int full_n,
785 double *x,
787 const double *dx,
789 const double *xl,
791 const double *xu,
793 const double rhoend,
795 double xtol_rel,
797 double minf_max,
799 double ftol_rel,
801 double ftol_abs,
803 int maxeval,
805 double (*f)(int n, double *x, void *objf_data),
808 void *objf_data,
810 int verbose,
812 bobyqa_data *bdata
813) {
814 int i, j;
815 double d, dm;
816
817 if(bdata==NULL) return BOBYQA_INVALID_ARGS;
818 if(full_n!=bdata->nfull) return BOBYQA_INVALID_ARGS;
819 if(x==NULL || dx==NULL) return BOBYQA_INVALID_ARGS;
820 if(xl==NULL || xu==NULL) return BOBYQA_INVALID_ARGS;
821
822 /* Copy full parameter list */
823 for(i=0; i<full_n; i++) bdata->xfull[i]=x[i];
824
825 /* Make list of fitted parameters (those that are not fixed);
826 and internal list of their positions in full list;
827 and rescaling factor for each dimension based on initial step size
828 so that initial step size would be equal in all directions
829 */
830 for(i=j=0; i<full_n; i++) if(dx[i]!=0.0 && xu[i]>xl[i]) {
831 /* Positions in full list */
832 bdata->xplace[j]=i;
833 /* Set scaling factors */
834 bdata->xscale[j]=fabs(dx[i]);
835 /* Set initial scaled parameters */
836 bdata->x[j]=x[i]/bdata->xscale[j];
837 /* Set scaled limits */
838 bdata->xl[j]=xl[i]/bdata->xscale[j];
839 bdata->xu[j]=xu[i]/bdata->xscale[j];
840 j++; // index of fitted parameters
841 } // next parameter
842 /* check that nr of fitted parameters is the same that was used to
843 allocate memory in the data struct */
844 if(j!=bdata->n) return BOBYQA_INVALID_ARGS;
845
846 /* Initial step sizes are now internally scaled to 1, therefore: */
847 bdata->rhobeg = 1.0;
848 /* however, 2*rhobeg must be <= xu[]-xl[] */
849 j=0; dm=bdata->xu[j]-bdata->xl[j];
850 for(j=1; j<bdata->n; j++) {d=bdata->xu[j]-bdata->xl[j]; if(d<dm) dm=d;}
851 if(dm < 2.*bdata->rhobeg) {
852 if(dm>1.0E-20) {
853 /* Set smaller rhobeg to have sufficient space between the bounds */
854 bdata->rhobeg=0.5*dm;
855 } else {
856 /* Return from BOBYQA because one of the differences
857 XU(I)-XL(I)s is less than 2*RHOBEG, and very small, too. */
858 if(verbose>0) fprintf(stderr, "Error: stepsize<2*rhobeg\n");
859 printf("smallest stepsize=%g 2*rhobeg=%g\n", dm, 2.*bdata->rhobeg);
860 return(BOBYQA_INVALID_ARGS);
861 }
862 }
863
864 /* Set rhoend; if not given by caller, then compute rhoend from
865 optimization stop info */
866 if(rhoend>0.0) bdata->rhoend=rhoend;
867 else bdata->rhoend = xtol_rel * bdata->rhobeg;
868 if(!isfinite(bdata->rhoend)) bdata->rhoend=1.0E-14;
869
870 /* Return error if there is insufficient space between the bounds.
871 Modify the initial estimates X[], if necessary, in order to avoid
872 conflicts between the bounds and the construction of the first quadratic
873 model.
874 The lower and upper bounds (sl[], su[]) on moves from the updated X[]
875 are set now, in order to provide useful and exact information about
876 components of X[] that become within distance RHOBEG from their bounds. */
877 for(j=0; j<bdata->n; j++) {
878 d=bdata->xu[j]-bdata->xl[j];
879 /* Set sl and su */
880 bdata->sl[j]= bdata->xl[j]-bdata->x[j];
881 bdata->su[j] = bdata->xu[j]-bdata->x[j];
882 if(bdata->sl[j] >= -bdata->rhobeg) {
883 if(bdata->sl[j] >= 0.0) {
884 bdata->x[j]=bdata->xl[j];
885 bdata->sl[j]=0.0;
886 bdata->su[j]=d;
887 } else {
888 bdata->x[j]=bdata->xl[j]+bdata->rhobeg;
889 bdata->sl[j]=-bdata->rhobeg;
890 bdata->su[j]=fmax(bdata->xu[j]-bdata->x[j], bdata->rhobeg);
891 }
892 } else if(bdata->su[j] <= bdata->rhobeg) {
893 if(bdata->su[j] <= 0.0) {
894 bdata->x[j]=bdata->xu[j];
895 bdata->sl[j]=-d;
896 bdata->su[j]=0.0;
897 } else {
898 bdata->x[j]=bdata->xu[j]-bdata->rhobeg;
899 bdata->sl[j]=fmin(bdata->xl[j]-bdata->x[j], -bdata->rhobeg);
900 bdata->su[j]=bdata->rhobeg;
901 }
902 }
903 }
904
905 bdata->verbose=verbose;
906 bdata->minf_max=minf_max;
907 bdata->ftol_rel=ftol_rel;
908 bdata->ftol_abs=ftol_abs;
909 bdata->maxeval=maxeval;
910
911 bdata->objf=(bobyqa_func)f;
912 bdata->objf_data=objf_data;
913
914 return BOBYQA_SUCCESS;
915}
916/*****************************************************************************/
917
918/*****************************************************************************/
919// BOBYQB
922{
923 double a, fval;
924 int i;
925
926 if(bdata->verbose>5) {printf("bobyqb_xupdate()\n"); fflush(stdout);}
927 fval=bdata->fval[bdata->kopt-1];
928 //printf("fsave=%g fval=%g minf=%g\n", bdata->fsave, fval, bdata->minf);
929 if(fval<=bdata->fsave) {
930 for(i=0; i<bdata->n; i++) {
931 a=fmax(bdata->xl[i], bdata->xbase[i]+bdata->xopt[i]);
932 bdata->x[i]=fmin(a, bdata->xu[i]);
933 if(bdata->xopt[i]==bdata->sl[i]) bdata->x[i]=bdata->xl[i];
934 if(bdata->xopt[i]==bdata->su[i]) bdata->x[i]=bdata->xu[i];
935 }
936 bdata->minf = fval;
937 /* Update also the full parameter list */
938 bobyqa_xfull(bdata);
939 } else {
940 bdata->minf = bdata->fsave; // Added by VO 2012-09-10
941 }
942}
943/******************************************************************************/
946{
947 int i, j, k;
948 double dtemp;
949
950 if(bdata->verbose>5) {printf("update_gopt()\n"); fflush(stdout);}
951 for(j=k=0; j<bdata->n; j++) for(i=0; i<=j; i++, k++) {
952 if(i<j) bdata->gopt[j]+=bdata->hq[k]*bdata->xopt[i];
953 bdata->gopt[i]+=bdata->hq[k]*bdata->xopt[j];
954 }
955 if(bdata->nevals<=bdata->npt) return;
956 for(k=0; k<bdata->npt; k++) {
957 dtemp=0.0;
958 for(j=0; j<bdata->n; j++)
959 dtemp+=bdata->xpt[k + j*bdata->npt]*bdata->xopt[j];
960 dtemp*=bdata->pq[k];
961 for(j=0; j<bdata->n; j++)
962 bdata->gopt[j]+=dtemp*bdata->xpt[k + j*bdata->npt];
963 }
964 return;
965}
966/******************************************************************************/
974{
975 double fracsq, sumpq=0.0, sum, temp, sumz, sumw;
976 int i, j, k, jj;
977
978 if(bdata->verbose>5) {printf("shift_xbase()\n"); fflush(stdout);}
979 fracsq=0.25*bdata->xoptsq;
980 for(k=0; k<bdata->npt; k++) {
981 sumpq+=bdata->pq[k];
982 sum=-0.5*bdata->xoptsq;
983 if(!isfinite(sumpq) || !isfinite(sum)) {
984 if(bdata->verbose>0) {
985 printf("INF in shift_xbase(): sumpq=%E sum=%E\n", sumpq, sum);
986 exit(345);
987 }
988 }
989 for(i=0; i<bdata->n; i++) sum+=bdata->xpt[k+i*bdata->npt]*bdata->xopt[i];
990 // bdata->w2npt[bdata->npt+k]=sum; // Original code
991 bdata->w2npt[k]=sum;
992
993
994 temp=fracsq-0.5*sum; //printf("temp=%.15E\n", temp);
995 for(i=0; i<bdata->n; i++) {
996 bdata->wn[i]=bdata->bmat[k+i*bdata->ndim];
997 bdata->vlag[i]=sum*bdata->xpt[k+i*bdata->npt] + temp*bdata->xopt[i];
998 for(j=0; j<=i; j++)
999 bdata->bmat[bdata->npt+i + j*bdata->ndim] +=
1000 bdata->wn[i]*bdata->vlag[j] + bdata->vlag[i]*bdata->wn[j];
1001 }
1002 }
1003
1004
1005 /* Then the revisions of BMAT that depend on ZMAT are calculated. */
1006 for(jj=0; jj<bdata->nptm; jj++) {
1007 sumz=sumw=0.0;
1008 for(k=0; k<bdata->npt; k++) {
1009 sumz+=bdata->zmat[k+jj*bdata->npt];
1010 // Original code:
1011 // bdata->vlag[k]=bdata->w2npt[bdata->npt+k]*bdata->zmat[k+jj*bdata->npt];
1012 bdata->vlag[k]=bdata->w2npt[k]*bdata->zmat[k+jj*bdata->npt];
1013 sumw+=bdata->vlag[k];
1014 }
1015 for(i=0; i<bdata->n; i++) {
1016 sum=(fracsq*sumz - 0.5*sumw)*bdata->xopt[i];
1017 for(k=0; k<bdata->npt; k++) sum+=bdata->vlag[k]*bdata->xpt[k+i*bdata->npt];
1018 bdata->wn[i]=sum;
1019 for(k=0; k<bdata->npt; k++)
1020 bdata->bmat[k+i*bdata->ndim] += sum*bdata->zmat[k+jj*bdata->npt];
1021 }
1022 for(i=0; i<bdata->n; i++) for(j=0; j<=i; j++)
1023 bdata->bmat[i+bdata->npt + j*bdata->ndim] += bdata->wn[i]*bdata->wn[j];
1024 }
1025
1026
1027 /* The following instructions complete the shift, including the changes
1028 to the second derivative parameters of the quadratic model. */
1029 for(i=jj=0; i<bdata->n; i++) {
1030 bdata->wn[i]=-0.5*sumpq*bdata->xopt[i];
1031 for(k=0; k<bdata->npt; k++) {
1032 bdata->wn[i] += bdata->pq[k]*bdata->xpt[k+i*bdata->npt];
1033 bdata->xpt[k+i*bdata->npt]-=bdata->xopt[i];
1034 }
1035 for(j=0; j<=i; j++, jj++) {
1036 bdata->hq[jj] +=
1037 bdata->wn[j]*bdata->xopt[i] + bdata->xopt[j]*bdata->wn[i];
1038 bdata->bmat[bdata->npt+j+i*bdata->ndim] =
1039 bdata->bmat[bdata->npt+i+j*bdata->ndim];
1040 }
1041 }
1042 for(i=0; i<bdata->n; i++) {
1043 bdata->xbase[i]+=bdata->xopt[i]; bdata->xnew[i]-=bdata->xopt[i];
1044 bdata->sl[i] -= bdata->xopt[i]; bdata->su[i] -= bdata->xopt[i];
1045 bdata->xopt[i] = 0.0;
1046 }
1047 bdata->xoptsq=0.0;
1048}
1049/******************************************************************************/
1050
1051/******************************************************************************/
1056{
1057 int i, j, k;
1058 double dx, bsum, sum, suma, sumb;
1059
1060 if(bdata->verbose>5) {printf("bobyqb_vlag_beta_for_d()\n"); fflush(stdout);}
1061 for(k=0; k<bdata->npt; k++) {
1062 for(j=0, suma=sumb=sum=0.0; j<bdata->n; j++) {
1063 suma+=bdata->xpt[k+j*bdata->npt]*bdata->dtrial[j];
1064 sumb+=bdata->xpt[k+j*bdata->npt]*bdata->xopt[j];
1065 sum+=bdata->bmat[k+j*bdata->ndim]*bdata->dtrial[j];
1066 }
1067 bdata->w2npt[k]=suma*(0.5*suma+sumb); bdata->vlag[k]=sum;
1068 bdata->w2npt[bdata->npt+k]=suma;
1069 }
1070 for(j=0, bdata->beta=0.0; j<bdata->nptm; j++) {
1071 for(k=0, sum=0.0; k<bdata->npt; k++)
1072 sum+=bdata->zmat[k+j*bdata->npt]*bdata->w2npt[k];
1073 bdata->beta-=sum*sum;
1074 for(k=0; k<bdata->npt; k++)
1075 bdata->vlag[k]+=sum*bdata->zmat[k+j*bdata->npt];
1076 }
1077 bdata->dsq=bsum=dx=0.0;
1078 for(j=0; j<bdata->n; j++) {
1079 bdata->dsq += bdata->dtrial[j]*bdata->dtrial[j];
1080 for(k=0, sum=0.0; k<bdata->npt; k++)
1081 sum+=bdata->w2npt[k]*bdata->bmat[k+j*bdata->ndim];
1082 bsum+=sum*bdata->dtrial[j];
1083 for(i=0; i<bdata->n; i++)
1084 sum+=bdata->bmat[bdata->npt+j+i*bdata->ndim]*bdata->dtrial[i];
1085 bdata->vlag[bdata->npt+j]=sum; bsum+=sum*bdata->dtrial[j];
1086 dx+=bdata->dtrial[j]*bdata->xopt[j];
1087 }
1088 bdata->beta+= dx*dx + bdata->dsq*(bdata->xoptsq+dx+dx+0.5*bdata->dsq) - bsum;
1089 bdata->vlag[bdata->kopt-1]+=1.0;
1090}
1091/******************************************************************************/
1094{
1095 int i, ih, j, k, nh, ksav;
1096 double d1, diff, temp, den, densav, hdiag, pqold;
1097 double suma, sumb, sum, gqsq, gisq;
1098
1099 if(bdata->verbose>5) {printf("calc_with_xnew()\n"); fflush(stdout);}
1100
1101 /* Put the variables for the next calculation of the objective function
1102 in XNEW, with any adjustments for the bounds */
1103 for (i=0; i<bdata->n; i++) {
1104 d1=fmax(bdata->xl[i], bdata->xbase[i]+bdata->xnew[i]);
1105 bdata->x[i]=fmin(d1, bdata->xu[i]);
1106 if(bdata->xnew[i]==bdata->sl[i]) bdata->x[i]=bdata->xl[i];
1107 if(bdata->xnew[i]==bdata->su[i]) bdata->x[i]=bdata->xu[i];
1108 }
1109
1110 /* Calculate the value of the objective function at XBASE+XNEW, unless
1111 the limit on the number of calculations of F has been reached. */
1112 if((bdata->maxeval>0) && (bdata->nevals>=bdata->maxeval)) {
1113 if(bdata->verbose>3) printf("BOBYQA_MAXEVAL_REACHED\n");
1114 bdata->rc = BOBYQA_MAXEVAL_REACHED;
1115 }
1116 if(bdata->rc != BOBYQA_SUCCESS) {
1117 bobyqb_xupdate(bdata);
1118 return bdata->rc;
1119 }
1120
1121 /* Update the full parameter list for objf() */
1122 bdata->newf=bobyqa_x_funcval(bdata, bdata->x);
1123 if(bdata->ntrits == -1) {
1124 bdata->fsave = bdata->newf;
1125 if(bdata->verbose>3) printf("BOBYQA_XTOL_REACHED 1\n");
1126 bdata->rc = BOBYQA_XTOL_REACHED;
1127 bobyqb_xupdate(bdata);
1128 return bdata->rc;
1129 }
1130
1131 if(bdata->newf < bdata->minf_max) {
1132 bdata->minf = bdata->newf;
1133 if(bdata->verbose>3) printf("BOBYQA_MINF_MAX_REACHED\n");
1134 return BOBYQA_MINF_MAX_REACHED;
1135 }
1136
1137 /* Use the quadratic model to predict the change in F due to the step D,
1138 and set DIFF to the error of this prediction. */
1139 bdata->fopt=bdata->fval[bdata->kopt-1]; bdata->vquad=0.0;
1140 for(j=ih=0; j<bdata->n; j++) {
1141 bdata->vquad += bdata->dtrial[j]*bdata->gopt[j];
1142 for(i=0; i<=j; i++, ih++) {
1143 temp = bdata->dtrial[i]*bdata->dtrial[j]; if(i==j) temp*=0.5;
1144 bdata->vquad += bdata->hq[ih]*temp;
1145 }
1146 }
1147 for(k=0; k<bdata->npt; k++)
1148 bdata->vquad += 0.5*bdata->pq[k]*(bdata->w2npt[bdata->npt+k]*bdata->w2npt[bdata->npt+k]);
1149
1150 diff = bdata->newf - bdata->fopt - bdata->vquad;
1151 bdata->diffc=bdata->diffb; bdata->diffb=bdata->diffa;
1152 bdata->diffa=fabs(diff);
1153 if(bdata->dnorm > bdata->rho) bdata->nfsav=bdata->nevals;
1154
1155 /* Pick the next value of DELTA after a trust region step. */
1156 if(bdata->ntrits > 0 && bdata->vquad >= 0.0) {
1157 /* Return from BOBYQA because a trust region step has failed to reduce Q. */
1158#if(0) // this is the original way of doing this
1159 if(bdata->verbose>3)
1160 printf("BOBYQA_ROUNDOFF_LIMITED 3; ntrits=%d vquad=%g\n",
1161 bdata->ntrits, bdata->vquad);
1162 bdata->rc = BOBYQA_ROUNDOFF_LIMITED; /* or FTOL_REACHED? */
1163 bobyqb_xupdate(bdata); //*bdata.minf = f;
1164 return bdata->rc;
1165#else // this might work better with scales
1166 bdata->fsave = bdata->newf;
1167 if(bdata->verbose>3) printf("BOBYQA_XTOL_REACHED 2\n");
1168 bdata->rc = BOBYQA_XTOL_REACHED;
1169 bobyqb_xupdate(bdata);
1170 return bdata->rc;
1171#endif
1172 }
1173
1174 if(bdata->ntrits > 0) {
1175 bdata->ratio=(bdata->newf-bdata->fopt)/bdata->vquad;
1176 if(bdata->ratio <= 0.1) {
1177 bdata->delta = fmin(0.5*bdata->delta, bdata->dnorm);
1178 } else if(bdata->ratio <= .7) {
1179 bdata->delta = fmax(0.5*bdata->delta, bdata->dnorm);
1180 } else {
1181 bdata->delta = fmax(0.5*bdata->delta, bdata->dnorm + bdata->dnorm);
1182 }
1183 if(bdata->delta <= 1.5*bdata->rho) bdata->delta=bdata->rho;
1184
1185 /* Recalculate KNEW and DENOM if the new F is less than FOPT. */
1186 if(bdata->newf < bdata->fopt) {
1187 ksav=bdata->knew; densav=bdata->denom;
1188 bdata->delsq=bdata->delta*bdata->delta; bdata->scaden=0.0;
1189 bdata->biglsq=0.0; bdata->knew=0;
1190 for(k=0; k<bdata->npt; k++) {
1191 for(j=0, hdiag=0.0; j<bdata->nptm; j++)
1192 hdiag+=bdata->zmat[k+j*bdata->npt]*bdata->zmat[k+j*bdata->npt];
1193 if(!isfinite(hdiag) && bdata->verbose>0)
1194 printf("INF in calc_with_xnew(): k=%d hdiag=%.10E\n", k, hdiag);
1195 den=bdata->beta*hdiag + bdata->vlag[k]*bdata->vlag[k];
1196 if(!isfinite(den) && bdata->verbose>0) {
1197 printf("INF in calc_with_xnew(): k=%d den=%.10E\n", k, den);
1198 }
1199 for(j=0, bdata->distsq=0.0; j<bdata->n; j++) {
1200 d1=bdata->xpt[k+j*bdata->npt]-bdata->xnew[j];
1201 bdata->distsq+=d1*d1;
1202 }
1203 if(!isfinite(bdata->distsq) && bdata->verbose>0) {
1204 printf("INF in calc_with_xnew(): k=%d bdata->distsq=%.10E\n",
1205 k, bdata->distsq);
1206 }
1207 d1=bdata->distsq/bdata->delsq; temp=fmax(1.0, d1*d1);
1208 if(temp*den > bdata->scaden) {
1209 bdata->scaden=temp*den; bdata->knew=k+1; bdata->denom=den;}
1210 bdata->biglsq=fmax(bdata->biglsq, bdata->vlag[k]*bdata->vlag[k]*temp);
1211 }
1212 if(bdata->scaden <= 0.5*bdata->biglsq) {
1213 bdata->knew=ksav; bdata->denom=densav;}
1214 }
1215 }
1216
1217 /* Update BMAT and ZMAT, so that the KNEW-th interpolation point can be
1218 moved. Also update the second derivative terms of the model. */
1219 bobyqa_update(bdata);
1220 pqold=bdata->pq[bdata->knew-1]; bdata->pq[bdata->knew-1]=0.0;
1221 for(i=ih=0; i<bdata->n; i++) {
1222 temp=pqold*bdata->xpt[bdata->knew-1 + i * bdata->npt];
1223 for(j=0; j<=i; j++, ih++)
1224 bdata->hq[ih]+=temp*bdata->xpt[bdata->knew-1 + j*bdata->npt];
1225 }
1226 for(j=0; j<bdata->nptm; j++) {
1227 temp=diff*bdata->zmat[bdata->knew-1+j*bdata->npt];
1228 for(k=0; k<bdata->npt; k++) bdata->pq[k]+=temp*bdata->zmat[k+j*bdata->npt];
1229 }
1230
1231 /* Include the new interpolation point, and make the changes to GOPT at
1232 the old XOPT that are caused by the updating of the quadratic model. */
1233 bdata->fval[bdata->knew-1]=bdata->newf;
1234 for(i=0; i<bdata->n; i++) {
1235 bdata->xpt[bdata->knew-1 + i*bdata->npt]=bdata->xnew[i];
1236 bdata->wn[i]=bdata->bmat[bdata->knew-1 + i*bdata->ndim];
1237 }
1238
1239 for(k=0; k<bdata->npt; k++) {
1240 for(j=0, suma=0.0; j<bdata->nptm; j++) {
1241#if(1) // modified by VO
1242 double v;
1243 v=bdata->zmat[bdata->knew-1 + j*bdata->npt]*bdata->zmat[k + j*bdata->npt];
1244 if(isfinite(v)) suma+=v;
1245 else if(bdata->verbose>0) {
1246 printf("INF in calc_with_xnew(v): k=%d j=%d a=%E b=%E\n",
1247 k, j, bdata->zmat[bdata->knew-1 + j*bdata->npt],
1248 bdata->zmat[k + j*bdata->npt]);
1249 }
1250#else // original
1251 suma+=bdata->zmat[bdata->knew-1 + j*bdata->npt] *
1252 bdata->zmat[k + j*bdata->npt];
1253#endif
1254 if(!isfinite(suma) && bdata->verbose>0) {
1255 printf("INF in calc_with_xnew(suma): k=%d j=%d a=%E b=%E\n", k, j,
1256 bdata->zmat[bdata->knew-1+j*bdata->npt], bdata->zmat[k+j*bdata->npt]);
1257 }
1258 }
1259 /* Detect singularity here (happens if too many iterations) */
1260 if(!isfinite(suma)) {
1261 if(bdata->verbose>0) printf("INF in calc_with_xnew: suma\n");
1262 if(bdata->verbose>3) printf("BOBYQA_ROUNDOFF_LIMITED 4\n");
1263 bdata->rc = BOBYQA_ROUNDOFF_LIMITED;
1264 bobyqb_xupdate(bdata);
1265 return bdata->rc;
1266 }
1267 for(j=0, sumb=0.0; j<bdata->n; j++)
1268 sumb+=bdata->xpt[k+j*bdata->npt]*bdata->xopt[j];
1269 temp=suma*sumb;
1270 for(j=0; j<bdata->n; j++)
1271 bdata->wn[j]+=temp*bdata->xpt[k+j*bdata->npt];
1272 }
1273 for(i=0; i<bdata->n; i++) bdata->gopt[i]+=diff*bdata->wn[i];
1274
1275 /* Update XOPT, GOPT and bdata->kopt if the new calculated F is less than FOPT */
1276 if(!isfinite(bdata->fopt) || !isfinite(bdata->newf)) { // Added by VO 2012-05-24
1277 if(bdata->verbose>3) printf("BOBYQA_ROUNDOFF_LIMITED N\n");
1278 bdata->rc = BOBYQA_ROUNDOFF_LIMITED;
1279 bobyqb_xupdate(bdata);
1280 return bdata->rc;
1281 }
1282 if(bdata->newf < bdata->fopt) {
1283 bdata->kopt=bdata->knew; bdata->xoptsq=0.0;
1284 for(j=0, ih=0; j<bdata->n; j++) {
1285 bdata->xopt[j]=bdata->xnew[j];
1286 bdata->xoptsq += bdata->xopt[j]*bdata->xopt[j];
1287 for(i=0; i<=j; i++, ih++) {
1288 if(i<j) bdata->gopt[j]+=bdata->hq[ih]*bdata->dtrial[i];
1289 bdata->gopt[i]+=bdata->hq[ih]*bdata->dtrial[j];
1290 }
1291 }
1292 for(k=0; k<bdata->npt; k++) {
1293 for(j=0, temp=0.0; j<bdata->n; j++)
1294 temp+=bdata->xpt[k+j*bdata->npt]*bdata->dtrial[j];
1295 temp*=bdata->pq[k];
1296 for(i=0; i<bdata->n; i++) bdata->gopt[i]+=temp*bdata->xpt[k+i*bdata->npt];
1297 }
1298 /* Check against stopping criteria */
1299 if(1) { // isfinite(bdata->fopt) && isfinite(bdata->newf)) {
1300 /* decrease in absolute function value */
1301 if(fabs(bdata->fopt-bdata->newf) < bdata->ftol_abs) {
1302 if(bdata->verbose>10)
1303 printf("fopt=%.15E newf=%.15E ftol_abs=%.15E\n", bdata->fopt,
1304 bdata->newf, bdata->ftol_abs);
1305 if(bdata->verbose>3) printf("BOBYQA_ABSFTOL_REACHED 2a\n");
1306 bdata->rc = BOBYQA_ABSFTOL_REACHED;
1307 bobyqb_xupdate(bdata);
1308 return bdata->rc;
1309 }
1310 /* decrease in relative function value */
1311 if(fabs(bdata->fopt-bdata->newf) <
1312 bdata->ftol_rel*0.5*(fabs(bdata->newf)+fabs(bdata->fopt)) ) {
1313 if(bdata->verbose>3) printf("BOBYQA_RELFTOL_REACHED 2b\n");
1314 bdata->rc = BOBYQA_RELFTOL_REACHED;
1315 bobyqb_xupdate(bdata);
1316 return bdata->rc;
1317 }
1318 /* catch situation where both new and old function values equal zero */
1319 if(bdata->ftol_rel>0 && bdata->newf==bdata->fopt) {
1320 if(bdata->verbose>3) printf("BOBYQA_FTOL_REACHED 2c\n");
1321 bdata->rc = BOBYQA_FTOL_REACHED;
1322 bobyqb_xupdate(bdata);
1323 return bdata->rc;
1324 }
1325 }
1326 }
1327
1328
1329 if(bdata->ntrits<=0) return bdata->rc;
1330 /* Calculate the parameters of the least Frobenius norm interpolant to
1331 the current data, the gradient of this interpolant at XOPT being put
1332 into VLAG(NPT+I), I=1,2,...,N. */
1333 nh=bdata->n*(bdata->n+1)/2;
1334 for(k=0; k<bdata->npt; k++) {
1335 bdata->vlag[k]=bdata->fval[k]-bdata->fval[bdata->kopt-1];
1336 bdata->w2npt[k]=0.0;
1337 }
1338 for(j=0; j<bdata->nptm; j++) {
1339 for(k=0, sum=0.0; k<bdata->npt; k++)
1340 sum+=bdata->zmat[k+j*bdata->npt]*bdata->vlag[k];
1341 for(k=0; k<bdata->npt; k++)
1342 bdata->w2npt[k]+=sum*bdata->zmat[k+j*bdata->npt];
1343 }
1344 for(k=0; k<bdata->npt; k++) {
1345 for(j=0, sum=0.0; j<bdata->n; j++)
1346 sum+=bdata->xpt[k+j*bdata->npt]*bdata->xopt[j];
1347 bdata->w2npt[k+bdata->npt]=bdata->w2npt[k];
1348 bdata->w2npt[k]*=sum;
1349 }
1350 gqsq=gisq=0.0;
1351 for(i=0; i<bdata->n; i++) {
1352 for(k=0, sum=0.0; k<bdata->npt; k++)
1353 sum+=bdata->bmat[k+i*bdata->ndim]*bdata->vlag[k] +
1354 bdata->xpt[k+i*bdata->npt]*bdata->w2npt[k];
1355 if(bdata->xopt[i]==bdata->sl[i]) {
1356 d1=fmin(0.0, bdata->gopt[i]); gqsq+=d1*d1;
1357 d1=fmin(0.0, sum); gisq+=d1*d1;
1358 } else if(bdata->xopt[i]==bdata->su[i]) {
1359 d1=fmax(0.0, bdata->gopt[i]); gqsq+=d1*d1;
1360 d1=fmax(0.0, sum); gisq+=d1*d1;
1361 } else {
1362 d1=bdata->gopt[i]; gqsq+=d1*d1; gisq+=sum*sum;
1363 }
1364 bdata->vlag[bdata->npt+i]=sum;
1365 }
1366
1367 /* Test whether to replace the new quadratic model by the least Frobenius
1368 norm interpolant, making the replacement if the test is satisfied. */
1369 bdata->itest++; if(gqsq<10.0*gisq) bdata->itest=0;
1370 if(bdata->itest>=3) {
1371 for(i=0; i<bdata->npt || i<nh; i++) {
1372 if(i<bdata->n) bdata->gopt[i]=bdata->vlag[bdata->npt+i];
1373 if(i<bdata->npt) bdata->pq[i]=bdata->w2npt[bdata->npt+i];
1374 if(i<nh) bdata->hq[i]=0.0;
1375 bdata->itest=0;
1376 }
1377 }
1378
1379 return bdata->rc;
1380}
1381/******************************************************************************/
1384{
1385 if(bdata->verbose>5) printf("bobyqb_next_rho_delta()\n");
1386 bdata->delta=0.5*bdata->rho;
1387 bdata->ratio = bdata->rho / bdata->rhoend;
1388 if(bdata->ratio <= 16.) {
1389 bdata->rho = bdata->rhoend;
1390 } else if(bdata->ratio <= 250.) {
1391 bdata->rho = sqrt(bdata->ratio) * bdata->rhoend;
1392 } else {
1393 bdata->rho *= 0.1;
1394 }
1395 bdata->delta = fmax(bdata->delta, bdata->rho);
1396 bdata->ntrits=0; bdata->nfsav=bdata->nevals;
1397}
1398/******************************************************************************/
1403{
1404 int i, rc=0;
1405
1406 if(bdata->verbose>5) {printf("bobyqb_do_rescue()\n"); fflush(stdout);}
1407 /* XBASE is also moved to XOPT by a call of RESCUE. This calculation is
1408 more expensive than the previous shift, because new matrices BMAT and
1409 ZMAT are generated from scratch, which may include the replacement of
1410 interpolation points whose positions seem to be causing near linear
1411 dependence in the interpolation conditions. Therefore RESCUE is called
1412 only if rounding errors have reduced by at least a factor of two the
1413 denominator of the formula for updating the H matrix. It provides a
1414 useful safeguard, but is not invoked in most applications of BOBYQA. */
1415 bdata->nfsav = bdata->nevals;
1416 bdata->kbase = bdata->kopt;
1417 rc = bobyqa_rescue(bdata);
1418
1419 /* XOPT is updated now in case the branch below to label 720 is taken.
1420 Any updating of GOPT occurs after the branch below to label 20, which
1421 leads to a trust region iteration as does the branch to label 60. */
1422 bdata->xoptsq=0.0;
1423 if(bdata->kopt!=bdata->kbase) {
1424 for(i=0; i<bdata->n; i++) {
1425 bdata->xopt[i]=bdata->xpt[bdata->kopt-1 + i*bdata->npt];
1426 bdata->xoptsq+=bdata->xopt[i]*bdata->xopt[i];
1427 }
1428 }
1429 if(rc != BOBYQA_SUCCESS) {
1430 bdata->rc = rc;
1431 if(bdata->verbose>3) printf("rescue() not successful\n");
1432 bobyqb_xupdate(bdata);
1433 return bdata->rc;
1434 }
1435 bdata->nresc = bdata->nevals;
1436 if(bdata->nfsav < bdata->nevals) {
1437 bdata->nfsav = bdata->nevals;
1438 /* Update GOPT if necessary after each call of RESCUE that makes a call of
1439 objf. */
1440 if(bdata->kopt != bdata->kbase) bobyqb_update_gopt(bdata);
1441 }
1442 return BOBYQA_SUCCESS;
1443}
1444/******************************************************************************/
1450{
1451 int i, j, k, rescue;
1452 double d1, den, hdiag, temp;
1453
1454 if(bdata->verbose>5) {printf("bobyqb_part()\n"); fflush(stdout);}
1455 do {
1456 rescue=0;
1457
1458 /* Calculate VLAG and BETA for the current choice of D. The scalar
1459 product of D with XPT(K,.) is going to be held in W(NPT+K) for
1460 use when VQUAD is calculated. */
1462
1463 /* If NTRITS is zero, the denominator may be increased by replacing
1464 the step D of ALTMOV by a Cauchy step. Then RESCUE may be called if
1465 rounding errors have damaged the chosen denominator. */
1466 if(bdata->ntrits == 0) {
1467 d1=bdata->vlag[bdata->knew-1];
1468 bdata->denom = d1*d1 + bdata->alpha * bdata->beta;
1469 // VO: tried this, did not seem to make any better
1470 // while(bdata->denom<0.999999999*bdata->cauchy&&bdata->cauchy>1.0E-10) {
1471 while(bdata->denom < bdata->cauchy && bdata->cauchy > 0.0) {
1472 for(i=0; i<bdata->n; i++) {
1473 bdata->xnew[i]=bdata->xalt[i];
1474 bdata->dtrial[i]=bdata->xnew[i]-bdata->xopt[i];
1475 }
1476 bdata->cauchy=0.0;
1478 d1=bdata->vlag[bdata->knew-1];
1479 bdata->denom = d1*d1 + bdata->alpha * bdata->beta;
1480 }
1481 d1 = bdata->vlag[bdata->knew-1];
1482 // For testing, you can request rescue() here. DO NOT LEAVE IT HERE!!!!
1483 //if(bdata->rescue_nr<1 && bdata->stop->nevals>400) rescue=1; else
1484 if(bdata->denom <= 0.5*d1*d1) {
1485 // in practise this happens only if either alpha or beta is negative
1486 if(bdata->verbose>4)
1487 printf("1: denom=%g vs 0.5*vlag*vlag=%g\n", bdata->denom, 0.5*d1*d1);
1488 //printf("denom=%g d1^2=%g\n", bdata->denom, d1*d1);
1489 if(bdata->verbose>0)
1490 printf("too much cancellation 1; nevals=%d nresc=%d\n",
1491 bdata->nevals, bdata->nresc);
1492 if(bdata->nevals > bdata->nresc) {
1493 rescue=1; //goto L190;
1494 } else {
1495 /* Return from BOBYQA because of much cancellation in a denominator */
1496 bdata->rc = BOBYQA_ROUNDOFF_LIMITED; // do not change this value
1497 // unless you change the following test too
1498 if(bdata->verbose>3) printf("BOBYQA_ROUNDOFF_LIMITED 1\n");
1499 bobyqb_xupdate(bdata);
1500 //return bdata->rc;
1501 }
1502 }
1503
1504 } else {
1505
1506 /* Alternatively, if NTRITS is positive, then set KNEW to the index of
1507 the next interpolation point to be deleted to make room for a trust
1508 region step. Again RESCUE may be called if rounding errors have damaged
1509 the chosen denominator, which is the reason for attempting to select
1510 KNEW before calculating the next value of the objective function. */
1511 bdata->delsq = bdata->delta * bdata->delta;
1512 bdata->scaden = bdata->biglsq =0.0; bdata->knew=0;
1513 for(k=0; k<bdata->npt; k++) {
1514 if(k==bdata->kopt-1) continue;
1515 for(j=0, hdiag=0.0; j<bdata->nptm; j++)
1516 hdiag += bdata->zmat[k+j*bdata->npt]*bdata->zmat[k+j*bdata->npt];
1517 den= bdata->beta*hdiag + bdata->vlag[k]*bdata->vlag[k];
1518 for(j=0, bdata->distsq=0.0; j<bdata->n; j++) {
1519 d1=bdata->xpt[k+j*bdata->npt]-bdata->xopt[j];
1520 bdata->distsq += d1*d1;
1521 }
1522 d1=bdata->distsq/bdata->delsq; temp=fmax(1.0, d1*d1);
1523 if(temp*den > bdata->scaden) {
1524 bdata->scaden = temp*den; bdata->knew=k+1; bdata->denom=den;}
1525 bdata->biglsq=fmax(bdata->biglsq, (bdata->vlag[k]*bdata->vlag[k])*temp);
1526 }
1527 //printf("2:scaden=%g vs 0.5*biglsq=%g\n",bdata->scaden,0.5*bdata->biglsq);
1528 if(bdata->scaden <= 0.5*bdata->biglsq) {
1529 if(bdata->verbose>0)
1530 printf("too much cancellation 2; nevals=%d nresc=%d\n",
1531 bdata->nevals, bdata->nresc);
1532 if(bdata->nevals > bdata->nresc) {
1533 rescue=1;
1534 } else {
1535 /* Return from BOBYQA because of much cancellation in denominator. */
1536 if(bdata->verbose>3) printf("BOBYQA_ROUNDOFF_LIMITED 2\n");
1537 if(bdata->verbose>4)
1538 printf("scaden=%.15E 0.5*biglsq=%.15E\n",
1539 bdata->scaden, 0.5*bdata->biglsq);
1540 bdata->rc = BOBYQA_ROUNDOFF_LIMITED;
1541 bobyqb_xupdate(bdata);
1542 //return bdata->rc;
1543 }
1544 }
1545 }
1546 if(bdata->rc == BOBYQA_ROUNDOFF_LIMITED) return -1;
1547 if(rescue==1) {
1548 if(bobyqb_do_rescue(bdata)!=BOBYQA_SUCCESS) return -1; //bdata->rc;
1549 if(bdata->nfsav < bdata->nevals || bdata->ntrits>0) {
1550 return 1;
1551 }
1552
1553 /* Pick two alternative vectors of variables, relative to XBASE, that
1554 are suitable as new positions of the KNEW-th interpolation point.
1555 Firstly, XNEW is set to the point on a line through XOPT and another
1556 interpolation point that minimizes the predicted value of the next
1557 denominator, subject to ||XNEW - XOPT|| .LEQ. ADELT and to the SL
1558 and SU bounds. Secondly, XALT is set to the best feasible point on
1559 a constrained version of the Cauchy step of the KNEW-th Lagrange
1560 function, the corresponding value of the square of this function
1561 being returned in CAUCHY. The choice between these alternatives is
1562 oing to be made when the denominator is calculated. */
1563 bobyqa_altmov(bdata);
1564 for(i=0; i<bdata->n; i++) bdata->dtrial[i]=bdata->xnew[i]-bdata->xopt[i];
1565 }
1566 } while(rescue!=0);
1567
1568 return 0;
1569}
1570/******************************************************************************/
1576{
1577 int j, k;
1578 double sum, d;
1579
1580 if(bdata->verbose>5) {printf("ip_dist()\n"); fflush(stdout);}
1581 for(k=0, bdata->knew=0; k<bdata->npt; k++) {
1582 for(j=0, sum=0.0; j<bdata->n; j++) {
1583 d=bdata->xpt[k+j*bdata->npt] - bdata->xopt[j];
1584 sum+=d*d;
1585 }
1586 if(sum > bdata->distsq) {bdata->knew=k+1; bdata->distsq=sum;}
1587 }
1588 if(bdata->knew==0) return 0; else return 1;
1589}
1590/******************************************************************************/
1594{
1595 int i;
1596 double d, dist;
1597
1598 if(bdata->verbose>5) {printf("ip_alternative()\n"); fflush(stdout);}
1599 dist = sqrt(bdata->distsq);
1600 if(bdata->ntrits == -1) {
1601 bdata->delta=fmin(0.1*bdata->delta, 0.5*dist);
1602 if(bdata->delta <= 1.5*bdata->rho) bdata->delta=bdata->rho;
1603 }
1604 bdata->ntrits=0;
1605 d=fmin(0.1*dist, bdata->delta);
1606 bdata->adelt = fmax(d, bdata->rho);
1607 bdata->dsq= bdata->adelt * bdata->adelt;
1608 /* Severe cancellation is likely to occur if XOPT is too far from XBASE. */
1609 /* If the following test holds, then XBASE is shifted so that XOPT becomes */
1610 /* zero. The appropriate changes are made to BMAT and to the second */
1611 /* derivatives of the current model, beginning with the changes to BMAT */
1612 /* that do not depend on ZMAT. VLAG is used temporarily for working space. */
1613 if(bdata->dsq <= bdata->xoptsq*0.001) bobyqb_shift_xbase(bdata);
1614
1615 bobyqa_altmov(bdata);
1616 for(i=0; i<bdata->n; i++) bdata->dtrial[i]=bdata->xnew[i]-bdata->xopt[i];
1617}
1618/******************************************************************************/
1624 bobyqa_data *bdata
1625) {
1626 if(bdata->verbose>2) {printf("bobyqb()\n"); fflush(stdout);}
1627
1628 int i, j, k;
1629 double curv;
1630 double bdtol;
1631 double errbig;
1632 double bdtest;
1633 double frhosq;
1634 bobyqa_result rc2;
1635 double d1;
1636
1637
1638 /* The call of PRELIM sets the elements of XBASE, XPT, FVAL, GOPT, HQ, PQ,
1639 BMAT and ZMAT for the first iteration, with the corresponding values of
1640 of NF and KOPT, which are the number of calls of objf() so far and the
1641 index of the interpolation point at the trust region centre. Then the
1642 initial XOPT is set too. The branch to label 720 occurs if MAXFUN is
1643 less than NPT. GOPT will be updated if KOPT is different from KBASE. */
1644 rc2 = bobyqa_prelim(bdata);
1645
1646 for(i=0, bdata->xoptsq=0.0; i<bdata->n; i++) {
1647 bdata->xopt[i] = bdata->xpt[bdata->kopt-1 +i*bdata->npt];
1648 bdata->xoptsq+=bdata->xopt[i]*bdata->xopt[i];
1649 }
1650 bdata->fsave = bdata->fval[0];
1651 if (rc2 != BOBYQA_SUCCESS) {
1652 bdata->rc = rc2;
1653 if(bdata->verbose>3) printf("prelim() was not successful\n");
1654 bobyqb_xupdate(bdata);
1655 return bdata->rc;
1656 }
1657 bdata->kbase = 1;
1658
1659 /* Complete the settings that are required for the iterative procedure. */
1660 bdata->rho=bdata->rhobeg;
1661 bdata->delta= bdata->rho;
1662 bdata->nresc= bdata->nevals;
1663 bdata->ntrits= 0;
1664 bdata->diffa=bdata->diffb=bdata->diffc= 0.0;
1665 bdata->ratio =0.0; //=1.0;
1666 bdata->itest= 0;
1667 bdata->nfsav= bdata->nevals;
1668
1669 /* Update GOPT if necessary before the first iteration and after each
1670 call of RESCUE that makes a call of objf(). */
1671 if (bdata->kopt != bdata->kbase) bobyqb_update_gopt(bdata);
1672
1673 do { // start main loop
1674 /* Generate the next point in the trust region that provides a small value
1675 of the quadratic model subject to the constraints on the variables.
1676 The int NTRITS is set to the number "trust region" iterations that
1677 have occurred since the last "alternative" iteration. If the length
1678 of XNEW-XOPT is less than 0.5*RHO, however, then there is a branch to
1679 label 650 or 680 with NTRITS=-1, instead of calculating F at XNEW. */
1680 bobyqa_trsbox(bdata);
1681 bdata->dnorm = fmin(bdata->delta, sqrt(bdata->dsq));
1682
1683#if(0) // original
1684 if(bdata->dnorm < 0.5 * bdata->rho) {
1685#else
1686 if(bdata->dnorm>0.0 && bdata->dnorm < 0.5 * bdata->rho) {
1687#endif
1688 if(bdata->verbose>10) {
1689 printf("ntrits set to -1; A\n");
1690 printf("bdata->dnorm=%.15E 0.5*bdata->rho=%.15E\n",
1691 bdata->dnorm, 0.5*bdata->rho);
1692 printf("delta=%.15E dsq=%.15E\n", bdata->delta, bdata->dsq);
1693 }
1694 bdata->ntrits = -1;
1695 d1=10.0*bdata->rho; bdata->distsq = d1*d1;
1696 if(bdata->nevals <= bdata->nfsav + 2) {
1697 if(bdata->verbose>10) {
1698 printf("nevals<=nfsav+2 (nevals=%d nfsav=%d)\n",
1699 bdata->nevals, bdata->nfsav);
1700 }
1701 } else {
1702
1703 /* The following choice between labels 650 and 680 depends on whether or
1704 not our work with the current RHO seems to be complete. Either RHO is
1705 decreased or termination occurs if the errors in the quadratic model
1706 at the last three interpolation points compare favourably with
1707 predictions of likely improvements to the model within distance
1708 0.5*RHO of XOPT. */
1709 d1 = fmax(bdata->diffa, bdata->diffb); errbig = fmax(d1, bdata->diffc);
1710 frhosq = bdata->rho * .125 * bdata->rho;
1711 if(bdata->_crvmin<=0.0 || errbig <= frhosq*bdata->_crvmin) {
1712 bdtest=bdtol= errbig/bdata->rho;
1713
1714 for(j=0; j<bdata->n; j++) {
1715 bdtest=bdtol;
1716 if(bdata->xnew[j]==bdata->sl[j]) bdtest=bdata->gnew[j];
1717 if(bdata->xnew[j]==bdata->su[j]) bdtest=-bdata->gnew[j];
1718 if(bdtest<bdtol) {
1719 curv=bdata->hq[(j+1 + (j+1)*(j+1))/2 - 1];
1720 for(k=0; k<bdata->npt; k++) {
1721 d1=bdata->xpt[k+j*bdata->npt]; curv+=bdata->pq[k]*(d1*d1);
1722 }
1723 bdtest += 0.5*curv*bdata->rho;
1724 if(bdtest < bdtol) break;
1725 }
1726 }
1727 if(bdtest>=bdtol) {
1728 /* The calculations with the current value of RHO are complete.
1729 Pick the next values of RHO and DELTA. */
1730 if (bdata->rho > bdata->rhoend) {
1731 bobyqb_next_rho_delta(bdata);
1732 continue;
1733 }
1734
1735 /* Return from the calculation, after another Newton-Raphson step,
1736 if it is too short to have been tried before. */
1737 if(bdata->ntrits != -1) {
1738 bobyqb_xupdate(bdata);
1739 return bdata->rc;
1740 }
1741 bdata->rc=bobyqb_calc_with_xnew(bdata);
1742 if(bdata->rc!=BOBYQA_SUCCESS) return bdata->rc;
1743 /* If a trust region step has provided a sufficient decrease in F,
1744 then branch for another trust region calculation.
1745 The case NTRITS=0 occurs when the new interpolation point was
1746 reached by an alternative step. */
1747 if (bdata->ntrits==0 || bdata->newf<=bdata->fopt+0.1*bdata->vquad) {
1748 continue;
1749 }
1750
1751 /* Alternatively, find out if the interpolation points are close
1752 enough to the best point so far. */
1753 d1=fmax(2.0*bdata->delta, 10.0*bdata->rho);
1754 bdata->distsq=d1*d1;
1755 }
1756 }
1757 }
1758
1759 } else {
1760
1761 bdata->ntrits++;
1762
1763 /* Severe cancellation is likely to occur if XOPT is too far from XBASE.
1764 If the following test holds, then XBASE is shifted so that XOPT becomes
1765 zero. The appropriate changes are made to BMAT and to the second
1766 derivatives of the current model, beginning with the changes to BMAT
1767 that do not depend on ZMAT.
1768 VLAG is used temporarily for working space */
1769 if(bdata->dsq <= bdata->xoptsq * .001) bobyqb_shift_xbase(bdata);
1770
1771 if (bdata->ntrits == 0) {
1772 bobyqa_altmov(bdata);
1773 for(i=0; i<bdata->n; i++) bdata->dtrial[i]=bdata->xnew[i]-bdata->xopt[i];
1774 }
1775
1776 i=bobyqb_part(bdata);
1777 if(i==-1) return bdata->rc;
1778 if(i==1) continue;
1779
1780 bdata->rc=bobyqb_calc_with_xnew(bdata);
1781 if(bdata->rc!=BOBYQA_SUCCESS) return bdata->rc;
1782
1783 /* If a trust region step has provided a sufficient decrease in F, then
1784 branch for another trust region calculation. The case NTRITS=0 occurs
1785 when the new interpolation point was reached by an alternative step. */
1786 if (bdata->ntrits==0 || bdata->newf <= bdata->fopt+0.1*bdata->vquad) {
1787 continue;
1788 }
1789
1790 /* Alternatively, find out if the interpolation points are close enough
1791 to the best point so far. */
1792 d1=fmax(2.0*bdata->delta, 10.0*bdata->rho);
1793 bdata->distsq=d1*d1;
1794
1795 }
1796 while(1) {
1797 /* Check if interpolation points are close enough, and update distsq
1798 if necessary */
1799 i=bobyqb_ip_dist(bdata);
1800
1801 /* If not close enough (KNEW is positive),
1802 then ALTMOV finds alternative new positions for
1803 the KNEW-th interpolation point within distance ADELT of XOPT. */
1804 if(i!=0) { // Tästä iffistä ei jatketa alle
1805 /* Find alternative new positions for the KNEWth interpolation point
1806 within distance ADELT of XOPT. */
1807 bobyqb_ip_alternative(bdata);
1808 i=bobyqb_part(bdata);
1809 if(i==-1) return bdata->rc;
1810 if(i==1) break;
1811
1812 bdata->rc=bobyqb_calc_with_xnew(bdata);
1813 if(bdata->rc!=BOBYQA_SUCCESS) return bdata->rc;
1814
1815 /* If a trust region step has provided a sufficient decrease in F, then
1816 branch for another trust region calculation. The case NTRITS=0 occurs
1817 when the new interpolation point was reached by an alternative step. */
1818 if (bdata->ntrits == 0 || bdata->newf <= bdata->fopt + 0.1*bdata->vquad) {
1819 break;
1820 }
1821
1822 /* Alternatively, find out if the interpolation points are close enough
1823 to the best point so far. */
1824 d1=fmax(2.0*bdata->delta, 10.0*bdata->rho);
1825 bdata->distsq=d1*d1;
1826
1827 continue;
1828 }
1829 /* Another trust region iteration, unless the calculations with the
1830 current RHO are complete. */
1831 if(bdata->ntrits != -1) {
1832 if(bdata->ratio>0.0 || fmax(bdata->delta, bdata->dnorm) > bdata->rho) {
1833 break;
1834 }
1835 }
1836
1837 /* The calculations with the current value of RHO are complete. Pick the
1838 next values of RHO and DELTA. */
1839 if (bdata->rho > bdata->rhoend) {
1840 bobyqb_next_rho_delta(bdata);
1841 break;
1842 }
1843
1844 /* Return from the calculation, after another Newton-Raphson step, if
1845 it is too short to have been tried before */
1846 if (bdata->ntrits == -1) {
1847 bdata->rc=bobyqb_calc_with_xnew(bdata);
1848 if(bdata->rc!=BOBYQA_SUCCESS) return bdata->rc;
1849 /* If a trust region step has provided a sufficient decrease in F, then
1850 branch for another trust region calculation. The case NTRITS=0 occurs
1851 when the new interpolation point was reached by an alternative step. */
1852 if (bdata->ntrits == 0 || bdata->newf <= bdata->fopt+0.1*bdata->vquad) {
1853 break;
1854 }
1855 /* Alternatively, find out if the interpolation points are close enough
1856 to the best point so far. */
1857 d1=fmax(2.0*bdata->delta, 10.0*bdata->rho);
1858 bdata->distsq=d1*d1;
1859
1860 continue;
1861 } else {
1862 bobyqb_xupdate(bdata);
1863 return bdata->rc;
1864 }
1865 }
1866 } while(1);
1867 // actually we should never reach this point
1868 return bdata->rc;
1869} /* bobyqb() */
1870/*****************************************************************************/
1871
1872/*****************************************************************************/
1873// ALTMOV
1876 bobyqa_data *bdata
1877) {
1878 bdata->altmov_nr++;
1879 if(bdata->verbose>3) {printf("bobyqa_altmov()\n"); fflush(stdout);}
1880
1881 double d1, d2;
1882 int i, j, k;
1883 double ha, gw, diff;
1884 int ilbd, isbd;
1885 double slbd;
1886 int iubd;
1887 double vlag, subd, temp;
1888 int ksav;
1889 double step=0.0, curv;
1890 int iflag;
1891 double scale, csave=0.0, tempa, tempb, tempd, sumin, ggfree;
1892 int ibdsav=0;
1893 double dderiv, bigstp, predsq, presav, distsq, stpsav=0.0, wfixsq, wsqsav=0.0;
1894
1895
1896 /* Set the first NPT components of CCSTEP to the leading elements of the
1897 KNEW-th column of the H matrix. */
1898 for(k=0; k<bdata->npt; k++) bdata->hcol[k]=0.0;
1899 for(j=0; j<bdata->npt-bdata->n-1; j++) {
1900 temp = bdata->zmat[(bdata->knew-1) + j*bdata->npt];
1901 for(k=0; k<bdata->npt; k++)
1902 bdata->hcol[k] += temp * bdata->zmat[k + j*bdata->npt];
1903 }
1904 bdata->alpha = bdata->hcol[bdata->knew-1];
1905 ha = 0.5*bdata->alpha;
1906
1907 /* Calculate the gradient of the KNEW-th Lagrange function at XOPT. */
1908 for(i=0; i<bdata->n; i++)
1909 bdata->glag[i]=bdata->bmat[bdata->knew-1 + i*bdata->ndim];
1910 for(k=0; k<bdata->npt; k++) {
1911 temp=0.0;
1912 for(j=0; j<bdata->n; j++) temp+=bdata->xpt[k + j*bdata->npt]*bdata->xopt[j];
1913 temp*=bdata->hcol[k];
1914 for(i=0; i<bdata->n; i++) bdata->glag[i]+=temp*bdata->xpt[k+i*bdata->npt];
1915 }
1916
1917 /* Search for a large denominator along the straight lines through XOPT
1918 and another interpolation point. SLBD and SUBD will be lower and upper
1919 bounds on the step along each of these lines in turn. PREDSQ will be
1920 set to the square of the predicted denominator for each line. PRESAV
1921 will be set to the largest admissible value of PREDSQ that occurs. */
1922 presav=0.0;
1923 for(k=ksav=0; k<bdata->npt; k++) {
1924 if(k==bdata->kopt-1) continue;
1925 dderiv=distsq=0.0;
1926 for(i=0; i<bdata->n; i++) {
1927 temp = bdata->xpt[k + i*bdata->npt] - bdata->xopt[i];
1928 dderiv += bdata->glag[i]*temp;
1929 distsq += temp*temp;
1930 }
1931 subd = bdata->adelt / sqrt(distsq);
1932 slbd=-subd; ilbd=iubd=0;
1933 sumin = fmin(1.0, subd);
1934
1935 /* Revise SLBD and SUBD if necessary because of the bounds in SL and SU. */
1936 for(i=0; i<bdata->n; i++) {
1937 temp = bdata->xpt[k + i*bdata->npt] - bdata->xopt[i];
1938 if(temp>0.0) {
1939 if(slbd*temp < bdata->sl[i]-bdata->xopt[i]) {
1940 slbd = (bdata->sl[i] - bdata->xopt[i]) / temp;
1941 ilbd = -i;
1942 }
1943 if(subd*temp > bdata->su[i] - bdata->xopt[i]) {
1944 subd = fmax(sumin, (bdata->su[i] - bdata->xopt[i]) / temp);
1945 iubd = i;
1946 }
1947 } else if(temp<0.0) {
1948 if(slbd*temp > bdata->su[i] - bdata->xopt[i]) {
1949 slbd = (bdata->su[i] - bdata->xopt[i]) / temp;
1950 ilbd = i;
1951 }
1952 if(subd*temp < bdata->sl[i] - bdata->xopt[i]) {
1953 subd = fmax(sumin, (bdata->sl[i] - bdata->xopt[i]) / temp);
1954 iubd = -i;
1955 }
1956 }
1957 }
1958
1959 /* Seek a large modulus of the KNEW-th Lagrange function when the index
1960 of the other interpolation point on the line through XOPT is KNEW. */
1961 if(k==bdata->knew-1) {
1962 diff = dderiv - 1.0;
1963 step = slbd; vlag = slbd * (dderiv - slbd * diff);
1964 isbd = ilbd; temp = subd * (dderiv - subd * diff);
1965 if(fabs(temp) > fabs(vlag)) {
1966 step = subd; vlag = temp; isbd = iubd;
1967 }
1968 tempd = 0.5 * dderiv;
1969 tempa = tempd - diff * slbd;
1970 tempb = tempd - diff * subd;
1971 if(tempa*tempb < 0.0) {
1972 temp = tempd*tempd/diff;
1973 if(fabs(temp) > fabs(vlag)) {step=tempd/diff; vlag=temp; isbd=0;}
1974 }
1975
1976 } else {
1977 /* Search along each of the other lines through XOPT and another point. */
1978 step = slbd; vlag = slbd * (1.0 - slbd);
1979 isbd = ilbd; temp = subd * (1.0 - subd);
1980 if(fabs(temp) > fabs(vlag)) {step=subd; vlag=temp; isbd=iubd;}
1981 if(subd>0.5 && fabs(vlag)<0.25) {step=0.5; vlag=0.25; isbd=0;}
1982 vlag*=dderiv;
1983 }
1984
1985 /* Calculate PREDSQ for the current line search and maintain PRESAV. */
1986 temp = step*(1.0-step)*distsq;
1987 predsq = vlag*vlag*(vlag*vlag + ha*temp*temp);
1988 if(predsq>presav) {presav=predsq; ksav=k; stpsav=step; ibdsav=isbd;}
1989 }
1990
1991 /* Construct XNEW in a way that satisfies the bound constraints exactly. */
1992 for(i=0; i<bdata->n; i++) {
1993 temp=bdata->xopt[i]+stpsav*(bdata->xpt[ksav+i*bdata->npt]-bdata->xopt[i]);
1994 d2=fmin(bdata->su[i],temp);
1995 bdata->xnew[i] = fmax(bdata->sl[i],d2);
1996 }
1997 if(ibdsav<0) bdata->xnew[-ibdsav]=bdata->sl[-ibdsav];
1998 if(ibdsav>0) bdata->xnew[ibdsav]=bdata->su[ibdsav];
1999
2000
2001 /* Prepare for the iterative method that assembles the constrained Cauchy
2002 step in CCSTEP. The sum of squares of the fixed components of CCSTEP is
2003 formed in WFIXSQ, and the free components of CCSTEP are set to BIGSTP. */
2004 bigstp = bdata->adelt + bdata->adelt;
2005 iflag=0;
2006 do {
2007 wfixsq = ggfree = 0.0;
2008 for(i=0; i<bdata->n; i++) {
2009 bdata->ccstep[i]=0.0;
2010 tempa = fmin(bdata->xopt[i] - bdata->sl[i], bdata->glag[i]);
2011 tempb = fmax(bdata->xopt[i] - bdata->su[i], bdata->glag[i]);
2012
2013/*
2014 // Removed again 2012-05-15 since now these do not have any effect
2015 if(fabs(tempa)<1.0E-20) tempa=0.0; // These 2 lines added by VO 2012-05-11
2016 if(fabs(tempb)<1.0E-20) tempb=0.0; // to prevent huge nr of function evals
2017*/
2018
2019 if(tempa>0.0 || tempb<0.0) {
2020 bdata->ccstep[i]=bigstp;
2021 d2=bdata->glag[i]*bdata->glag[i];
2022 // Added else by VO 2014-10-02
2023 if(isfinite(d2)) ggfree+=d2; else ggfree+=fabs(bdata->glag[i]);
2024 }
2025 }
2026 //if(ggfree==0.0) {bdata->cauchy=0.0; return;}
2027 // Added isfinite test by VO 2012-09-16
2028 if(!isfinite(ggfree) || ggfree==0.0) {bdata->cauchy=0.0; return;}
2029
2030
2031 /* Investigate whether more components of CCSTEP can be fixed. */
2032 do {
2033 //temp = bdata->adelt * bdata->adelt - wfixsq;
2034 temp=fma(bdata->adelt, bdata->adelt, -wfixsq);
2035 // This test added by VO 2014-10-02
2036 if(isnan(temp) || !isfinite(temp)) break;
2037 if(temp>0.0) {
2038 wsqsav=wfixsq; step=sqrt(temp/ggfree);
2039 // This test added by VO 2012-05-24 and updated 2014-10-02
2040 if(isnan(step) || !isfinite(step)) {bdata->cauchy=0.0; return;}
2041 ggfree=0.0;
2042 for(i=0; i<bdata->n; i++) {
2043 if(bdata->ccstep[i]==bigstp) {
2044 //d2 = bdata->xopt[i] - step*bdata->glag[i];
2045 d2=fma(bdata->glag[i], -step, bdata->xopt[i]);
2046 if(d2 <= bdata->sl[i]) {
2047 bdata->ccstep[i] = bdata->sl[i] - bdata->xopt[i];
2048 wfixsq+=bdata->ccstep[i]*bdata->ccstep[i];
2049 } else if(d2 >= bdata->su[i]) {
2050 bdata->ccstep[i] = bdata->su[i] - bdata->xopt[i];
2051 wfixsq+=bdata->ccstep[i]*bdata->ccstep[i];
2052 } else {
2053 ggfree+=bdata->glag[i]*bdata->glag[i];
2054 }
2055 }
2056 }
2057 }
2058#if(0) // original code
2059// } while(temp>0.0 && wfixsq>wsqsav && ggfree>0.0);
2060#else // Changed by VO
2061 // 2012-06-04 by VO: added tests to prevent looping forever in 32-bit Win7
2062 } while(isfinite(ggfree) && isfinite(wfixsq) && isfinite(wsqsav) &&
2063 // wfixsq-wsqsav>1.0E-30 && ggfree>1.0E-30 && temp>0.0);
2064 // Changed limits by VO 2012-09-16
2065 wfixsq-wsqsav>1.0E-50 && ggfree>1.0E-50 && temp>0.0);
2066#endif
2067
2068 /* Set the remaining free components of CCSTEP and all components of XALT,
2069 except that CCSTEP may be scaled later. */
2070 for(i=0, gw=0.0; i<bdata->n; i++) {
2071 if(bdata->ccstep[i]==bigstp) {
2072 bdata->ccstep[i] = -step*bdata->glag[i];
2073 d2=fmin(bdata->su[i], bdata->xopt[i]+bdata->ccstep[i]);
2074 bdata->xalt[i]=fmax(bdata->sl[i], d2);
2075 } else if(bdata->ccstep[i]==0.0) {
2076 bdata->xalt[i]=bdata->xopt[i];
2077 } else if(bdata->glag[i]>0.0) {
2078 bdata->xalt[i]=bdata->sl[i];
2079 } else {
2080 bdata->xalt[i]=bdata->su[i];
2081 }
2082 gw += bdata->glag[i]*bdata->ccstep[i];
2083 }
2084
2085 /* Set CURV to the curvature of the KNEW-th Lagrange function along CCSTEP.
2086 Scale CCSTEP by a factor less than one if that can reduce the modulus of
2087 the Lagrange function at XOPT+CCSTEP. Set CAUCHY to the final value of
2088 the square of this function. */
2089 for(k=0, curv=0.0; k<bdata->npt; k++) {
2090 for(j=0, temp=0.0; j<bdata->n; j++)
2091 temp+=bdata->xpt[k + j*bdata->npt] * bdata->ccstep[j];
2092 curv += bdata->hcol[k]*temp*temp;
2093 }
2094 if(iflag==1) curv=-curv;
2095 if(curv>-gw && curv<-(1.0+M_SQRT2)*gw) {
2096 scale = -gw/curv;
2097 for(i=0; i<bdata->n; i++) {
2098 //temp = bdata->xopt[i] + scale*bdata->ccstep[i];
2099 temp = fma(scale, bdata->ccstep[i], bdata->xopt[i]);
2100 d2=fmin(bdata->su[i], temp);
2101 bdata->xalt[i]=fmax(bdata->sl[i], d2);
2102 }
2103
2104 d1=0.5*gw*scale;
2105 } else {
2106 d1=fma(0.5, curv, gw); //d1=gw+0.5*curv;
2107 }
2108 bdata->cauchy=d1*d1;
2109
2110 /* If IFLAG is zero, then XALT is calculated as before after reversing
2111 the sign of GLAG. Thus two XALT vectors become available. The one that
2112 is chosen is the one that gives the larger value of CAUCHY. */
2113 if(iflag==0) {
2114 for(i=0; i<bdata->n; i++) {
2115 bdata->glag[i]=-bdata->glag[i];
2116 bdata->ccstep[bdata->n+i]=bdata->xalt[i];
2117 }
2118 csave=bdata->cauchy; iflag=1;
2119 } else {
2120 break;
2121 }
2122 } while(1);
2123 if(csave > bdata->cauchy) {
2124 for(i=0; i<bdata->n; i++) bdata->xalt[i]=bdata->ccstep[bdata->n+i];
2125 bdata->cauchy=csave;
2126 }
2127 return;
2128} /* bobyqa_altmov() */
2129/******************************************************************************/
2130
2131/******************************************************************************/
2136 bobyqa_data *bdata
2137) {
2138 bdata->prelim_nr++;
2139 if(bdata->verbose>5) {printf("bobyqa_prelim()\n"); fflush(stdout);}
2140
2141 double f, d1, d2;
2142 int i, j, k, ih, np, nfm;
2143 int nfx, ipt=0, jpt=0;
2144 double fbeg, diff, temp, recip, stepa, stepb;
2145 int itemp;
2146 double rhosq, SQRT_HALF;
2147 int nf;
2148
2149 /* Function Body */
2150 rhosq = bdata->rhobeg * bdata->rhobeg;
2151 recip = 1.0 / rhosq;
2152 np = bdata->n + 1;
2153 bdata->kopt=0;
2154 stepa=stepb=fbeg=0.0;
2155 jpt=ipt=0;
2156
2157
2158 /* Set XBASE to the initial vector of variables, and set the initial
2159 elements of XPT, BMAT, HQ, PQ and ZMAT to zero. */
2160 for(j=0; j<bdata->n; j++) {
2161 bdata->xbase[j]=bdata->x[j];
2162 for(k=0; k<bdata->npt; k++) bdata->xpt[k+j*bdata->npt]=0.0;
2163 for(i=0; i<bdata->ndim; i++) bdata->bmat[i+j*bdata->ndim]=0.0;
2164 }
2165 for(ih=0; ih<bdata->n*np/2; ih++) bdata->hq[ih]=0.0;
2166 for(k=0; k<bdata->npt; k++) {
2167 bdata->pq[k]=0.0;
2168 for(j=0; j<bdata->npt-np; j++) bdata->zmat[k+j*bdata->npt]=0.0;
2169 }
2170
2171 /* Begin the initialization procedure. NF becomes one more than the number
2172 of function values so far. The coordinates of the displacement of the
2173 next initial interpolation point from XBASE are set in XPT(NF+1,.). */
2174 nf=0; SQRT_HALF=sqrt(0.5);
2175 do {
2176 nfm=nf; nfx=nf-bdata->n; nf++;
2177 if(nfm<=2*bdata->n) {
2178 if(nfm>=1 && nfm<=bdata->n) {
2179 stepa=bdata->rhobeg;
2180 if(bdata->su[nfm-1]==0.0) stepa=-stepa;
2181 bdata->xpt[nf-1+(nfm-1)*bdata->npt]=stepa;
2182 } else if (nfm > bdata->n) {
2183 stepa = bdata->xpt[nf-1 - bdata->n + (nfx-1)*bdata->npt];
2184 stepb = -bdata->rhobeg;
2185 if(bdata->sl[nfx-1]==0.0) {
2186 stepb=fmin(2.0*bdata->rhobeg, bdata->su[nfx-1]);}
2187 if(bdata->su[nfx-1]==0.0) {
2188 stepb=fmax(-2.0*bdata->rhobeg, bdata->sl[nfx-1]);}
2189 bdata->xpt[nf-1 + (nfx-1)*bdata->npt] = stepb;
2190 }
2191 } else {
2192 itemp=(nfm-np)/bdata->n;
2193 jpt=nfm-itemp*bdata->n-bdata->n; ipt=jpt+itemp;
2194 if(ipt > bdata->n) {itemp=jpt; jpt=ipt-bdata->n; ipt=itemp;}
2195 bdata->xpt[nf-1+(ipt-1)*bdata->npt]= bdata->xpt[ipt+(ipt-1)*bdata->npt];
2196 bdata->xpt[nf-1+(jpt-1)*bdata->npt]= bdata->xpt[jpt+(jpt-1)*bdata->npt];
2197 }
2198
2199 /* Calculate the next value of F. The least function value so far and
2200 its index are required. */
2201 for(j=0; j<bdata->n; j++) {
2202 d2 = bdata->xbase[j] + bdata->xpt[nf-1 + j*bdata->npt];
2203 d1 = fmax(bdata->xl[j],d2);
2204 bdata->x[j] = fmin(d1,bdata->xu[j]);
2205 if(bdata->xpt[nf-1 + j*bdata->npt] == bdata->sl[j])
2206 bdata->x[j]=bdata->xl[j];
2207 else if(bdata->xpt[nf-1 + j*bdata->npt] == bdata->su[j])
2208 bdata->x[j]=bdata->xu[j];
2209 }
2210 /* Update the full parameter list for objf() */
2211 f=bobyqa_x_funcval(bdata, bdata->x);
2212 bdata->fval[nf-1]=f;
2213 if(nf==1) {fbeg=f; bdata->kopt=1;}
2214 else if(f<bdata->fval[bdata->kopt-1]) bdata->kopt=nf;
2215
2216 /* Set the nonzero initial elements of BMAT and the quadratic model in the
2217 cases when NF is at most 2*N+1. If NF exceeds N+1, then the positions
2218 of the NF-th and (NF-N)-th interpolation points may be switched, in
2219 order that the function value at the first of them contributes to the
2220 off-diagonal second derivative terms of the initial quadratic model. */
2221
2222 if(nf<=2*bdata->n+1) {
2223 if(nf>=2 && nf<=bdata->n+1) {
2224 bdata->gopt[nfm-1] = (f-fbeg)/stepa;
2225 if(bdata->npt < nf+bdata->n) {
2226 bdata->bmat[(nfm-1)*bdata->ndim] = -1.0/stepa;
2227 bdata->bmat[(nf-1) + (nfm-1)*bdata->ndim] = 1.0/stepa;
2228 bdata->bmat[bdata->npt + (nfm-1) + (nfm-1)*bdata->ndim] = -0.5*rhosq;
2229 }
2230 } else if(nf>=bdata->n+2) {
2231 ih = nfx*(nfx+1)/2;
2232 temp = (f-fbeg)/stepb; diff=stepb-stepa;
2233 bdata->hq[ih-1] = 2.0*(temp-bdata->gopt[nfx-1])/diff;
2234 bdata->gopt[nfx-1] = (bdata->gopt[nfx-1]*stepb - temp*stepa) / diff;
2235 if(stepa*stepb < 0.0) {
2236 if(f < bdata->fval[nf-1 - bdata->n]) {
2237 bdata->fval[nf-1] = bdata->fval[nf-1 - bdata->n];
2238 bdata->fval[nf-1 - bdata->n] = f;
2239 if(bdata->kopt==nf) bdata->kopt=nf-bdata->n;
2240 bdata->xpt[nf-1 - bdata->n + (nfx-1)*bdata->npt] = stepb;
2241 bdata->xpt[nf-1 + (nfx-1)*bdata->npt] = stepa;
2242 }
2243 }
2244 bdata->bmat[(nfx-1)*bdata->ndim] = -(stepa+stepb)/(stepa*stepb);
2245 bdata->bmat[(nf-1) + (nfx-1)*bdata->ndim] =
2246 -0.5/bdata->xpt[nf-1 - bdata->n + (nfx-1)*bdata->npt];
2247 bdata->bmat[nf-1 - bdata->n + (nfx-1)*bdata->ndim] =
2248 -bdata->bmat[(nfx-1)*bdata->ndim] -
2249 bdata->bmat[nf-1 + (nfx-1)*bdata->ndim];
2250 bdata->zmat[(nfx-1)*bdata->npt] = M_SQRT2/(stepa*stepb);
2251 bdata->zmat[nf-1 + (nfx-1)*bdata->npt] = SQRT_HALF/rhosq;
2252 bdata->zmat[nf-1 - bdata->n + (nfx-1)*bdata->npt] =
2253 -bdata->zmat[(nfx-1)*bdata->npt] -
2254 bdata->zmat[nf-1 + (nfx-1)*bdata->npt];
2255 }
2256
2257 } else {
2258 /* Set the off-diagonal second derivatives of the Lagrange functions and
2259 the initial quadratic model. */
2260 ih = ipt*(ipt-1)/2 + jpt;
2261 bdata->zmat[(nfx-1)*bdata->npt] = recip;
2262 bdata->zmat[nf-1 + (nfx-1)*bdata->npt] = recip;
2263 bdata->zmat[ipt + (nfx-1)*bdata->npt] = -recip;
2264 bdata->zmat[jpt + (nfx-1)*bdata->npt] = -recip;
2265 temp= bdata->xpt[nf - 1 + (ipt-1)*bdata->npt]
2266 * bdata->xpt[nf - 1 + (jpt-1)*bdata->npt];
2267 bdata->hq[ih-1] =
2268 (fbeg - bdata->fval[ipt] - bdata->fval[jpt] + f) / temp;
2269
2270 }
2271 //bdata->nevals=nf; // VO: added 2012-05-10, removed 2012-09-16
2272 if(f < bdata->minf_max) {
2273 //printf("BOBYQA_MINF_MAX_REACHED\n");
2274 return BOBYQA_MINF_MAX_REACHED;
2275 } else if((bdata->maxeval>0) && (bdata->nevals>=bdata->maxeval)) {
2276 //printf("BOBYQA_MAXEVAL_REACHED\n");
2277 return BOBYQA_MAXEVAL_REACHED;
2278 }
2279 } while (nf<bdata->npt);
2280
2281 return BOBYQA_SUCCESS;
2282} /* bobyqa_prelim() */
2283/******************************************************************************/
2284
2285/******************************************************************************/
2286// RESCUE
2294{
2295 bdata->rescue_nr++;
2296 // rescue() is called very seldomly, therefore tell it always in verbose mode
2297 if(bdata->verbose>0) {printf("bobyqa_rescue()\n"); fflush(stdout);}
2298
2299 double d1, d2, f;
2300 int i, j, k, ih, jp, ip, iq, np, iw;
2301 double xp=0.0, xq=0.0, den;
2302 int ihp=1;
2303 int ihq, jpn, kpt, kold;
2304 double sum, diff, winc, temp, bsum;
2305 int nrem;
2306 double hdiag, fbase, sfrac, vquad, sumpq;
2307 double dsqmin=0.0, distsq, vlmxsq;
2308 /* PTSAUX is also a working space array with length 2*N. For J=1,2,...,N,
2309 PTSAUX(1,J) and PTSAUX(2,J) specify the two positions of provisional
2310 interpolation points when a nonzero step is taken along e_J (the J-th
2311 coordinate direction) through XBASE+XOPT, as specified below.
2312 Usually these steps have length DELTA, but other lengths are chosen
2313 if necessary in order to satisfy the given bounds on the variables. */
2314 double *ptsaux;
2315 /* PTSID is also a working space array. It has NPT components that denote
2316 provisional new positions of the original interpolation points, in
2317 case changes are needed to restore the linear independence of the
2318 interpolation conditions. The K-th point is a candidate for change
2319 if and only if PTSID(K) is nonzero. In this case let p and q be the
2320 int parts of PTSID(K) and (PTSID(K)-p) multiplied by N+1. If p
2321 and q are both positive, the step from XBASE+XOPT to the new K-th
2322 interpolation point is PTSAUX(1,p)*e_p + PTSAUX(1,q)*e_q. Otherwise
2323 the step is PTSAUX(1,p)*e_p or PTSAUX(2,q)*e_q in the cases q=0 or
2324 p=0, respectively. */
2325 double *ptsid;
2326 /* Working space of length NDIM+NPT. */
2327 double *w;
2328
2329
2330 /* Allocate local memory; no need to preallocate */
2331 ptsaux=malloc(2*bdata->n*sizeof(double));
2332 ptsid=malloc(bdata->npt*sizeof(double));
2333 w=malloc((bdata->ndim*bdata->npt)*sizeof(double));
2334
2335 /* Function Body */
2336 np = bdata->n + 1;
2337 sfrac = 0.5 / (double)np;
2338
2339 /* Shift the interpolation points so that XOPT becomes the origin, and set
2340 the elements of ZMAT to zero. The value of SUMPQ is required in the
2341 updating of HQ below. The squares of the distances from XOPT to the
2342 other interpolation points are set at the end of W. Increments of WINC
2343 may be added later to these squares to balance the consideration of
2344 the choice of point that is going to become current. */
2345 sumpq = winc = 0.0;
2346 for(k=0; k<bdata->npt; k++) {
2347 for(j=0, distsq=0.0; j<bdata->n; j++) {
2348 bdata->xpt[k + j*bdata->npt] -= bdata->xopt[j];
2349 distsq += bdata->xpt[k + j*bdata->npt] * bdata->xpt[k + j*bdata->npt];
2350 }
2351 sumpq += bdata->pq[k];
2352 w[bdata->ndim + k] = distsq;
2353 winc=fmax(winc, distsq);
2354 for(j=0; j<bdata->nptm; j++) bdata->zmat[k + j*bdata->npt] = 0.0;
2355 }
2356
2357 /* Update HQ so that HQ and PQ define the second derivatives of the model
2358 after XBASE has been shifted to the trust region centre. */
2359 ih = 0;
2360 for(j=0; j<bdata->n; j++) {
2361 w[j] = 0.5*sumpq*bdata->xopt[j];
2362 for(k=0; k<bdata->npt; k++)
2363 w[j] += bdata->pq[k] * bdata->xpt[k + j*bdata->npt];
2364 for(i=0; i<=j; i++, ih++)
2365 bdata->hq[ih] += w[i]*bdata->xopt[j] + w[j]*bdata->xopt[i];
2366 }
2367
2368 /* Shift XBASE, SL, SU and XOPT. Set the elements of BMAT to zero, and
2369 also set the elements of PTSAUX. */
2370 for(j=0; j<bdata->n; j++) {
2371 bdata->xbase[j] += bdata->xopt[j];
2372 bdata->sl[j] -= bdata->xopt[j];
2373 bdata->su[j] -= bdata->xopt[j];
2374 bdata->xopt[j] = 0.0;
2375 ptsaux[j] = fmin(bdata->delta, bdata->su[j]);
2376 ptsaux[j+bdata->n] = fmax((-bdata->delta), bdata->sl[j]);
2377 if(ptsaux[j] + ptsaux[j+bdata->n] < 0.0) {
2378 temp = ptsaux[j];
2379 ptsaux[j] = ptsaux[j+bdata->n];
2380 ptsaux[j+bdata->n] = temp;
2381 }
2382 if(fabs(ptsaux[j+bdata->n]) < 0.5*(fabs(ptsaux[j])))
2383 ptsaux[j+bdata->n] = 0.5*ptsaux[j];
2384 for(i=0; i<bdata->ndim; ++i) bdata->bmat[i + j*bdata->ndim] = 0.0;
2385 }
2386 fbase = bdata->fval[bdata->kopt-1];
2387
2388 /* Set the identifiers of the artificial interpolation points that are
2389 along a coordinate direction from XOPT, and set the corresponding
2390 nonzero elements of BMAT and ZMAT. */
2391 ptsid[0] = sfrac;
2392 for(j=0; j<bdata->n; j++) {
2393 jp = j + 1; jpn = jp + bdata->n;
2394 ptsid[jp] = (double)(j+1) + sfrac;
2395 if(jpn < bdata->npt) {
2396 ptsid[jpn] = (double)(j+1)/(double)(np+1) + sfrac;
2397 temp = 1.0 / (ptsaux[j] - ptsaux[j+bdata->n]);
2398 bdata->bmat[jp + j*bdata->ndim] = -temp + 1.0 / ptsaux[j];
2399 bdata->bmat[jpn + j*bdata->ndim] = temp + 1.0 / ptsaux[j+bdata->n];
2400 bdata->bmat[j*bdata->ndim + 1] =
2401 -bdata->bmat[jp + j*bdata->ndim] - bdata->bmat[jpn + j*bdata->ndim];
2402 bdata->zmat[j*bdata->npt] = M_SQRT2/fabs(ptsaux[j] * ptsaux[j+bdata->n]);
2403 bdata->zmat[jp + j*bdata->npt] =
2404 bdata->zmat[j*bdata->npt] * ptsaux[j+bdata->n] * temp;
2405 bdata->zmat[jpn + j*bdata->npt] =
2406 -bdata->zmat[j*bdata->npt] * ptsaux[j] * temp;
2407 } else {
2408 bdata->bmat[j*bdata->ndim] = -1.0 / ptsaux[j];
2409 bdata->bmat[jp + j*bdata->ndim] = 1.0 / ptsaux[j];
2410 bdata->bmat[j + bdata->npt + j*bdata->ndim] = -0.5*(ptsaux[j]*ptsaux[j]);
2411 }
2412 }
2413
2414 /* Set any remaining identifiers with their nonzero elements of ZMAT. */
2415 if (bdata->npt >= bdata->n + np) {
2416 for(k=2*np-1; k<bdata->npt; k++) {
2417 /* we end up here only when user has given higher NPT than is
2418 usually required */
2419 iw = (int) ( ((double)(k+1-np)-0.5) / (double)bdata->n );
2420 ip = k+1 - np - iw*bdata->n;
2421 iq = ip + iw;
2422 if(iq>bdata->n) iq-=bdata->n;
2423 ptsid[k] = (double)ip + (double)iq/(double)np + sfrac;
2424 temp = 1.0 / (ptsaux[ip]*ptsaux[iq]);
2425 bdata->zmat[(k-np)*bdata->npt] = temp;
2426 bdata->zmat[ip + (k-np)*bdata->npt] = -temp;
2427 bdata->zmat[iq + (k-np)*bdata->npt] = -temp;
2428 bdata->zmat[k + (k-np)*bdata->npt] = temp;
2429 }
2430 }
2431 nrem=bdata->npt; kold=1; bdata->knew=bdata->kopt;
2432
2433 do {
2434 /* Reorder the provisional points in the way that exchanges PTSID(KOLD)
2435 with PTSID(KNEW). */
2436 for(j=0; j<bdata->n; j++) {
2437 temp = bdata->bmat[kold-1 + j*bdata->ndim];
2438 bdata->bmat[kold-1 + j*bdata->ndim] =
2439 bdata->bmat[bdata->knew-1 + j*bdata->ndim];
2440 bdata->bmat[bdata->knew-1 + j*bdata->ndim]=temp;
2441 }
2442 for(j=0; j<bdata->nptm; j++) {
2443 temp = bdata->zmat[kold-1 + j*bdata->npt];
2444 bdata->zmat[kold-1 + j*bdata->npt] =
2445 bdata->zmat[bdata->knew-1 + j*bdata->npt];
2446 bdata->zmat[bdata->knew-1 + j*bdata->npt] = temp;
2447 }
2448 ptsid[kold-1] = ptsid[bdata->knew-1];
2449 ptsid[bdata->knew-1]=0.0;
2450 w[bdata->ndim + bdata->knew-1]=0.0;
2451 --nrem;
2452 if(bdata->knew != bdata->kopt) {
2453 temp = bdata->vlag[kold-1];
2454 bdata->vlag[kold-1] = bdata->vlag[bdata->knew-1];
2455 bdata->vlag[bdata->knew-1] = temp;
2456
2457 /* Update the BMAT and ZMAT matrices so that the status of the KNEW-th
2458 interpolation point can be changed from provisional to original. The
2459 branch to label 350 occurs if all the original points are reinstated. */
2460 bobyqa_update(bdata);
2461 if(nrem==0) {free(ptsaux); free(ptsid); free(w); return BOBYQA_SUCCESS;}
2462 /* The nonnegative values of W(NDIM+K) are required in the search below. */
2463 for(k=0; k<bdata->npt; k++)
2464 w[k+bdata->ndim] = fabs(w[k+bdata->ndim]);
2465 }
2466
2467 /* Pick the index KNEW of an original interpolation point that has not
2468 yet replaced one of the provisional interpolation points, giving
2469 attention to the closeness to XOPT and to previous tries with KNEW. */
2470 while(1) {
2471 dsqmin=0.0;
2472 for(k=0; k<bdata->npt; k++) {
2473 if(w[bdata->ndim+k] > 0.0) {
2474 if(dsqmin==0.0 || w[bdata->ndim+k]<dsqmin) {
2475 bdata->knew=k+1; dsqmin=w[bdata->ndim+k];}
2476 }
2477 }
2478 if(dsqmin==0.0) break;
2479
2480 /* Form the W-vector of the chosen original interpolation point. */
2481 for(j=0; j<bdata->n; j++)
2482 w[bdata->npt+j] = bdata->xpt[bdata->knew-1 + j*bdata->npt];
2483
2484
2485 for(k=0; k<bdata->npt; k++) {
2486 sum=0.0;
2487 if(k==bdata->kopt-1) { // then nothing
2488 } else if(ptsid[k]==0.0) {
2489 for(j=0; j<bdata->n; j++)
2490 sum += w[bdata->npt+j]*bdata->xpt[k + j*bdata->npt];
2491 } else {
2492 ip = (int)ptsid[k];
2493 if(ip>0) sum = w[bdata->npt + ip-1] * ptsaux[ip-1]; // ok
2494 iq = (int) ( (double)np*ptsid[k] - (double)(ip*np)); // ok
2495 if(iq>0) {
2496 iw=0; if(ip==0) iw=1;
2497 sum += w[iq-1 + bdata->npt] * ptsaux[iq-1 + iw*bdata->n];
2498 }
2499 }
2500 w[k] = 0.5*sum*sum;
2501 }
2502 /* Calculate VLAG and BETA for the required updating of the H matrix if
2503 XPT(KNEW,.) is reinstated in the set of interpolation points. */
2504 for(k=0; k<bdata->npt; k++) {
2505 for(j=0, sum=0.0; j<bdata->n; j++)
2506 sum += bdata->bmat[k + j*bdata->ndim] * w[bdata->npt + j];
2507 bdata->vlag[k] = sum;
2508 }
2509 bdata->beta = 0.0;
2510 for(j=0; j<bdata->nptm; j++) {
2511 for(k=0, sum=0.0; k<bdata->npt; k++)
2512 sum += bdata->zmat[k + j*bdata->npt] * w[k];
2513 bdata->beta -= sum*sum;
2514 for(k=0; k<bdata->npt; k++)
2515 bdata->vlag[k] += sum * bdata->zmat[k + j*bdata->npt];
2516 }
2517 bsum = distsq = 0.0;
2518 for(j=0; j<bdata->n; j++) {
2519 for(k=0, sum=0.0; k<bdata->npt; k++)
2520 sum += bdata->bmat[k + j*bdata->ndim] * w[k];
2521 jp = j + bdata->npt;
2522 bsum += sum * w[jp];
2523 for(ip=bdata->npt; ip<bdata->ndim; ip++)
2524 sum += bdata->bmat[ip + j*bdata->ndim] * w[ip];
2525 bsum += sum * w[jp];
2526 bdata->vlag[jp] = sum;
2527 d1 = bdata->xpt[bdata->knew-1 + j*bdata->npt]; distsq += d1*d1;
2528 }
2529
2530 bdata->beta += 0.5*distsq*distsq - bsum;
2531 bdata->vlag[bdata->kopt-1] += 1.0;
2532
2533 /* KOLD is set to the index of the provisional interpolation point that is
2534 going to be deleted to make way for the KNEW-th original interpolation
2535 point. The choice of KOLD is governed by the avoidance of a small value
2536 of the denominator in the updating calculation of UPDATE. */
2537 bdata->denom = vlmxsq = 0.0;
2538 for(k=0; k<bdata->npt; k++) {
2539 if(ptsid[k] != 0.0) {
2540 for(j=0, hdiag=0.0; j<bdata->nptm; j++)
2541 hdiag += bdata->zmat[k + j*bdata->npt] * bdata->zmat[k + j*bdata->npt];
2542 den = bdata->beta*hdiag + bdata->vlag[k]*bdata->vlag[k];
2543 if(den > bdata->denom) {kold=k+1; bdata->denom=den;}
2544 }
2545 vlmxsq = fmax(vlmxsq, bdata->vlag[k]*bdata->vlag[k]);
2546 }
2547 if(bdata->denom > 0.01*vlmxsq) break;
2548 w[bdata->ndim + bdata->knew-1] = -w[bdata->ndim + bdata->knew-1] - winc;
2549 } // end of while
2550 } while(dsqmin!=0.0); // end of main loop
2551
2552 /* When this point is reached, all the final positions of the interpolation
2553 points have been chosen although any changes have not been included yet
2554 in XPT. Also the final BMAT and ZMAT matrices are complete, but, apart
2555 from the shift of XBASE, the updating of the quadratic model remains to
2556 be done. The following cycle through the new interpolation points begins
2557 by putting the new point in XPT(KPT,.) and by setting PQ(KPT) to zero,
2558 except that a RETURN occurs if MAXFUN prohibits another value of F. */
2559 for(kpt=0; kpt<bdata->npt; kpt++) if((ptsid[kpt]!=0.0)) {
2560
2561 if((bdata->maxeval>0) && (bdata->nevals>=bdata->maxeval)) {
2562 free(ptsaux); free(ptsid); free(w); return BOBYQA_MAXEVAL_REACHED;}
2563
2564 ih = 0;
2565 for(j=0; j<bdata->n; j++) {
2566 w[j] = bdata->xpt[kpt + j*bdata->npt];
2567 bdata->xpt[kpt + j*bdata->npt] = 0.0;
2568 temp = bdata->pq[kpt] * w[j];
2569 for(i=0; i<=j; i++, ih++) bdata->hq[ih] += temp*w[i];
2570 }
2571 bdata->pq[kpt] = 0.0;
2572 ip = (int) ptsid[kpt];
2573 iq = (int) ((double)np * ptsid[kpt] - (double)(ip * np));
2574 if(ip > 0) {
2575 xp = ptsaux[ip-1];
2576 bdata->xpt[kpt + (ip-1)*bdata->npt] = xp;
2577 }
2578 if(iq > 0) {
2579 xq = ptsaux[iq-1];
2580 if(ip==0) xq = ptsaux[iq-1 + bdata->n];
2581 bdata->xpt[kpt + (iq-1)*bdata->npt] = xq;
2582 }
2583
2584 /* Set VQUAD to the value of the current model at the new point. */
2585 vquad = fbase;
2586 if(ip > 0) {
2587 ihp = (ip + ip*ip) / 2;
2588 vquad += xp * (bdata->gopt[ip-1] + 0.5*xp*bdata->hq[ihp-1]);
2589 }
2590 if(iq > 0) {
2591 ihq = (iq + iq*iq) / 2;
2592 vquad += xq * (bdata->gopt[iq-1] + 0.5*xq*bdata->hq[ihq-1]);
2593 if(ip > 0) {
2594 if(ihp>=ihq) iw=ihp; else iw=ihq;
2595 iw-=abs(ip-iq);
2596 vquad += xp*xq*bdata->hq[iw-1];
2597 }
2598 }
2599 for(k=0; k<bdata->npt; k++) {
2600 temp=0.0;
2601 if(ip > 0) temp += xp * bdata->xpt[k + (ip-1)*bdata->npt];
2602 if(iq > 0) temp += xq * bdata->xpt[k + (iq-1)*bdata->npt];
2603 vquad += 0.5 * bdata->pq[k] * temp*temp;
2604 }
2605
2606 /* Calculate F at the new interpolation point, and set DIFF to the factor
2607 that is going to multiply the KPT-th Lagrange function when the model
2608 is updated to provide interpolation to the new function value. */
2609 for(i=0; i<bdata->n; i++) {
2610 d2 = bdata->xbase[i] + bdata->xpt[kpt + i*bdata->npt];
2611 d1 = fmax(bdata->xl[i], d2);
2612 w[i] = fmin(d1, bdata->xu[i]);
2613 if(bdata->xpt[kpt + i*bdata->npt] == bdata->sl[i]) w[i] = bdata->xl[i];
2614 if(bdata->xpt[kpt + i*bdata->npt] == bdata->su[i]) w[i] = bdata->xu[i];
2615 }
2616
2617 /* Update the full parameter list for objf() */
2618 f=bobyqa_x_funcval(bdata, w);
2619 bdata->fval[kpt] = f;
2620
2621 if(f < bdata->fval[bdata->kopt-1]) bdata->kopt = kpt+1;
2622 if(f < bdata->minf_max) {
2623 free(ptsaux); free(ptsid); free(w); return BOBYQA_MINF_MAX_REACHED;}
2624 else if((bdata->maxeval>0) && (bdata->nevals>=bdata->maxeval)) {
2625 free(ptsaux); free(ptsid); free(w); return BOBYQA_MAXEVAL_REACHED;}
2626 diff = f - vquad;
2627
2628 /* Update the quadratic model. The RETURN from the subroutine occurs when
2629 all the new interpolation points are included in the model. */
2630
2631 for(i=0; i<bdata->n; i++)
2632 bdata->gopt[i] += diff * bdata->bmat[kpt + i*bdata->ndim];
2633 for(k=0; k<bdata->npt; k++) {
2634 for(j=0, sum=0.0; j<bdata->nptm; j++)
2635 sum += bdata->zmat[k + j*bdata->npt] * bdata->zmat[kpt + j*bdata->npt];
2636 temp = diff * sum;
2637 if(ptsid[k]==0.0) {
2638 bdata->pq[k] += temp;
2639 } else {
2640 ip = (int)ptsid[k];
2641 iq = (int) ((double)np*ptsid[k] - (double)(ip*np));
2642 ihq = (iq*iq + iq) / 2;
2643 if(ip == 0) {
2644 d1=ptsaux[iq-1 + bdata->n];
2645 bdata->hq[ihq-1] += temp * (d1*d1);
2646 } else {
2647 ihp = (ip*ip + ip) / 2;
2648 d1 = ptsaux[ip-1];
2649 bdata->hq[ihp-1] += temp * (d1*d1);
2650 if(iq > 0) {
2651 d1 = ptsaux[iq-1];
2652 bdata->hq[ihq-1] += temp * (d1*d1);
2653 if(ihp>=ihq) iw=ihp; else iw=ihq;
2654 iw-=abs(iq-ip); // iw = max(ihp,ihq) - abs(iq-ip);
2655 bdata->hq[iw-1] += temp * ptsaux[ip-1] * ptsaux[iq-1];
2656 }
2657 }
2658 }
2659 }
2660 ptsid[kpt] = 0.0;
2661 }
2662
2663 free(ptsaux); free(ptsid); free(w);
2664 return BOBYQA_SUCCESS;
2665} /* bobyqa_rescue() */
2666/******************************************************************************/
2667
2668/******************************************************************************/
2669// TRSBOX
2673 bobyqa_data *bdata
2674) {
2675 int i, j, k, ih=0;
2676 double temp;
2677
2678 for(j=0; j<bdata->n; j++) {
2679 bdata->hs[j]=0.0;
2680 for(i=0; i<=j; i++, ih++) {
2681 if(i<j) bdata->hs[j]+=bdata->hq[ih]*bdata->s[i];
2682 bdata->hs[i]+=bdata->hq[ih]*bdata->s[j];
2683 }
2684 }
2685 for(k=0; k<bdata->npt; k++) if(bdata->pq[k]!=0.0) {
2686 for(j=0, temp=0.0; j<bdata->n; j++)
2687 temp+=bdata->xpt[k+j*bdata->npt]*bdata->s[j];
2688 temp*=bdata->pq[k];
2689 for(i=0; i<bdata->n; i++) bdata->hs[i]+=temp*bdata->xpt[k+i*bdata->npt];
2690 }
2691}
2692/******************************************************************************/
2696 bobyqa_data *bdata
2697) {
2698 int i;
2699 double d1, d2;
2700
2701 for(i=0, bdata->dsq=0.0; i<bdata->n; i++) {
2702 if(bdata->xbdi[i]==-1.0) bdata->xnew[i]=bdata->sl[i];
2703 else if(bdata->xbdi[i]==1.0) bdata->xnew[i]=bdata->su[i];
2704 else {
2705 d2=bdata->xopt[i]+bdata->dtrial[i]; d1=fmin(d2, bdata->su[i]);
2706 bdata->xnew[i]=fmax(d1, bdata->sl[i]);
2707 }
2708 bdata->dtrial[i]=bdata->xnew[i]-bdata->xopt[i];
2709 bdata->dsq+=bdata->dtrial[i]*bdata->dtrial[i];
2710 }
2711}
2712/******************************************************************************/
2713
2714/******************************************************************************/
2725 bobyqa_data *bdata
2726) {
2727 bdata->trsbox_nr++;
2728 if(bdata->verbose>5) {printf("trsbox()\n"); fflush(stdout);}
2729 int i, iu, iact, nact, isav, iterc, itermax, perp_altern=1;
2730 double ds, dhd, dhs, cth, shs, sth, ssq, beta, sdec=0.0, blen;
2731 double angt, qred, d1, d2;
2732 double temp, xsav=0.0, xsum, angbd, dredg=0.0, sredg;
2733 double resid, delsq, ggsav=0.0, tempa, tempb, redmax;
2734 double dredsq=0.0, redsav, gredsq=0.0, rednew;
2735 double rdprev=0.0, rdnext=0.0, stplen, stepsq;
2736
2737
2738 /* The sign of GOPT(I) gives the sign of the change to the I-th variable
2739 that will reduce Q from its value at XOPT. Thus XBDI(I) shows whether
2740 or not to fix the I-th variable at one of its bounds initially, with
2741 NACT being set to the number of fixed variables. D and GNEW are also
2742 set for the first iteration. DELSQ is the upper bound on the sum of
2743 squares of the free variables. QRED is the reduction in Q so far. */
2744 iterc=0; nact=0;
2745 for(i=0; i<bdata->n; i++) {
2746 bdata->xbdi[i] = 0.0;
2747 if(bdata->xopt[i]<=bdata->sl[i] && bdata->gopt[i]>=0.0)
2748 bdata->xbdi[i]=-1.0;
2749 else if(bdata->xopt[i]>=bdata->su[i] && bdata->gopt[i]<=0.0)
2750 bdata->xbdi[i]=1.0;
2751 if(bdata->xbdi[i]!=0.0) nact++;
2752 bdata->dtrial[i]=0.0;
2753 bdata->gnew[i]=bdata->gopt[i];
2754 }
2755 delsq = bdata->delta*bdata->delta;
2756 qred = 0.0;
2757 bdata->_crvmin = -1.0;
2758
2759 /* Set the next search direction of the conjugate gradient method. It is
2760 the steepest descent direction initially and when the iterations are
2761 restarted because a variable has just been fixed by a bound, and of
2762 course the components of the fixed variables are zero. ITERMAX is an
2763 upper bound on the indices of the conjugate gradient iterations. */
2764 beta = 0.0;
2765 itermax = iterc + bdata->n - nact;
2766 while(1) {
2767 stepsq = 0.0;
2768 for(i=0; i<bdata->n; i++) {
2769 if(bdata->xbdi[i]!=0.0) bdata->s[i]=0.0;
2770 else if(beta==0.0) bdata->s[i]=-bdata->gnew[i];
2771 else bdata->s[i]=beta*bdata->s[i]-bdata->gnew[i];
2772 stepsq+=bdata->s[i]*bdata->s[i];
2773 }
2774 if(stepsq == 0.0) {
2775 trsbox_set_xnew(bdata); return;
2776 }
2777 if(beta==0.0) {gredsq=stepsq; itermax=iterc+bdata->n-nact;}
2778 if(gredsq*delsq <= qred*qred*1.0E-04) {
2779 trsbox_set_xnew(bdata); return;
2780 }
2781
2782 /* Multiply the search direction by the second derivative matrix of Q and
2783 calculate some scalars for the choice of steplength. Then set BLEN to
2784 the length of the the step to the trust region boundary and STPLEN to
2785 the steplength, ignoring the simple bounds. */
2786 trsbox_s_multiply(bdata);
2787
2788 resid=delsq; ds=shs=0.0;
2789 for(i=0; i<bdata->n; i++) if(bdata->xbdi[i]==0.0) {
2790 resid-=bdata->dtrial[i]*bdata->dtrial[i];
2791 ds+=bdata->s[i]*bdata->dtrial[i]; shs+=bdata->s[i]*bdata->hs[i];
2792 }
2793 // if(resid<=0.0) break;
2794 // Added isfinite test by VO 2012-09-16
2795 if(!isfinite(resid) || resid<=0.0) break;
2796 temp=sqrt(stepsq*resid + ds*ds);
2797 if(ds<0.0) blen=(temp-ds)/stepsq; else blen=resid/(temp+ds);
2798 stplen=blen; if(shs>0.0) {d1=blen; d2=gredsq/shs; stplen=fmin(d1, d2);}
2799
2800 /* Reduce STPLEN if necessary in order to preserve the simple bounds,
2801 letting IACT be the index of the new constrained variable. */
2802 iact=0;
2803 for(i=0; i<bdata->n; i++) if(bdata->s[i]!=0.0) {
2804 xsum=bdata->xopt[i]+bdata->dtrial[i];
2805 if(bdata->s[i]>0.0) temp=(bdata->su[i]-xsum)/bdata->s[i];
2806 else temp=(bdata->sl[i]-xsum)/bdata->s[i];
2807 if(temp<stplen) {stplen=temp; iact=i+1;}
2808 }
2809
2810 /* Update CRVMIN, GNEW and D. Set SDEC to the decrease that occurs in Q. */
2811 sdec=0.0;
2812 if(isfinite(stplen) && stplen>0.0) {
2813// Changed to include isfinite test by VO 2012-09-16
2814// if(stplen>0.0) {
2815// if(stplen>1.0E-15) { // Changed by VO 2012-05-11 to reduce fevals
2816// Returned back to original 2012-05-15 since now it seems to have no effect
2817
2818 iterc++; temp=shs/stepsq;
2819 if(iact==0 && temp>0.0) {
2820 bdata->_crvmin=fmin(bdata->_crvmin, temp);
2821 if(bdata->_crvmin==-1.0) bdata->_crvmin=temp;
2822 }
2823 ggsav=gredsq; gredsq=0.0;
2824 for(i=0; i<bdata->n; i++) {
2825 bdata->gnew[i]+=stplen*bdata->hs[i];
2826 if(bdata->xbdi[i]==0.0) gredsq+=bdata->gnew[i]*bdata->gnew[i];
2827 bdata->dtrial[i]+=stplen*bdata->s[i];
2828 }
2829 d1=stplen*(ggsav-0.5*stplen*shs); sdec=fmax(d1,0.0); qred+=sdec;
2830 }
2831
2832 /* Restart the conjugate gradient method if it has hit a new bound. */
2833 if(iact>0) {
2834 i=iact-1; nact++;
2835 if(bdata->s[i]<0.0) bdata->xbdi[i]=-1.0; else bdata->xbdi[i]=1.0;
2836 delsq-=bdata->dtrial[i]*bdata->dtrial[i];
2837 if(!isfinite(delsq) || delsq<=0.0) break; // Added isfinite 2012-09-16
2838 beta=0.0;
2839 continue;
2840 }
2841
2842 /* If STPLEN is less than BLEN, then either apply another conjugate
2843 gradient iteration or RETURN. */
2844 if(stplen>=blen) break;
2845 if(iterc==itermax || sdec<=0.01*qred) {
2846 trsbox_set_xnew(bdata); return;
2847 }
2848 beta=gredsq/ggsav; if(!isfinite(beta)) beta=0.0; // Added isfinite 2012-09-16
2849 } // end of while
2850
2851 bdata->_crvmin=0.0;
2852
2853 while(1) {
2854 if(perp_altern==1) {
2855 /* Prepare for the alternative iteration by calculating some scalars
2856 and by multiplying the reduced D by the second derivative matrix of
2857 Q, where S holds the reduced D in the call of GGMULT. */
2858 if(nact>=bdata->n-1) {
2859 trsbox_set_xnew(bdata); return;
2860 }
2861 dredsq=dredg=gredsq=0.0;
2862 for(i=0; i<bdata->n; i++) {
2863 if(bdata->xbdi[i]==0.0) {
2864 dredsq+=bdata->dtrial[i]*bdata->dtrial[i];
2865 dredg+=bdata->dtrial[i]*bdata->gnew[i];
2866 gredsq+=bdata->gnew[i]*bdata->gnew[i]; bdata->s[i]=bdata->dtrial[i];
2867 } else {
2868 bdata->s[i]=0.0;
2869 }
2870 }
2871 trsbox_s_multiply(bdata);
2872 for(i=0; i<bdata->n; i++) bdata->hred[i]=bdata->hs[i];
2873 }
2874
2875 /* Let the search direction S be a linear combination of the reduced D
2876 and the reduced G that is orthogonal to the reduced D. */
2877 iterc++;
2878 temp = gredsq*dredsq - dredg*dredg;
2879 if(!isfinite(temp) || temp<=qred*qred*1.0E-04) {// Added isfinite 2012-09-16
2880 trsbox_set_xnew(bdata); return;
2881 }
2882 temp = sqrt(temp);
2883 for(i=0; i<bdata->n; i++) {
2884 if(bdata->xbdi[i]==0.0)
2885 bdata->s[i]=(dredg*bdata->dtrial[i]-dredsq*bdata->gnew[i])/temp;
2886 else bdata->s[i]=0.0;
2887 }
2888 sredg=-temp;
2889
2890 /* By considering the simple bounds on the variables, calculate an upper
2891 bound on the tangent of half the angle of the alternative iteration,
2892 namely ANGBD, except that, if already a free variable has reached a
2893 bound, there is a branch back to label 100 after fixing that variable. */
2894 angbd=1.0; iact=0;
2895 for(i=0; i<bdata->n; i++) if(bdata->xbdi[i]==0.0) {
2896 tempa=bdata->xopt[i]+bdata->dtrial[i]-bdata->sl[i];
2897 tempb=bdata->su[i]-bdata->xopt[i]-bdata->dtrial[i];
2898 if(tempa<=0.0) {nact++; bdata->xbdi[i]=-1.0; break;}
2899 else if(tempb<=0.0) {nact++; bdata->xbdi[i]=1.0; break;}
2900 d1=bdata->dtrial[i]; d2=bdata->s[i]; ssq=d1*d1+d2*d2;
2901 d1=bdata->xopt[i]-bdata->sl[i]; temp=ssq-d1*d1;
2902 if(temp>0.0) {
2903 temp=sqrt(temp)-bdata->s[i];
2904 if(angbd*temp>tempa) {angbd=tempa/temp; iact=i+1; xsav=-1.0;}
2905 }
2906 d1=bdata->su[i]-bdata->xopt[i]; temp=ssq-d1*d1;
2907 if(temp>0.0) {
2908 temp=sqrt(temp)+bdata->s[i];
2909 if(angbd*temp>tempb) {angbd=tempb/temp; iact=i+1; xsav=1.0;}
2910 }
2911 }
2912 if(i<bdata->n) {perp_altern=1; continue;} // Break in the loop
2913
2914 /* Calculate HHD and some curvatures for the alternative iteration. */
2915 trsbox_s_multiply(bdata);
2916 shs=dhs=dhd=0.0;
2917 for(i=0; i<bdata->n; i++) if(bdata->xbdi[i]==0.0) {
2918 shs += bdata->s[i]*bdata->hs[i];
2919 dhs += bdata->dtrial[i]*bdata->hs[i];
2920 dhd += bdata->dtrial[i]*bdata->hred[i];
2921 }
2922
2923 /* Seek the greatest reduction in Q for a range of equally spaced values
2924 of ANGT in [0,ANGBD], where ANGT is the tangent of half the angle of
2925 the alternative iteration. */
2926 redmax=redsav=0.0; isav=0;
2927 iu=(int)(angbd*17.+3.1);
2928 for(i=1; i<=iu; i++) {
2929 angt = angbd*(double)i/(double)iu;
2930 sth = (angt+angt)/(1.0+angt*angt);
2931 temp = shs+angt*(angt*dhd-dhs-dhs);
2932 rednew = sth*(angt*dredg-sredg-0.5*sth*temp);
2933 if(rednew>redmax) {redmax=rednew; isav=i; rdprev=redsav;}
2934 else if(i==isav+1) {rdnext=rednew;}
2935 redsav=rednew;
2936 }
2937
2938 /* Return if the reduction is zero. Otherwise, set the sine and cosine
2939 of the angle of the alternative iteration, and calculate SDEC. */
2940 if(isav==0) {
2941 trsbox_set_xnew(bdata); return;
2942 }
2943 if(isav<iu) {
2944 temp = (rdnext-rdprev)/(redmax+redmax-rdprev-rdnext);
2945 angt = angbd*((double)isav+0.5*temp)/(double)iu;
2946 }
2947 d2=angt*angt; cth=(1.0-d2)/(1.0+d2);
2948 sth = (angt+angt)/(1.0+d2);
2949 temp = shs+angt*(angt*dhd-dhs-dhs);
2950 sdec = sth*(angt*dredg-sredg-0.5*sth*temp);
2951 if(sdec<=0.0) {
2952 trsbox_set_xnew(bdata); return;
2953 }
2954
2955 /* Update GNEW, D and HRED. If the angle of the alternative iteration
2956 is restricted by a bound on a free variable, that variable is fixed
2957 at the bound. */
2958 dredg=gredsq=0.0;
2959 for(i=0; i<bdata->n; i++) {
2960 bdata->gnew[i]+=(cth-1.0)*bdata->hred[i]+sth*bdata->hs[i];
2961 if(bdata->xbdi[i]==0.0) {
2962 bdata->dtrial[i]=cth*bdata->dtrial[i]+sth*bdata->s[i];
2963 dredg+=bdata->dtrial[i]*bdata->gnew[i];
2964 gredsq+=bdata->gnew[i]*bdata->gnew[i];
2965 }
2966 bdata->hred[i]=cth*bdata->hred[i]+sth*bdata->hs[i];
2967 }
2968
2969 qred += sdec;
2970 if(iact>0 && isav==iu) {
2971 nact++; bdata->xbdi[iact-1]=xsav;
2972 perp_altern=1; continue;
2973 }
2974
2975 /* If SDEC is sufficiently small, then RETURN after setting XNEW to
2976 XOPT+D, giving careful attention to the bounds. */
2977 if(sdec<=0.01*qred) break;
2978
2979 perp_altern=0;
2980 } // end of while
2981
2982 trsbox_set_xnew(bdata);
2983 return;
2984} /* bobyqa_trsbox() */
2985/******************************************************************************/
2986
2987/******************************************************************************/
2988// UPDATE
2999 bobyqa_data *bdata
3000) {
3001 bdata->update_nr++;
3002 if(bdata->verbose>4) {printf("bobyqa_update()\n"); fflush(stdout);}
3003
3004 int i, j, k, jp;
3005 double tau, temp, d1, d2;
3006 double alpha, tempa, tempb, ztest;
3007
3008 /* Function Body */
3009 ztest = 0.0;
3010 for(k=0; k<bdata->npt; k++) for(j=0; j<bdata->nptm; j++) {
3011 d1=fabs(bdata->zmat[k + j*bdata->npt]);
3012 if(d1>ztest) ztest=d1;
3013 }
3014 ztest*=1.0E-20;
3015
3016 /* Apply the rotations that put zeros in the KNEW-th row of ZMAT. */
3017 for(j=1; j<bdata->nptm; j++) {
3018 if(fabs(bdata->zmat[bdata->knew-1 + j*bdata->npt]) > ztest) {
3019 d1=bdata->zmat[bdata->knew-1];
3020 d2=bdata->zmat[bdata->knew-1 + j*bdata->npt];
3021 temp=hypot(d1,d2);
3022 tempa=bdata->zmat[bdata->knew-1] / temp;
3023 tempb=bdata->zmat[bdata->knew-1 + j*bdata->npt] / temp;
3024 for(i=0; i<bdata->npt; i++) {
3025 temp=tempa*bdata->zmat[i] + tempb*bdata->zmat[i + j*bdata->npt];
3026 if(temp<-1.0E+100) temp=-1.0E+100; // added by VO
3027 else if(temp>+1.0E+100) temp=+1.0E+100; // added by VO
3028 bdata->zmat[i + j*bdata->npt] =
3029 tempa*bdata->zmat[i + j*bdata->npt] - tempb*bdata->zmat[i];
3030 if(bdata->zmat[i + j*bdata->npt]<-1.0E+100) // added by VO
3031 bdata->zmat[i + j*bdata->npt]=-1.0E+100;
3032 else if(bdata->zmat[i + j*bdata->npt]>+1.0E+100) // added by VO
3033 bdata->zmat[i + j*bdata->npt]=+1.0E+100;
3034 bdata->zmat[i]=temp;
3035 }
3036 }
3037 bdata->zmat[bdata->knew-1 + j*bdata->npt]=0.0;
3038 }
3039
3040 /* Put the first NPT components of the KNEW-th column of HLAG into WNDIM,
3041 and calculate the parameters of the updating formula. */
3042 for(i=0; i<bdata->npt; i++)
3043 bdata->wndim[i]=bdata->zmat[bdata->knew-1]*bdata->zmat[i];
3044 alpha=bdata->wndim[bdata->knew-1]; tau=bdata->vlag[bdata->knew-1];
3045 bdata->vlag[bdata->knew-1]-=1.0;
3046
3047 /* Complete the updating of ZMAT. */
3048 temp=sqrt(bdata->denom);
3049 //if(isnan(temp) || !isfinite(temp)) temp=1.0E-20; // added by VO 2012-06-04
3050 if(isnan(temp) || !isfinite(temp)) temp=1.0E-50; // changed limit 2012-09-16
3051 tempa=tau/temp;
3052 //if(isnan(tempa)||!isfinite(tempa)) tempa=tau*1.0E+20; //added by VO 2012-06-04
3053 if(isnan(tempa)||!isfinite(tempa)) tempa=tau*1.0E+50; //changed limit 2012-09-16
3054 tempb=bdata->zmat[bdata->knew-1]/temp;
3055 if(isnan(tempa)||!isfinite(tempa))
3056 //tempb=bdata->zmat[bdata->knew-1]*1.0E+20; //added by VO 2012-06-04
3057 tempb=bdata->zmat[bdata->knew-1]*1.0E+50; //changed limit 2012-09-16
3058 for(i=0; i<bdata->npt; i++)
3059 bdata->zmat[i]=tempa*bdata->zmat[i]-tempb*bdata->vlag[i];
3060
3061 /* Finally, update the matrix BMAT. */
3062 for (j = 1; j <=bdata->n; j++) {
3063 jp = bdata->npt + j;
3064 bdata->wndim[jp-1] = bdata->bmat[bdata->knew-1 + (j-1)*bdata->ndim];
3065 tempa=(alpha*bdata->vlag[jp-1] - tau*bdata->wndim[jp-1]) / bdata->denom;
3066 tempb=(-bdata->beta*bdata->wndim[jp-1]-tau*bdata->vlag[jp-1])/bdata->denom;
3067 for(i=1; i<=jp; i++) {
3068#if(0) // original
3069 bdata->bmat[i-1 + (j-1)*bdata->ndim]= bdata->bmat[i-1 + (j-1)*bdata->ndim]
3070 + tempa*bdata->vlag[i-1] + tempb*bdata->wndim[i-1];
3071#else // modified
3072 bdata->bmat[i-1 + (j-1)*bdata->ndim] +=
3073 tempa*bdata->vlag[i-1] + tempb*bdata->wndim[i-1];
3074#endif
3075 /* Previous change should lead to same result, but some differences exist.
3076 Same effect is seen already in the first f2c version 110917.
3077 This is because of precision issues, calculations are done in different
3078 order, and also putting last sum in parenthesis changes the result.
3079 */
3080
3081 if(i>bdata->npt) {
3082 bdata->bmat[jp-1 + (i-1 - bdata->npt) * bdata->ndim] =
3083 bdata->bmat[i-1 + (j-1)*bdata->ndim];
3084 }
3085 }
3086 }
3087
3088} /* bobyqa_update() */
3089/******************************************************************************/
3090
3091/******************************************************************************/
bobyqa_result bobyqa_prelim(bobyqa_data *bdata)
Definition bobyqa.c:2135
void bobyqb_ip_alternative(bobyqa_data *bdata)
Definition bobyqa.c:1593
bobyqa_result bobyqb(bobyqa_data *bdata)
Definition bobyqa.c:1622
char * bobyqa_rc(bobyqa_result rc)
Definition bobyqa.c:381
void bobyqb_vlag_beta_for_d(bobyqa_data *bdata)
Definition bobyqa.c:1055
void bobyqa_print(bobyqa_data *bdata, int sw, FILE *fp)
Definition bobyqa.c:640
bobyqa_result bobyqa_free_memory(bobyqa_data *bdata)
Definition bobyqa.c:592
int bobyqb_ip_dist(bobyqa_data *bdata)
Definition bobyqa.c:1575
void bobyqb_update_gopt(bobyqa_data *bdata)
Definition bobyqa.c:945
void bobyqa_altmov(bobyqa_data *bdata)
Definition bobyqa.c:1875
int bobyqb_part(bobyqa_data *bdata)
Definition bobyqa.c:1449
bobyqa_result bobyqa(int n, int npt, double *x, const double *xl, const double *xu, const double *dx, const double rhoend, double xtol_rel, double minf_max, double ftol_rel, double ftol_abs, int maxeval, int *nevals, double *minf, double(*f)(int n, double *x, void *objf_data), void *objf_data, double *working_space, int verbose)
Definition bobyqa.c:40
double bobyqa_x_funcval(bobyqa_data *bdata, double *x)
Definition bobyqa.c:751
void bobyqa_trsbox(bobyqa_data *bdata)
Definition bobyqa.c:2724
int bobyqb_do_rescue(bobyqa_data *bdata)
Definition bobyqa.c:1402
int bobyqb_calc_with_xnew(bobyqa_data *bdata)
Definition bobyqa.c:1093
bobyqa_result bobyqa_set_memory(int n, int fitted_n, int npt, bobyqa_data *bdata, double *wm)
Definition bobyqa.c:501
bobyqa_result bobyqa_reset_memory(bobyqa_data *bdata)
Definition bobyqa.c:614
void bobyqb_xupdate(bobyqa_data *bdata)
Definition bobyqa.c:921
int bobyqa_working_memory_size(int n, int fitted_n, int npt, bobyqa_data *bdata)
Definition bobyqa.c:441
void bobyqa_xfull(bobyqa_data *bdata)
Definition bobyqa.c:769
void bobyqb_shift_xbase(bobyqa_data *bdata)
Definition bobyqa.c:973
void bobyqa_update(bobyqa_data *bdata)
Definition bobyqa.c:2998
bobyqa_result bobyqa_rescue(bobyqa_data *bdata)
Definition bobyqa.c:2293
bobyqa_result bobyqa_set_optimization(int full_n, double *x, const double *dx, const double *xl, const double *xu, const double rhoend, double xtol_rel, double minf_max, double ftol_rel, double ftol_abs, int maxeval, double(*f)(int n, double *x, void *objf_data), void *objf_data, int verbose, bobyqa_data *bdata)
Definition bobyqa.c:781
int bobyqa_minimize_single_parameter(bobyqa_data *bdata)
Definition bobyqa.c:210
int fixed_params(int n, const double *lower, const double *upper, const double *delta)
Definition bobyqa.c:418
void bobyqb_next_rho_delta(bobyqa_data *bdata)
Definition bobyqa.c:1383
void trsbox_s_multiply(bobyqa_data *bdata)
Definition bobyqa.c:2672
void trsbox_set_xnew(bobyqa_data *bdata)
Definition bobyqa.c:2695
Header file for libtpcmodel.
double(* bobyqa_func)(int n, const double *x, void *func_data)
Definition libtpcmodel.h:92
bobyqa_result
Definition libtpcmodel.h:77
double * hcol
double * xnew
double cauchy
double * dtrial
double rhoend
double * wmptr
double * su
double biglsq
double distsq
double * xl
double * hs
double * zmat
double * gopt
double ftol_abs
double * xscale
double * xbase
double scaden
double * pq
double minf_max
double * xopt
double * fval
double * glag
double ftol_rel
void * objf_data
double rhobeg
double * w2npt
double * xbdi
double * bmat
double * x
double * lwmptr
double * wn
double * wndim
double * s
double * hred
double * gnew
double xoptsq
bobyqa_func objf
double * vlag
double * sl
double * xu
double * xfull
double * xalt
double * hq
double * xpt
double * ccstep