67 #ifndef INCLUDED_newuoa_h_GUID_F9E56CF3_7B12_41A0_4A09_E2A02B48FAC1 68 #define INCLUDED_newuoa_h_GUID_F9E56CF3_7B12_41A0_4A09_E2A02B48FAC1 79 #include <type_traits> 82 #define DEBUG_LOG(what) 85 #define DEBUG_LOG(what) DEBUG_LOG(what) 87 #define DEBUG_LOG(what) 93 template <
class Function>
94 void biglag(
long n,
long npt,
double *xopt,
double *xpt,
double *bmat,
95 double *zmat,
long *idz,
long *ndim,
long *knew,
double *delta,
96 double *d__,
double *alpha,
double *hcol,
double *gc,
double *gd,
97 double *s,
double *w, Function &&
function) {
113 long xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1, zmat_offset,
114 i__1, i__2, i__, j, k, iu, nptm, iterc, isave;
115 double sp, ss, cf1, cf2, cf3, cf4, cf5, dhd, cth, tau, sth, sum, temp, step,
116 angle, scale, denom, delsq, tempa, tempb, twopi, taubeg, tauold, taumax,
122 zmat_offset = 1 + zmat_dim1;
125 xpt_offset = 1 + xpt_dim1;
129 bmat_offset = 1 + bmat_dim1;
139 delsq = *delta * *delta;
145 for (k = 1; k <= i__1; ++k)
148 for (j = 1; j <= i__1; ++j) {
149 temp = zmat[*knew + j * zmat_dim1];
153 for (k = 1; k <= i__2; ++k)
154 hcol[k] += temp * zmat[k + j * zmat_dim1];
156 *alpha = hcol[*knew];
162 for (i__ = 1; i__ <= i__2; ++i__) {
163 d__[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
164 gc[i__] = bmat[*knew + i__ * bmat_dim1];
171 for (k = 1; k <= i__2; ++k) {
175 for (j = 1; j <= i__1; ++j) {
176 temp += xpt[k + j * xpt_dim1] * xopt[j];
177 sum += xpt[k + j * xpt_dim1] * d__[j];
179 temp = hcol[k] * temp;
182 for (i__ = 1; i__ <= i__1; ++i__) {
183 gc[i__] += temp * xpt[k + i__ * xpt_dim1];
184 gd[i__] += sum * xpt[k + i__ * xpt_dim1];
191 for (i__ = 1; i__ <= i__1; ++i__) {
195 sp += d__[i__] * gc[i__];
196 dhd += d__[i__] * gd[i__];
198 scale = *delta / sqrt(dd);
202 if (sp * sp > dd * .99 * gg)
204 tau = scale * (fabs(sp) + 0.5 * scale * fabs(dhd));
205 if (gg * delsq < tau * .01 * tau)
208 for (i__ = 1; i__ <= i__1; ++i__) {
209 d__[i__] = scale * d__[i__];
210 gd[i__] = scale * gd[i__];
211 s[i__] = gc[i__] + temp * gd[i__];
216 for (iterc = 0; iterc != n; ++iterc) {
219 for (i__ = 1; i__ <= i__1; ++i__) {
223 sp += d__[i__] * s[i__];
228 temp = dd * ss - sp * sp;
229 if (temp <= dd * 1e-8 * ss)
233 for (i__ = 1; i__ <= i__1; ++i__) {
234 s[i__] = (dd * s[i__] - sp * d__[i__]) / denom;
241 for (k = 1; k <= i__1; ++k) {
244 for (j = 1; j <= i__2; ++j)
245 sum += xpt[k + j * xpt_dim1] * s[j];
248 for (i__ = 1; i__ <= i__2; ++i__)
249 w[i__] += sum * xpt[k + i__ * xpt_dim1];
251 cf1 = cf2 = cf3 = cf4 = cf5 = 0;
253 for (i__ = 1; i__ <= i__2; ++i__) {
254 cf1 += s[i__] * w[i__];
255 cf2 += d__[i__] * gc[i__];
256 cf3 += s[i__] * gc[i__];
257 cf4 += d__[i__] * gd[i__];
258 cf5 += s[i__] * gd[i__];
261 cf4 = 0.5 * cf4 - cf1;
263 taubeg = cf1 + cf2 + cf4;
264 taumax = tauold = taubeg;
267 temp = twopi / (double)(iu + 1);
269 for (i__ = 1; i__ <= i__2; ++i__) {
270 angle = (double)i__ * temp;
273 tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
274 if (fabs(tau) > fabs(taumax)) {
278 }
else if (i__ == isave + 1)
287 if (tempa != tempb) {
290 step = 0.5 * (tempa - tempb) / (tempa + tempb);
292 angle = temp * ((double)isave + step);
296 tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
298 for (i__ = 1; i__ <= i__2; ++i__) {
299 d__[i__] = cth * d__[i__] + sth * s[i__];
300 gd[i__] = cth * gd[i__] + sth * w[i__];
301 s[i__] = gc[i__] + gd[i__];
303 if (fabs(tau) <= fabs(taubeg) * 1.1)
308 void bigden(
long n,
long npt,
double *xopt,
double *xpt,
double *bmat,
309 double *zmat,
long *idz,
long *ndim,
long *kopt,
long *knew,
310 double *d__,
double *w,
double *vlag,
double *beta,
double *s,
311 double *wvec,
double *prod) {
338 long xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1, zmat_offset,
339 wvec_dim1, wvec_offset, prod_dim1, prod_offset, i__1, i__2, i__, j, k,
340 isave, iterc, jc, ip, iu, nw, ksav, nptm;
341 double dd, d__1, ds, ss, den[9], par[9], tau, sum, diff, temp, step, alpha,
342 angle, denex[9], tempa, tempb, tempc, ssden, dtest, xoptd, twopi, xopts,
343 denold, denmax, densav, dstemp, sumold, sstemp, xoptsq;
347 zmat_offset = 1 + zmat_dim1;
350 xpt_offset = 1 + xpt_dim1;
354 prod_offset = 1 + prod_dim1;
357 wvec_offset = 1 + wvec_dim1;
360 bmat_offset = 1 + bmat_dim1;
367 twopi = atan(1.0) * 8.;
372 for (k = 1; k <= i__1; ++k)
375 for (j = 1; j <= i__1; ++j) {
376 temp = zmat[*knew + j * zmat_dim1];
380 for (k = 1; k <= i__2; ++k)
381 w[n + k] += temp * zmat[k + j * zmat_dim1];
383 alpha = w[n + *knew];
389 dd = ds = ss = xoptsq = 0;
391 for (i__ = 1; i__ <= i__2; ++i__) {
395 s[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
396 ds += d__[i__] * s[i__];
402 xoptsq += d__1 * d__1;
404 if (ds * ds > dd * .99 * ss) {
406 dtest = ds * ds / ss;
408 for (k = 1; k <= i__2; ++k) {
413 for (i__ = 1; i__ <= i__1; ++i__) {
414 diff = xpt[k + i__ * xpt_dim1] - xopt[i__];
415 dstemp += d__[i__] * diff;
416 sstemp += diff * diff;
418 if (dstemp * dstemp / sstemp < dtest) {
420 dtest = dstemp * dstemp / sstemp;
427 for (i__ = 1; i__ <= i__2; ++i__)
428 s[i__] = xpt[ksav + i__ * xpt_dim1] - xopt[i__];
430 ssden = dd * ss - ds * ds;
437 temp = 1.0 / sqrt(ssden);
440 for (i__ = 1; i__ <= i__2; ++i__) {
441 s[i__] = temp * (dd * s[i__] - ds * d__[i__]);
442 xoptd += xopt[i__] * d__[i__];
443 xopts += xopt[i__] * s[i__];
446 tempa = 0.5 * xoptd * xoptd;
447 tempb = 0.5 * xopts * xopts;
448 den[0] = dd * (xoptsq + 0.5 * dd) + tempa + tempb;
449 den[1] = 2.0 * xoptd * dd;
450 den[2] = 2.0 * xopts * dd;
451 den[3] = tempa - tempb;
452 den[4] = xoptd * xopts;
453 for (i__ = 6; i__ <= 9; ++i__)
457 for (k = 1; k <= i__2; ++k) {
458 tempa = tempb = tempc = 0;
460 for (i__ = 1; i__ <= i__1; ++i__) {
461 tempa += xpt[k + i__ * xpt_dim1] * d__[i__];
462 tempb += xpt[k + i__ * xpt_dim1] * s[i__];
463 tempc += xpt[k + i__ * xpt_dim1] * xopt[i__];
465 wvec[k + wvec_dim1] = 0.25 * (tempa * tempa + tempb * tempb);
466 wvec[k + (wvec_dim1 << 1)] = tempa * tempc;
467 wvec[k + wvec_dim1 * 3] = tempb * tempc;
468 wvec[k + (wvec_dim1 << 2)] = 0.25 * (tempa * tempa - tempb * tempb);
469 wvec[k + wvec_dim1 * 5] = 0.5 * tempa * tempb;
472 for (i__ = 1; i__ <= i__2; ++i__) {
474 wvec[ip + wvec_dim1] = 0;
475 wvec[ip + (wvec_dim1 << 1)] = d__[i__];
476 wvec[ip + wvec_dim1 * 3] = s[i__];
477 wvec[ip + (wvec_dim1 << 2)] = 0;
478 wvec[ip + wvec_dim1 * 5] = 0;
481 for (jc = 1; jc <= 5; ++jc) {
483 if (jc == 2 || jc == 3)
486 for (k = 1; k <= i__2; ++k)
487 prod[k + jc * prod_dim1] = 0;
489 for (j = 1; j <= i__2; ++j) {
492 for (k = 1; k <= i__1; ++k)
493 sum += zmat[k + j * zmat_dim1] * wvec[k + jc * wvec_dim1];
497 for (k = 1; k <= i__1; ++k)
498 prod[k + jc * prod_dim1] += sum * zmat[k + j * zmat_dim1];
502 for (k = 1; k <= i__1; ++k) {
505 for (j = 1; j <= i__2; ++j)
506 sum += bmat[k + j * bmat_dim1] *
507 wvec[npt + j + jc * wvec_dim1];
508 prod[k + jc * prod_dim1] += sum;
512 for (j = 1; j <= i__1; ++j) {
515 for (i__ = 1; i__ <= i__2; ++i__)
516 sum += bmat[i__ + j * bmat_dim1] * wvec[i__ + jc * wvec_dim1];
517 prod[npt + j + jc * prod_dim1] = sum;
522 for (k = 1; k <= i__1; ++k) {
524 for (i__ = 1; i__ <= 5; ++i__) {
526 0.5 * prod[k + i__ * prod_dim1] * wvec[k + i__ * wvec_dim1];
529 den[0] = den[0] - par[0] - sum;
530 tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 1)] +
531 prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1];
532 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + (wvec_dim1 << 2)] +
533 prod[k + (prod_dim1 << 2)] * wvec[k + (wvec_dim1 << 1)];
534 tempc = prod[k + prod_dim1 * 3] * wvec[k + wvec_dim1 * 5] +
535 prod[k + prod_dim1 * 5] * wvec[k + wvec_dim1 * 3];
536 den[1] = den[1] - tempa - 0.5 * (tempb + tempc);
537 den[5] -= 0.5 * (tempb - tempc);
538 tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 3] +
539 prod[k + prod_dim1 * 3] * wvec[k + wvec_dim1];
540 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 5] +
541 prod[k + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 1)];
542 tempc = prod[k + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 2)] +
543 prod[k + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 3];
544 den[2] = den[2] - tempa - 0.5 * (tempb - tempc);
545 den[6] -= 0.5 * (tempb + tempc);
546 tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 2)] +
547 prod[k + (prod_dim1 << 2)] * wvec[k + wvec_dim1];
548 den[3] = den[3] - tempa - par[1] + par[2];
549 tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 5] +
550 prod[k + prod_dim1 * 5] * wvec[k + wvec_dim1];
551 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 3] +
552 prod[k + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 1)];
553 den[4] = den[4] - tempa - 0.5 * tempb;
554 den[7] = den[7] - par[3] + par[4];
555 tempa = prod[k + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 5] +
556 prod[k + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 2)];
557 den[8] -= 0.5 * tempa;
561 for (i__ = 1; i__ <= 5; ++i__) {
563 d__1 = prod[*knew + i__ * prod_dim1];
564 par[i__ - 1] = 0.5 * (d__1 * d__1);
567 denex[0] = alpha * den[0] + par[0] + sum;
568 tempa = 2.0 * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 1)];
569 tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + (prod_dim1 << 2)];
570 tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + prod_dim1 * 5];
571 denex[1] = alpha * den[1] + tempa + tempb + tempc;
572 denex[5] = alpha * den[5] + tempb - tempc;
573 tempa = 2.0 * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 3];
574 tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + prod_dim1 * 5];
575 tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + (prod_dim1 << 2)];
576 denex[2] = alpha * den[2] + tempa + tempb - tempc;
577 denex[6] = alpha * den[6] + tempb + tempc;
578 tempa = 2.0 * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 2)];
579 denex[3] = alpha * den[3] + tempa + par[1] - par[2];
580 tempa = 2.0 * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 5];
581 denex[4] = alpha * den[4] + tempa +
582 prod[*knew + (prod_dim1 << 1)] * prod[*knew + prod_dim1 * 3];
583 denex[7] = alpha * den[7] + par[3] - par[4];
584 denex[8] = alpha * den[8] +
585 prod[*knew + (prod_dim1 << 2)] * prod[*knew + prod_dim1 * 5];
587 sum = denex[0] + denex[1] + denex[3] + denex[5] + denex[7];
588 denold = denmax = sum;
591 temp = twopi / (double)(iu + 1);
594 for (i__ = 1; i__ <= i__1; ++i__) {
595 angle = (double)i__ * temp;
598 for (j = 4; j <= 8; j += 2) {
599 par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
600 par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
604 for (j = 1; j <= 9; ++j)
605 sum += denex[j - 1] * par[j - 1];
606 if (fabs(sum) > fabs(denmax)) {
610 }
else if (i__ == isave + 1) {
619 if (tempa != tempb) {
622 step = 0.5 * (tempa - tempb) / (tempa + tempb);
624 angle = temp * ((double)isave + step);
629 for (j = 4; j <= 8; j += 2) {
630 par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
631 par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
635 for (j = 1; j <= 9; ++j) {
636 *beta += den[j - 1] * par[j - 1];
637 denmax += denex[j - 1] * par[j - 1];
640 for (k = 1; k <= i__1; ++k) {
642 for (j = 1; j <= 5; ++j)
643 vlag[k] += prod[k + j * prod_dim1] * par[j - 1];
646 dd = tempa = tempb = 0;
648 for (i__ = 1; i__ <= i__1; ++i__) {
649 d__[i__] = par[1] * d__[i__] + par[2] * s[i__];
650 w[i__] = xopt[i__] + d__[i__];
654 tempa += d__[i__] * w[i__];
655 tempb += w[i__] * w[i__];
660 densav = fmax(densav, denold);
661 if (fabs(denmax) <= fabs(densav) * 1.1)
667 for (i__ = 1; i__ <= i__1; ++i__) {
668 temp = tempa * xopt[i__] + tempb * d__[i__] - vlag[npt + i__];
669 s[i__] = tau * bmat[*knew + i__ * bmat_dim1] + alpha * temp;
672 for (k = 1; k <= i__1; ++k) {
675 for (j = 1; j <= i__2; ++j)
676 sum += xpt[k + j * xpt_dim1] * w[j];
677 temp = (tau * w[n + k] - alpha * vlag[k]) * sum;
679 for (i__ = 1; i__ <= i__2; ++i__)
680 s[i__] += temp * xpt[k + i__ * xpt_dim1];
685 for (i__ = 1; i__ <= i__2; ++i__) {
689 ds += d__[i__] * s[i__];
691 ssden = dd * ss - ds * ds;
692 if (ssden >= dd * 1e-8 * ss)
697 for (k = 1; k <= i__2; ++k) {
699 for (j = 1; j <= 5; ++j)
700 w[k] += wvec[k + j * wvec_dim1] * par[j - 1];
705 void trsapp(
long n,
long npt,
double *xopt,
double *xpt,
double *gq,
double *hq,
706 double *pq,
double *delta,
double *step,
double *d__,
double *g,
707 double *hd,
double *hs,
double *crvmin) {
722 long xpt_dim1, xpt_offset, i__1, i__2, i__, j, k, ih, iu, iterc, isave,
724 double d__1, d__2, dd, cf, dg, gg, ds, sg, ss, dhd, dhs, cth, sgk, shs, sth,
725 qadd, qbeg, qred, qmin, temp, qsav, qnew, ggbeg, alpha, angle, reduc,
726 ggsav, delsq, tempa, tempb, bstep, ratio, twopi, angtest;
729 tempa = tempb = shs = sg = bstep = ggbeg = gg = qred = dd = 0.0;
731 xpt_offset = 1 + xpt_dim1;
744 delsq = *delta * *delta;
749 for (i__ = 1; i__ <= i__1; ++i__)
750 d__[i__] = xopt[i__];
756 for (i__ = 1; i__ <= i__1; ++i__) {
759 g[i__] = gq[i__] + hd[i__];
776 bstep = temp / (ds + sqrt(ds * ds + dd * temp));
781 for (j = 1; j <= i__1; ++j)
782 dhd += d__[j] * hd[j];
789 *crvmin = fmin(*crvmin, temp);
791 d__1 = alpha, d__2 = gg / dhd;
792 alpha = fmin(d__1, d__2);
794 qadd = alpha * (gg - 0.5 * alpha * dhd);
800 for (i__ = 1; i__ <= i__1; ++i__) {
801 step[i__] += alpha * d__[i__];
802 hs[i__] += alpha * hd[i__];
804 d__1 = g[i__] + hs[i__];
809 if (qadd <= qred * .01 || gg <= ggbeg * 1e-4 || iterc == itermax)
814 for (i__ = 1; i__ <= i__1; ++i__) {
815 d__[i__] = temp * d__[i__] - g[i__] - hs[i__];
819 ds += d__[i__] * step[i__];
833 if (gg <= ggbeg * 1e-4)
838 for (i__ = 1; i__ <= i__1; ++i__) {
839 sg += step[i__] * g[i__];
840 shs += step[i__] * hs[i__];
843 angtest = sgk / sqrt(gg * delsq);
849 temp = sqrt(delsq * gg - sgk * sgk);
850 tempa = delsq / temp;
853 for (i__ = 1; i__ <= i__1; ++i__)
854 d__[i__] = tempa * (g[i__] + hs[i__]) - tempb * step[i__];
859 for (i__ = 1; i__ <= i__1; ++i__) {
860 dg += d__[i__] * g[i__];
861 dhd += hd[i__] * d__[i__];
862 dhs += hd[i__] * step[i__];
865 cf = 0.5 * (shs - dhd);
870 temp = twopi / (double)(iu + 1);
872 for (i__ = 1; i__ <= i__1; ++i__) {
873 angle = (double)i__ * temp;
876 qnew = (sg + cf * cth) * cth + (dg + dhs * cth) * sth;
881 }
else if (i__ == isave + 1)
885 if ((
double)isave == 0)
890 if (tempa != tempb) {
893 angle = 0.5 * (tempa - tempb) / (tempa + tempb);
895 angle = temp * ((double)isave + angle);
899 reduc = qbeg - (sg + cf * cth) * cth - (dg + dhs * cth) * sth;
902 for (i__ = 1; i__ <= i__1; ++i__) {
903 step[i__] = cth * step[i__] + sth * d__[i__];
904 hs[i__] = cth * hs[i__] + sth * hd[i__];
906 d__1 = g[i__] + hs[i__];
910 ratio = reduc / qred;
911 if (iterc < itermax && ratio > .01)
921 for (i__ = 1; i__ <= i__1; ++i__)
924 for (k = 1; k <= i__1; ++k) {
927 for (j = 1; j <= i__2; ++j)
928 temp += xpt[k + j * xpt_dim1] * d__[j];
931 for (i__ = 1; i__ <= i__2; ++i__)
932 hd[i__] += temp * xpt[k + i__ * xpt_dim1];
936 for (j = 1; j <= i__2; ++j) {
938 for (i__ = 1; i__ <= i__1; ++i__) {
941 hd[j] += hq[ih] * d__[i__];
942 hd[i__] += hq[ih] * d__[j];
952 void update(
long n,
long npt,
double *bmat,
double *zmat,
long *idz,
long *ndim,
953 double *vlag,
double *beta,
long *knew,
double *w) {
961 long bmat_dim1, bmat_offset, zmat_dim1, zmat_offset, i__1, i__2, i__, j, ja,
962 jb, jl, jp, nptm, iflag;
963 double d__1, d__2, tau, temp, scala, scalb, alpha, denom, tempa, tempb,
969 zmat_offset = 1 + zmat_dim1;
972 bmat_offset = 1 + bmat_dim1;
981 for (j = 2; j <= i__1; ++j) {
984 }
else if (zmat[*knew + j * zmat_dim1] != 0) {
986 d__1 = zmat[*knew + jl * zmat_dim1];
988 d__2 = zmat[*knew + j * zmat_dim1];
989 temp = sqrt(d__1 * d__1 + d__2 * d__2);
990 tempa = zmat[*knew + jl * zmat_dim1] / temp;
991 tempb = zmat[*knew + j * zmat_dim1] / temp;
993 for (i__ = 1; i__ <= i__2; ++i__) {
994 temp = tempa * zmat[i__ + jl * zmat_dim1] +
995 tempb * zmat[i__ + j * zmat_dim1];
996 zmat[i__ + j * zmat_dim1] = tempa * zmat[i__ + j * zmat_dim1] -
997 tempb * zmat[i__ + jl * zmat_dim1];
998 zmat[i__ + jl * zmat_dim1] = temp;
1000 zmat[*knew + j * zmat_dim1] = 0;
1005 tempa = zmat[*knew + zmat_dim1];
1009 tempb = zmat[*knew + jl * zmat_dim1];
1011 for (i__ = 1; i__ <= i__1; ++i__) {
1012 w[i__] = tempa * zmat[i__ + zmat_dim1];
1014 w[i__] += tempb * zmat[i__ + jl * zmat_dim1];
1019 denom = alpha * *beta + tausq;
1027 temp = sqrt((fabs(denom)));
1028 tempb = tempa / temp;
1031 for (i__ = 1; i__ <= i__1; ++i__)
1032 zmat[i__ + zmat_dim1] =
1033 tempa * zmat[i__ + zmat_dim1] - tempb * vlag[i__];
1034 if (*idz == 1 && temp < 0)
1036 if (*idz >= 2 && temp >= 0)
1045 temp = zmat[*knew + jb * zmat_dim1] / denom;
1046 tempa = temp * *beta;
1048 temp = zmat[*knew + ja * zmat_dim1];
1049 scala = 1.0 / sqrt(fabs(*beta) * temp * temp + tausq);
1050 scalb = scala * sqrt((fabs(denom)));
1052 for (i__ = 1; i__ <= i__1; ++i__) {
1053 zmat[i__ + ja * zmat_dim1] =
1054 scala * (tau * zmat[i__ + ja * zmat_dim1] - temp * vlag[i__]);
1055 zmat[i__ + jb * zmat_dim1] =
1056 scalb * (zmat[i__ + jb * zmat_dim1] - tempa * w[i__] -
1071 for (i__ = 1; i__ <= i__1; ++i__) {
1072 temp = zmat[i__ + zmat_dim1];
1073 zmat[i__ + zmat_dim1] = zmat[i__ + *idz * zmat_dim1];
1074 zmat[i__ + *idz * zmat_dim1] = temp;
1079 for (j = 1; j <= i__1; ++j) {
1081 w[jp] = bmat[*knew + j * bmat_dim1];
1082 tempa = (alpha * vlag[jp] - tau * w[jp]) / denom;
1083 tempb = (-(*beta) * w[jp] - tau * vlag[jp]) / denom;
1085 for (i__ = 1; i__ <= i__2; ++i__) {
1086 bmat[i__ + j * bmat_dim1] =
1087 bmat[i__ + j * bmat_dim1] + tempa * vlag[i__] + tempb * w[i__];
1089 bmat[jp + (i__ - npt) * bmat_dim1] = bmat[i__ + j * bmat_dim1];
1096 template <
class Function>
1097 double newuob(
long n,
long npt,
double *x,
double rhobeg,
double rhoend,
1098 long maxfun,
double *xbase,
double *xopt,
double *xnew,
1099 double *xpt,
double *fval,
double *gq,
double *hq,
double *pq,
1100 double *bmat,
double *zmat,
long *ndim,
double *d__,
double *vlag,
1101 double *w, Function &&
function) {
1130 long xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1, zmat_offset,
1131 i__1, i__2, i__3, i__, j, k, ih, nf, nh, ip, jp, np, nfm, idz, ipt, jpt,
1132 nfmm, knew, kopt, nptm, ksave, nfsav, itemp, ktemp, itest, nftest;
1133 double d__1, d__2, d__3, f, dx, dsq, rho, sum, fbeg, diff, beta, gisq, temp,
1134 suma, sumb, fopt, bsum, gqsq, xipt, xjpt, sumz, diffa, diffb, diffc,
1135 hdiag, alpha, delta = 0.0, recip, reciq, fsave, dnorm, ratio, dstep,
1136 vquad, tempq, rhosq, detrat, crvmin = 0.0, distsq, xoptsq;
1139 diffc = ratio = dnorm = diffa = diffb = xoptsq = f = 0.0;
1141 rho = fbeg = fopt = xjpt = xipt = 0.0;
1142 itest = ipt = jpt = 0;
1143 alpha = dstep = 0.0;
1145 zmat_offset = 1 + zmat_dim1;
1146 zmat -= zmat_offset;
1148 xpt_offset = 1 + xpt_dim1;
1159 bmat_offset = 1 + bmat_dim1;
1160 bmat -= bmat_offset;
1168 nftest = (maxfun > 1) ? maxfun : 1;
1171 for (j = 1; j <= i__1; ++j) {
1174 for (k = 1; k <= i__2; ++k)
1175 xpt[k + j * xpt_dim1] = 0;
1177 for (i__ = 1; i__ <= i__2; ++i__)
1178 bmat[i__ + j * bmat_dim1] = 0;
1181 for (ih = 1; ih <= i__2; ++ih)
1184 for (k = 1; k <= i__2; ++k) {
1187 for (j = 1; j <= i__1; ++j)
1188 zmat[k + j * zmat_dim1] = 0;
1194 rhosq = rhobeg * rhobeg;
1195 recip = 1.0 / rhosq;
1196 reciq = sqrt(.5) / rhosq;
1202 if (nfm <= n << 1) {
1203 if (nfm >= 1 && nfm <= n) {
1204 xpt[nf + nfm * xpt_dim1] = rhobeg;
1205 }
else if (nfm > n) {
1206 xpt[nf + nfmm * xpt_dim1] = -(rhobeg);
1209 itemp = (nfmm - 1) / n;
1210 jpt = nfm - itemp * n - n;
1218 if (fval[ipt + np] < fval[ipt + 1])
1221 if (fval[jpt + np] < fval[jpt + 1])
1223 xpt[nf + ipt * xpt_dim1] = xipt;
1224 xpt[nf + jpt * xpt_dim1] = xjpt;
1230 for (j = 1; j <= i__1; ++j)
1231 x[j] = xpt[nf + j * xpt_dim1] + xbase[j];
1238 }
else if (f < fopt) {
1244 if (nfm <= n << 1) {
1245 if (nfm >= 1 && nfm <= n) {
1246 gq[nfm] = (f - fbeg) / rhobeg;
1248 bmat[nfm * bmat_dim1 + 1] = -1.0 / rhobeg;
1249 bmat[nf + nfm * bmat_dim1] = 1.0 / rhobeg;
1250 bmat[npt + nfm + nfm * bmat_dim1] = -.5 * rhosq;
1252 }
else if (nfm > n) {
1253 bmat[nf - n + nfmm * bmat_dim1] = .5 / rhobeg;
1254 bmat[nf + nfmm * bmat_dim1] = -.5 / rhobeg;
1255 zmat[nfmm * zmat_dim1 + 1] = -reciq - reciq;
1256 zmat[nf - n + nfmm * zmat_dim1] = reciq;
1257 zmat[nf + nfmm * zmat_dim1] = reciq;
1258 ih = nfmm * (nfmm + 1) / 2;
1259 temp = (fbeg - f) / rhobeg;
1260 hq[ih] = (gq[nfmm] - temp) / rhobeg;
1261 gq[nfmm] = .5 * (gq[nfmm] + temp);
1266 ih = ipt * (ipt - 1) / 2 + jpt;
1271 zmat[nfmm * zmat_dim1 + 1] = recip;
1272 zmat[nf + nfmm * zmat_dim1] = recip;
1273 zmat[ipt + 1 + nfmm * zmat_dim1] = -recip;
1274 zmat[jpt + 1 + nfmm * zmat_dim1] = -recip;
1275 hq[ih] = (fbeg - fval[ipt + 1] - fval[jpt + 1] + f) / (xipt * xjpt);
1289 for (i__ = 1; i__ <= i__1; ++i__) {
1290 xopt[i__] = xpt[kopt + i__ * xpt_dim1];
1293 xoptsq += d__1 * d__1;
1302 trsapp(n, npt, &xopt[1], &xpt[xpt_offset], &gq[1], &hq[1], &pq[1], &delta,
1303 &d__[1], &w[1], &w[np], &w[np + n], &w[np + (n << 1)], &crvmin);
1306 for (i__ = 1; i__ <= i__1; ++i__) {
1312 d__1 = delta, d__2 = sqrt(dsq);
1313 dnorm = fmin(d__1, d__2);
1314 if (dnorm < .5 * rho) {
1316 delta = 0.1 * delta;
1318 if (delta <= rho * 1.5)
1320 if (nf <= nfsav + 2)
1322 temp = crvmin * .125 * rho * rho;
1324 d__1 = fmax(diffa, diffb);
1325 if (temp <= fmax(d__1, diffc))
1332 if (dsq <= xoptsq * .001) {
1333 tempq = xoptsq * .25;
1335 for (k = 1; k <= i__1; ++k) {
1338 for (i__ = 1; i__ <= i__2; ++i__)
1339 sum += xpt[k + i__ * xpt_dim1] * xopt[i__];
1344 for (i__ = 1; i__ <= i__2; ++i__) {
1345 gq[i__] += temp * xpt[k + i__ * xpt_dim1];
1346 xpt[k + i__ * xpt_dim1] -= .5 * xopt[i__];
1347 vlag[i__] = bmat[k + i__ * bmat_dim1];
1348 w[i__] = sum * xpt[k + i__ * xpt_dim1] + tempq * xopt[i__];
1351 for (j = 1; j <= i__3; ++j)
1352 bmat[ip + j * bmat_dim1] = bmat[ip + j * bmat_dim1] +
1360 for (k = 1; k <= i__3; ++k) {
1363 for (i__ = 1; i__ <= i__2; ++i__) {
1364 sumz += zmat[i__ + k * zmat_dim1];
1365 w[i__] = w[npt + i__] * zmat[i__ + k * zmat_dim1];
1368 for (j = 1; j <= i__2; ++j) {
1369 sum = tempq * sumz * xopt[j];
1371 for (i__ = 1; i__ <= i__1; ++i__)
1372 sum += w[i__] * xpt[i__ + j * xpt_dim1];
1377 for (i__ = 1; i__ <= i__1; ++i__)
1378 bmat[i__ + j * bmat_dim1] +=
1379 sum * zmat[i__ + k * zmat_dim1];
1382 for (i__ = 1; i__ <= i__1; ++i__) {
1388 for (j = 1; j <= i__2; ++j)
1389 bmat[ip + j * bmat_dim1] += temp * vlag[j];
1397 for (j = 1; j <= i__2; ++j) {
1400 for (k = 1; k <= i__1; ++k) {
1401 w[j] += pq[k] * xpt[k + j * xpt_dim1];
1402 xpt[k + j * xpt_dim1] -= .5 * xopt[j];
1405 for (i__ = 1; i__ <= i__1; ++i__) {
1408 gq[j] += hq[ih] * xopt[i__];
1409 gq[i__] += hq[ih] * xopt[j];
1410 hq[ih] = hq[ih] + w[i__] * xopt[j] + xopt[i__] * w[j];
1411 bmat[npt + i__ + j * bmat_dim1] =
1412 bmat[npt + j + i__ * bmat_dim1];
1416 for (j = 1; j <= i__1; ++j) {
1417 xbase[j] += xopt[j];
1426 biglag(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset],
1427 &zmat[zmat_offset], &idz, ndim, &knew, &dstep, &d__[1], &alpha,
1428 &vlag[1], &vlag[npt + 1], &w[1], &w[np], &w[np + n],
1429 std::forward<Function>(
function));
1434 for (k = 1; k <= i__1; ++k) {
1439 for (j = 1; j <= i__2; ++j) {
1440 suma += xpt[k + j * xpt_dim1] * d__[j];
1441 sumb += xpt[k + j * xpt_dim1] * xopt[j];
1442 sum += bmat[k + j * bmat_dim1] * d__[j];
1444 w[k] = suma * (.5 * suma + sumb);
1449 for (k = 1; k <= i__1; ++k) {
1452 for (i__ = 1; i__ <= i__2; ++i__)
1453 sum += zmat[i__ + k * zmat_dim1] * w[i__];
1460 for (i__ = 1; i__ <= i__2; ++i__)
1461 vlag[i__] += sum * zmat[i__ + k * zmat_dim1];
1466 for (j = 1; j <= i__2; ++j) {
1469 for (i__ = 1; i__ <= i__1; ++i__)
1470 sum += w[i__] * bmat[i__ + j * bmat_dim1];
1471 bsum += sum * d__[j];
1474 for (k = 1; k <= i__1; ++k)
1475 sum += bmat[jp + k * bmat_dim1] * d__[k];
1477 bsum += sum * d__[j];
1478 dx += d__[j] * xopt[j];
1480 beta = dx * dx + dsq * (xoptsq + dx + dx + .5 * dsq) + beta - bsum;
1488 temp = 1.0 + alpha * beta / (d__1 * d__1);
1489 if (fabs(temp) <= .8) {
1490 bigden(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset],
1491 &zmat[zmat_offset], &idz, ndim, &kopt, &knew, &d__[1], &w[1],
1492 &vlag[1], &beta, &xnew[1], &w[*ndim + 1], &w[*ndim * 6 + 1]);
1498 for (i__ = 1; i__ <= i__2; ++i__) {
1499 xnew[i__] = xopt[i__] + d__[i__];
1500 x[i__] = xbase[i__] + xnew[i__];
1506 DEBUG_LOG(
"Return from NEWUOA because CALFUN has been called MAXFUN " 1510 f =
function(n, &x[1]);
1519 for (j = 1; j <= i__2; ++j) {
1520 vquad += d__[j] * gq[j];
1522 for (i__ = 1; i__ <= i__1; ++i__) {
1524 temp = d__[i__] * xnew[j] + d__[j] * xopt[i__];
1527 vquad += temp * hq[ih];
1531 for (k = 1; k <= i__1; ++k)
1532 vquad += pq[k] * w[k];
1533 diff = f - fopt - vquad;
1547 for (i__ = 1; i__ <= i__1; ++i__) {
1548 xopt[i__] = xnew[i__];
1551 xoptsq += d__1 * d__1;
1559 DEBUG_LOG(
"Return from NEWUOA because a trust region step has failed " 1563 ratio = (f - fsave) / vquad;
1566 }
else if (ratio <= .7) {
1569 delta = fmax(d__1, dnorm);
1572 d__1 = .5 * delta, d__2 = dnorm + dnorm;
1573 delta = fmax(d__1, d__2);
1575 if (delta <= rho * 1.5)
1582 d__1 = fmax(d__2, rho);
1583 rhosq = d__1 * d__1;
1591 for (k = 1; k <= i__1; ++k) {
1594 for (j = 1; j <= i__2; ++j) {
1599 d__1 = zmat[k + j * zmat_dim1];
1600 hdiag += temp * (d__1 * d__1);
1604 temp = (d__1 = beta * hdiag + d__2 * d__2, fabs(d__1));
1607 for (j = 1; j <= i__2; ++j) {
1609 d__1 = xpt[k + j * xpt_dim1] - xopt[j];
1610 distsq += d__1 * d__1;
1612 if (distsq > rhosq) {
1614 d__1 = distsq / rhosq;
1615 temp *= d__1 * (d__1 * d__1);
1617 if (temp > detrat && k != ktemp) {
1628 update(n, npt, &bmat[bmat_offset], &zmat[zmat_offset], &idz, ndim, &vlag[1],
1629 &beta, &knew, &w[1]);
1633 for (i__ = 1; i__ <= i__1; ++i__) {
1634 temp = pq[knew] * xpt[knew + i__ * xpt_dim1];
1636 for (j = 1; j <= i__2; ++j) {
1638 hq[ih] += temp * xpt[knew + j * xpt_dim1];
1646 for (j = 1; j <= i__2; ++j) {
1647 temp = diff * zmat[knew + j * zmat_dim1];
1651 for (k = 1; k <= i__1; ++k) {
1652 pq[k] += temp * zmat[k + j * zmat_dim1];
1657 for (i__ = 1; i__ <= i__1; ++i__) {
1658 gq[i__] += diff * bmat[knew + i__ * bmat_dim1];
1661 gqsq += d__1 * d__1;
1662 xpt[knew + i__ * xpt_dim1] = xnew[i__];
1668 if (ksave == 0 && delta == rho) {
1669 if (fabs(ratio) > .01) {
1673 for (k = 1; k <= i__1; ++k)
1674 vlag[k] = fval[k] - fval[kopt];
1677 for (i__ = 1; i__ <= i__1; ++i__) {
1680 for (k = 1; k <= i__2; ++k)
1681 sum += bmat[k + i__ * bmat_dim1] * vlag[k];
1689 if (gqsq < gisq * 100.)
1693 for (i__ = 1; i__ <= i__1; ++i__)
1696 for (ih = 1; ih <= i__1; ++ih)
1699 for (j = 1; j <= i__1; ++j) {
1702 for (k = 1; k <= i__2; ++k)
1703 w[j] += vlag[k] * zmat[k + j * zmat_dim1];
1708 for (k = 1; k <= i__1; ++k) {
1711 for (j = 1; j <= i__2; ++j)
1712 pq[k] += zmat[k + j * zmat_dim1] * w[j];
1724 if (f <= fsave + 0.1 * vquad)
1732 distsq = delta * 4. * delta;
1734 for (k = 1; k <= i__2; ++k) {
1737 for (j = 1; j <= i__1; ++j) {
1739 d__1 = xpt[k + j * xpt_dim1] - xopt[j];
1751 d__2 = 0.1 * sqrt(distsq), d__3 = .5 * delta;
1752 d__1 = fmin(d__2, d__3);
1753 dstep = fmax(d__1, rho);
1754 dsq = dstep * dstep;
1759 if (fmax(delta, dnorm) > rho)
1766 ratio = rho / rhoend;
1769 else if (ratio <= 250.)
1770 rho = sqrt(ratio) * rhoend;
1773 delta = fmax(delta, rho);
1783 for (i__ = 1; i__ <= i__2; ++i__)
1784 x[i__] = xbase[i__] + xopt[i__];
1790 template <
class Function>
1791 double newuoa_impl(Function &&
function,
long n,
long npt,
double *x,
1792 double rhobeg,
double rhoend,
long maxfun,
double *w) {
1821 long id, np, iw, igq, ihq, ixb, ifv, ipq, ivl, ixn, ixo, ixp, ndim, nptm,
1830 if (npt < n + 2 || npt > (n + 2) * np / 2) {
1831 DEBUG_LOG(
"NEWUOA: npt is not in the required interval.\n");
1839 ifv = ixp + n * npt;
1842 ipq = ihq + n * np / 2;
1844 izmat = ibmat + ndim * n;
1845 id = izmat + npt * nptm;
1852 return newuob(n, npt, &x[1], rhobeg, rhoend, maxfun, &w[ixb], &w[ixo],
1853 &w[ixn], &w[ixp], &w[ifv], &w[igq], &w[ihq], &w[ipq],
1854 &w[ibmat], &w[izmat], &ndim, &w[
id], &w[ivl], &w[iw],
1855 std::forward<Function>(
function));
1881 template <
typename Function>
1882 inline double newuoa(Function &&
function,
long n,
long npt,
double *x,
1883 double rhobeg,
double rhoend,
long maxfun,
double *w) {
1884 return newuoa_detail::newuoa_impl(std::forward<Function>(
function), n, npt,
1885 x, rhobeg, rhoend, maxfun, w);
1890 template <
typename Derived>
1894 std::is_same<typename Derived::Scalar, double>::value,
1895 "NEWUOA operates only on doubles, and you passed a different type.");
1896 static_assert(Derived::IsVectorAtCompileTime,
"NEWUOA must be passed x " 1897 "which is known to be a " 1898 "vector at compile time.");
1900 "Vector passed to NEWUOA must be fixed-size at compile " 1903 template <
typename Derived>
1905 return static_cast<long>(2 * Derived::SizeAtCompileTime + 1);
1910 template <
typename Function,
typename Derived>
1912 std::pair<double, double> rho,
long maxfun,
1914 detail::checkStaticAssertions(x);
1916 double rhoBeg, rhoEnd;
1917 std::tie(rhoBeg, rhoEnd) = rho;
1918 if (rhoEnd > rhoBeg) {
1919 std::swap(rhoBeg, rhoEnd);
1921 const auto n = Derived::SizeAtCompileTime;
1922 auto workingSpaceNeeded = (npt + 13) * (npt + n) + 3 * n * (n + 3) / 2;
1923 Eigen::VectorXd workingSpace(workingSpaceNeeded);
1925 return newuoa(std::forward<Function>(f), n, npt, x.derived().data(), rhoBeg,
1926 rhoEnd, maxfun, workingSpace.data());
1931 template <
typename Function,
typename Derived>
1933 std::pair<double, double> rho,
long maxfun,
1935 detail::checkStaticAssertions(x);
1936 return ei_newuoa(detail::computeReasonableNPT(x), x, rho, maxfun,
1937 std::forward<Function>(f));
1942 template <
typename Function,
typename Derived>
1944 std::pair<double, double> rho,
long maxfun,
1946 detail::checkStaticAssertions(x);
1949 Vec xCopy = Vec::Zero();
1950 auto wrappedFunc = [&f, &xCopy](
long n,
const double *x) {
1951 assert(n == Derived::SizeAtCompileTime &&
1952 "Should always be getting back the same size");
1956 xCopy = Vec::Map(x);
1957 return std::forward<Function>(f)(const_cast<const Vec &>(xCopy));
1959 return ei_newuoa(npt, x, rho, maxfun, wrappedFunc);
1964 template <
typename Function,
typename Derived>
1966 std::pair<double, double> rho,
long maxfun,
1968 detail::checkStaticAssertions(x);
1970 std::forward<Function>(f));
1973 #endif // INCLUDED_newuoa_h_GUID_F9E56CF3_7B12_41A0_4A09_E2A02B48FAC1 double ei_newuoa(long npt, Eigen::MatrixBase< Derived > &x, std::pair< double, double > rho, long maxfun, Function &&f)
Friendly wrapper around newuoa: takes a vector for x.
Definition: newuoa.h:1911
double ei_newuoa_wrapped(long npt, Eigen::MatrixBase< Derived > &x, std::pair< double, double > rho, long maxfun, Function &&f)
Friendlier wrapper around newuoa: takes a vector for x, and the function takes a reference to const v...
Definition: newuoa.h:1943
Definition: newuoa.h:1888
void checkStaticAssertions(Eigen::MatrixBase< Derived > &)
Checks shared static assertions about vectors to be optimized by NEWUOA.
Definition: newuoa.h:1891
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.
Definition: Constants.h:21
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48