1 /* Copyright (c) 2004 M. J. D. Powell (mjdp@cam.ac.uk)
2 * Copyright (c) 2007-2008 Massachusetts Institute of Technology
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 /* NEWUOA derivative-free optimization algorithm by M. J. D. Powell.
25 Original Fortran code by Powell (2004). Converted via f2c, cleaned up,
26 and incorporated into NLopt by S. G. Johnson (2008). See README. */
35 #define min(a,b) ((a) <= (b) ? (a) : (b))
36 #define max(a,b) ((a) >= (b) ? (a) : (b))
38 /*************************************************************************/
43 double *xpt, *pq, *hq, *gq, *xopt;
48 static double quad_model(int n, const double *x, double *grad, void *data)
50 quad_model_data *d = (quad_model_data *) data;
51 const double *xpt = d->xpt, *pq = d->pq, *hq = d->hq, *gq = d->gq, *xopt = d->xopt;
57 /* first, set hd to be Hessian matrix times x */
58 memset(hd, 0, sizeof(double) * n);
59 /* implicit Hessian terms (a sum of outer products of xpt vectors) */
60 for (k = 0; k < npt; ++k) {
62 for (j = 0; j < n; ++j)
63 temp += xpt[k + j * npt] * (xopt[j] + x[j]);
65 for (i = 0; i < n; ++i)
66 hd[i] += temp * xpt[k + i * npt];
68 /* explicit Hessian terms (stored as compressed lower triangle hq) */
70 for (j = 0; j < n; ++j) {
71 for (i = 0; i < j; ++i) {
72 hd[j] += hq[k] * (xopt[i] + x[i]);
73 hd[i] += hq[k] * (xopt[j] + x[j]);
76 hd[j] += hq[k++] * (xopt[j] + x[j]);
79 for (i = 0; i < n; ++i) {
80 val += (gq[i] + 0.5 * hd[i]) * (xopt[i] + x[i]);
81 if (grad) grad[i] = gq[i] + hd[i];
87 /* constraint function to enforce |x|^2 <= rho*rho */
88 static double rho_constraint(int n, const double *x, double *grad, void *data)
90 double rho = *((double *) data);
91 double val = - rho*rho;
93 for (i = 0; i < n; ++i)
95 if (grad) for (i = 0; i < n; ++i) grad[i] = 2*x[i];
99 static void trsapp_(int *n, int *npt, double *xopt,
100 double *xpt, double *gq, double *hq, double *pq,
101 double *delta, double *step, double *d__, double *g,
102 double *hd, double *hs, double *crvmin)
104 /* System generated locals */
105 int xpt_dim1, xpt_offset, i__1, i__2;
108 /* Local variables */
110 double dd, cf, dg, gg;
114 double ss, dhd, dhs, cth, sgk, shs, sth, qadd, half, qbeg, qred, qmin,
115 temp, qsav, qnew, zero, ggbeg, alpha, angle, reduc;
117 double ggsav, delsq, tempa, tempb;
119 double bstep, ratio, twopi;
125 /* N is the number of variables of a quadratic objective function, Q say. */
126 /* The arguments NPT, XOPT, XPT, GQ, HQ and PQ have their usual meanings, */
127 /* in order to define the current quadratic model Q. */
128 /* DELTA is the trust region radius, and has to be positive. */
129 /* STEP will be set to the calculated trial step. */
130 /* The arrays D, G, HD and HS will be used for working space. */
131 /* CRVMIN will be set to the least curvature of H along the conjugate */
132 /* directions that occur, except that it is set to zero if STEP goes */
133 /* all the way to the trust region boundary. */
135 /* The calculation of STEP begins with the truncated conjugate gradient */
136 /* method. If the boundary of the trust region is reached, then further */
137 /* changes to STEP may be made, each one being in the 2D space spanned */
138 /* by the current STEP and the corresponding gradient of Q. Thus STEP */
139 /* should provide a substantial reduction to Q within the trust region. */
141 /* Initialization, which includes setting HD to H times XOPT. */
143 /* Parameter adjustments */
145 xpt_offset = 1 + xpt_dim1;
160 twopi = atan(1.) * 8.;
161 delsq = *delta * *delta;
166 for (i__ = 1; i__ <= i__1; ++i__) {
168 d__[i__] = xopt[i__];
172 /* Prepare for the first line search. */
178 for (i__ = 1; i__ <= i__1; ++i__) {
181 g[i__] = gq[i__] + hd[i__];
184 /* Computing 2nd power */
197 /* Calculate the step to the trust region boundary and the product HD. */
202 bstep = temp / (ds + sqrt(ds * ds + dd * temp));
207 for (j = 1; j <= i__1; ++j) {
209 dhd += d__[j] * hd[j];
212 /* Update CRVMIN and set the step-length ALPHA. */
220 *crvmin = min(*crvmin,temp);
222 d__1 = alpha, d__2 = gg / dhd;
223 alpha = min(d__1,d__2);
225 qadd = alpha * (gg - half * alpha * dhd);
228 /* Update STEP and HS. */
233 for (i__ = 1; i__ <= i__1; ++i__) {
234 step[i__] += alpha * d__[i__];
235 hs[i__] += alpha * hd[i__];
237 /* Computing 2nd power */
238 d__1 = g[i__] + hs[i__];
242 /* Begin another conjugate direction iteration if required. */
245 if (qadd <= qred * .01) {
248 if (gg <= ggbeg * 1e-4) {
251 if (iterc == itermax) {
259 for (i__ = 1; i__ <= i__1; ++i__) {
260 d__[i__] = temp * d__[i__] - g[i__] - hs[i__];
261 /* Computing 2nd power */
264 ds += d__[i__] * step[i__];
266 /* Computing 2nd power */
280 /* Test whether an alternative iteration is required. */
283 if (gg <= ggbeg * 1e-4) {
289 for (i__ = 1; i__ <= i__1; ++i__) {
290 sg += step[i__] * g[i__];
292 shs += step[i__] * hs[i__];
295 angtest = sgk / sqrt(gg * delsq);
296 if (angtest <= -.99) {
300 /* Begin the alternative iteration by calculating D and HD and some */
301 /* scalar products. */
304 temp = sqrt(delsq * gg - sgk * sgk);
305 tempa = delsq / temp;
308 for (i__ = 1; i__ <= i__1; ++i__) {
310 d__[i__] = tempa * (g[i__] + hs[i__]) - tempb * step[i__];
318 for (i__ = 1; i__ <= i__1; ++i__) {
319 dg += d__[i__] * g[i__];
320 dhd += hd[i__] * d__[i__];
322 dhs += hd[i__] * step[i__];
325 /* Seek the value of the angle that minimizes Q. */
327 cf = half * (shs - dhd);
333 temp = twopi / (double) (iu + 1);
335 for (i__ = 1; i__ <= i__1; ++i__) {
336 angle = (double) i__ * temp;
339 qnew = (sg + cf * cth) * cth + (dg + dhs * cth) * sth;
344 } else if (i__ == isave + 1) {
350 if ((double) isave == zero) {
357 if (tempa != tempb) {
360 angle = half * (tempa - tempb) / (tempa + tempb);
362 angle = temp * ((double) isave + angle);
364 /* Calculate the new STEP and HS. Then test for convergence. */
368 reduc = qbeg - (sg + cf * cth) * cth - (dg + dhs * cth) * sth;
371 for (i__ = 1; i__ <= i__1; ++i__) {
372 step[i__] = cth * step[i__] + sth * d__[i__];
373 hs[i__] = cth * hs[i__] + sth * hd[i__];
375 /* Computing 2nd power */
376 d__1 = g[i__] + hs[i__];
380 ratio = reduc / qred;
381 if (iterc < itermax && ratio > .01) {
386 double *lb, *ub, minf, crv;
389 qmd.xpt = &xpt[1 + 1 * xpt_dim1];
398 for (j = 0; j < *n; ++j) lb[j] = -(ub[j] = *delta);
399 memset(&d__[1], 0, sizeof(double) * *n);
400 nlopt_minimize_constrained(NLOPT_LD_MMA, *n, quad_model, &qmd,
401 1, rho_constraint, delta, sizeof(double),
402 lb, ub, &d__[1], &minf, -HUGE_VAL,
403 0., 0., 1e-8, 0, 1000, 0.);
404 printf("trsapp = %g vs. nlopt (%d iters) = %g (delta = %g):\n",
405 quad_model(*n, &step[1], 0, &qmd), qmd.iter,minf,*delta);
406 for (j = 1; j <= *n; ++j)
407 printf(" xopt[%d] = %g, step[%d] = %g vs. %g\n", j, xopt[j], j, step[j], d__[j]);
408 printf("|d|^2 - delta^2 = %g, |step|^2 - delta^2 = %g\n",
409 rho_constraint(*n, &d__[1], 0, delta),
410 rho_constraint(*n, &step[1], 0, delta));
411 if (rho_constraint(*n, &d__[1], 0, delta) > -1e-6 * (*delta)*(*delta))
414 for (j = 1; j <= *n; ++j) d__[j] = step[j] - xopt[j];
415 quad_model(*n, &d__[1], &g[1], &qmd);
417 for (j = 1; j <= *n; ++j) {
418 crv += step[j] * (g[j] - gq[j]);
419 gg += step[j] * step[j];
423 printf("crvmin = %g, crv = %g\n", *crvmin, crv);
427 /* The following instructions act as a subroutine for setting the vector */
428 /* HD to the vector D multiplied by the second derivative matrix of Q. */
429 /* They are called from three different places, which are distinguished */
430 /* by the value of ITERC. */
434 for (i__ = 1; i__ <= i__1; ++i__) {
439 for (k = 1; k <= i__1; ++k) {
442 for (j = 1; j <= i__2; ++j) {
444 temp += xpt[k + j * xpt_dim1] * d__[j];
448 for (i__ = 1; i__ <= i__2; ++i__) {
450 hd[i__] += temp * xpt[k + i__ * xpt_dim1];
455 for (j = 1; j <= i__2; ++j) {
457 for (i__ = 1; i__ <= i__1; ++i__) {
460 hd[j] += hq[ih] * d__[i__];
463 hd[i__] += hq[ih] * d__[j];
469 if (iterc <= itersw) {
476 /*************************************************************************/
479 static void bigden_(int *n, int *npt, double *xopt,
480 double *xpt, double *bmat, double *zmat, int *idz,
481 int *ndim, int *kopt, int *knew, double *d__,
482 double *w, double *vlag, double *beta, double *s,
483 double *wvec, double *prod)
485 /* System generated locals */
486 int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
487 zmat_offset, wvec_dim1, wvec_offset, prod_dim1, prod_offset, i__1,
491 /* Local variables */
497 double ss, den[9], one, par[9], tau, sum, two, diff, half, temp;
501 double zero, alpha, angle, denex[9];
503 double tempa, tempb, tempc;
505 double ssden, dtest, quart, xoptd, twopi, xopts, denold, denmax,
506 densav, dstemp, sumold, sstemp, xoptsq;
509 /* N is the number of variables. */
510 /* NPT is the number of interpolation equations. */
511 /* XOPT is the best interpolation point so far. */
512 /* XPT contains the coordinates of the current interpolation points. */
513 /* BMAT provides the last N columns of H. */
514 /* ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H. */
515 /* NDIM is the first dimension of BMAT and has the value NPT+N. */
516 /* KOPT is the index of the optimal interpolation point. */
517 /* KNEW is the index of the interpolation point that is going to be moved. */
518 /* D will be set to the step from XOPT to the new point, and on entry it */
519 /* should be the D that was calculated by the last call of BIGLAG. The */
520 /* length of the initial D provides a trust region bound on the final D. */
521 /* W will be set to Wcheck for the final choice of D. */
522 /* VLAG will be set to Theta*Wcheck+e_b for the final choice of D. */
523 /* BETA will be set to the value that will occur in the updating formula */
524 /* when the KNEW-th interpolation point is moved to its new position. */
525 /* S, WVEC, PROD and the private arrays DEN, DENEX and PAR will be used */
526 /* for working space. */
528 /* D is calculated in a way that should provide a denominator with a large */
529 /* modulus in the updating formula when the KNEW-th interpolation point is */
530 /* shifted to the new position XOPT+D. */
532 /* Set some constants. */
534 /* Parameter adjustments */
536 zmat_offset = 1 + zmat_dim1;
539 xpt_offset = 1 + xpt_dim1;
543 prod_offset = 1 + prod_dim1;
546 wvec_offset = 1 + wvec_dim1;
549 bmat_offset = 1 + bmat_dim1;
562 twopi = atan(one) * 8.;
563 nptm = *npt - *n - 1;
565 /* Store the first NPT elements of the KNEW-th column of H in W(N+1) */
569 for (k = 1; k <= i__1; ++k) {
574 for (j = 1; j <= i__1; ++j) {
575 temp = zmat[*knew + j * zmat_dim1];
580 for (k = 1; k <= i__2; ++k) {
582 w[*n + k] += temp * zmat[k + j * zmat_dim1];
585 alpha = w[*n + *knew];
587 /* The initial search direction D is taken from the last call of BIGLAG, */
588 /* and the initial S is set below, usually to the direction from X_OPT */
589 /* to X_KNEW, but a different direction to an interpolation point may */
590 /* be chosen, in order to prevent S from being nearly parallel to D. */
597 for (i__ = 1; i__ <= i__2; ++i__) {
598 /* Computing 2nd power */
601 s[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
602 ds += d__[i__] * s[i__];
603 /* Computing 2nd power */
607 /* Computing 2nd power */
609 xoptsq += d__1 * d__1;
611 if (ds * ds > dd * .99 * ss) {
613 dtest = ds * ds / ss;
615 for (k = 1; k <= i__2; ++k) {
620 for (i__ = 1; i__ <= i__1; ++i__) {
621 diff = xpt[k + i__ * xpt_dim1] - xopt[i__];
622 dstemp += d__[i__] * diff;
624 sstemp += diff * diff;
626 if (dstemp * dstemp / sstemp < dtest) {
628 dtest = dstemp * dstemp / sstemp;
636 for (i__ = 1; i__ <= i__2; ++i__) {
638 s[i__] = xpt[ksav + i__ * xpt_dim1] - xopt[i__];
641 ssden = dd * ss - ds * ds;
645 /* Begin the iteration by overwriting S with a vector that has the */
646 /* required length and direction. */
650 temp = one / sqrt(ssden);
654 for (i__ = 1; i__ <= i__2; ++i__) {
655 s[i__] = temp * (dd * s[i__] - ds * d__[i__]);
656 xoptd += xopt[i__] * d__[i__];
658 xopts += xopt[i__] * s[i__];
661 /* Set the coefficients of the first two terms of BETA. */
663 tempa = half * xoptd * xoptd;
664 tempb = half * xopts * xopts;
665 den[0] = dd * (xoptsq + half * dd) + tempa + tempb;
666 den[1] = two * xoptd * dd;
667 den[2] = two * xopts * dd;
668 den[3] = tempa - tempb;
669 den[4] = xoptd * xopts;
670 for (i__ = 6; i__ <= 9; ++i__) {
675 /* Put the coefficients of Wcheck in WVEC. */
678 for (k = 1; k <= i__2; ++k) {
683 for (i__ = 1; i__ <= i__1; ++i__) {
684 tempa += xpt[k + i__ * xpt_dim1] * d__[i__];
685 tempb += xpt[k + i__ * xpt_dim1] * s[i__];
687 tempc += xpt[k + i__ * xpt_dim1] * xopt[i__];
689 wvec[k + wvec_dim1] = quart * (tempa * tempa + tempb * tempb);
690 wvec[k + (wvec_dim1 << 1)] = tempa * tempc;
691 wvec[k + wvec_dim1 * 3] = tempb * tempc;
692 wvec[k + (wvec_dim1 << 2)] = quart * (tempa * tempa - tempb * tempb);
694 wvec[k + wvec_dim1 * 5] = half * tempa * tempb;
697 for (i__ = 1; i__ <= i__2; ++i__) {
699 wvec[ip + wvec_dim1] = zero;
700 wvec[ip + (wvec_dim1 << 1)] = d__[i__];
701 wvec[ip + wvec_dim1 * 3] = s[i__];
702 wvec[ip + (wvec_dim1 << 2)] = zero;
704 wvec[ip + wvec_dim1 * 5] = zero;
707 /* Put the coefficents of THETA*Wcheck in PROD. */
709 for (jc = 1; jc <= 5; ++jc) {
711 if (jc == 2 || jc == 3) {
715 for (k = 1; k <= i__2; ++k) {
717 prod[k + jc * prod_dim1] = zero;
720 for (j = 1; j <= i__2; ++j) {
723 for (k = 1; k <= i__1; ++k) {
725 sum += zmat[k + j * zmat_dim1] * wvec[k + jc * wvec_dim1];
731 for (k = 1; k <= i__1; ++k) {
733 prod[k + jc * prod_dim1] += sum * zmat[k + j * zmat_dim1];
738 for (k = 1; k <= i__1; ++k) {
741 for (j = 1; j <= i__2; ++j) {
743 sum += bmat[k + j * bmat_dim1] * wvec[*npt + j + jc *
747 prod[k + jc * prod_dim1] += sum;
751 for (j = 1; j <= i__1; ++j) {
754 for (i__ = 1; i__ <= i__2; ++i__) {
756 sum += bmat[i__ + j * bmat_dim1] * wvec[i__ + jc * wvec_dim1];
759 prod[*npt + j + jc * prod_dim1] = sum;
763 /* Include in DEN the part of BETA that depends on THETA. */
766 for (k = 1; k <= i__1; ++k) {
768 for (i__ = 1; i__ <= 5; ++i__) {
769 par[i__ - 1] = half * prod[k + i__ * prod_dim1] * wvec[k + i__ *
774 den[0] = den[0] - par[0] - sum;
775 tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 1)] + prod[k + (
776 prod_dim1 << 1)] * wvec[k + wvec_dim1];
777 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + (wvec_dim1 << 2)] +
778 prod[k + (prod_dim1 << 2)] * wvec[k + (wvec_dim1 << 1)];
779 tempc = prod[k + prod_dim1 * 3] * wvec[k + wvec_dim1 * 5] + prod[k +
780 prod_dim1 * 5] * wvec[k + wvec_dim1 * 3];
781 den[1] = den[1] - tempa - half * (tempb + tempc);
782 den[5] -= half * (tempb - tempc);
783 tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 3] + prod[k +
784 prod_dim1 * 3] * wvec[k + wvec_dim1];
785 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 5] + prod[k
786 + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 1)];
787 tempc = prod[k + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 2)] + prod[k
788 + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 3];
789 den[2] = den[2] - tempa - half * (tempb - tempc);
790 den[6] -= half * (tempb + tempc);
791 tempa = prod[k + prod_dim1] * wvec[k + (wvec_dim1 << 2)] + prod[k + (
792 prod_dim1 << 2)] * wvec[k + wvec_dim1];
793 den[3] = den[3] - tempa - par[1] + par[2];
794 tempa = prod[k + prod_dim1] * wvec[k + wvec_dim1 * 5] + prod[k +
795 prod_dim1 * 5] * wvec[k + wvec_dim1];
796 tempb = prod[k + (prod_dim1 << 1)] * wvec[k + wvec_dim1 * 3] + prod[k
797 + prod_dim1 * 3] * wvec[k + (wvec_dim1 << 1)];
798 den[4] = den[4] - tempa - half * tempb;
799 den[7] = den[7] - par[3] + par[4];
800 tempa = prod[k + (prod_dim1 << 2)] * wvec[k + wvec_dim1 * 5] + prod[k
801 + prod_dim1 * 5] * wvec[k + (wvec_dim1 << 2)];
803 den[8] -= half * tempa;
806 /* Extend DEN so that it holds all the coefficients of DENOM. */
809 for (i__ = 1; i__ <= 5; ++i__) {
810 /* Computing 2nd power */
811 d__1 = prod[*knew + i__ * prod_dim1];
812 par[i__ - 1] = half * (d__1 * d__1);
816 denex[0] = alpha * den[0] + par[0] + sum;
817 tempa = two * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 1)];
818 tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + (prod_dim1 << 2)];
819 tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + prod_dim1 * 5];
820 denex[1] = alpha * den[1] + tempa + tempb + tempc;
821 denex[5] = alpha * den[5] + tempb - tempc;
822 tempa = two * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 3];
823 tempb = prod[*knew + (prod_dim1 << 1)] * prod[*knew + prod_dim1 * 5];
824 tempc = prod[*knew + prod_dim1 * 3] * prod[*knew + (prod_dim1 << 2)];
825 denex[2] = alpha * den[2] + tempa + tempb - tempc;
826 denex[6] = alpha * den[6] + tempb + tempc;
827 tempa = two * prod[*knew + prod_dim1] * prod[*knew + (prod_dim1 << 2)];
828 denex[3] = alpha * den[3] + tempa + par[1] - par[2];
829 tempa = two * prod[*knew + prod_dim1] * prod[*knew + prod_dim1 * 5];
830 denex[4] = alpha * den[4] + tempa + prod[*knew + (prod_dim1 << 1)] * prod[
831 *knew + prod_dim1 * 3];
832 denex[7] = alpha * den[7] + par[3] - par[4];
833 denex[8] = alpha * den[8] + prod[*knew + (prod_dim1 << 2)] * prod[*knew +
836 /* Seek the value of the angle that maximizes the modulus of DENOM. */
838 sum = denex[0] + denex[1] + denex[3] + denex[5] + denex[7];
843 temp = twopi / (double) (iu + 1);
846 for (i__ = 1; i__ <= i__1; ++i__) {
847 angle = (double) i__ * temp;
850 for (j = 4; j <= 8; j += 2) {
851 par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
853 par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
857 for (j = 1; j <= 9; ++j) {
859 sum += denex[j - 1] * par[j - 1];
861 if (fabs(sum) > fabs(denmax)) {
865 } else if (i__ == isave + 1) {
877 if (tempa != tempb) {
880 step = half * (tempa - tempb) / (tempa + tempb);
882 angle = temp * ((double) isave + step);
884 /* Calculate the new parameters of the denominator, the new VLAG vector */
885 /* and the new D. Then test for convergence. */
889 for (j = 4; j <= 8; j += 2) {
890 par[j - 1] = par[1] * par[j - 3] - par[2] * par[j - 2];
892 par[j] = par[1] * par[j - 2] + par[2] * par[j - 3];
896 for (j = 1; j <= 9; ++j) {
897 *beta += den[j - 1] * par[j - 1];
899 denmax += denex[j - 1] * par[j - 1];
902 for (k = 1; k <= i__1; ++k) {
904 for (j = 1; j <= 5; ++j) {
906 vlag[k] += prod[k + j * prod_dim1] * par[j - 1];
914 for (i__ = 1; i__ <= i__1; ++i__) {
915 d__[i__] = par[1] * d__[i__] + par[2] * s[i__];
916 w[i__] = xopt[i__] + d__[i__];
917 /* Computing 2nd power */
920 tempa += d__[i__] * w[i__];
922 tempb += w[i__] * w[i__];
928 densav = max(densav,denold);
930 if (fabs(denmax) <= fabs(densav) * 1.1) {
935 /* Set S to half the gradient of the denominator with respect to D. */
936 /* Then branch for the next iteration. */
939 for (i__ = 1; i__ <= i__1; ++i__) {
940 temp = tempa * xopt[i__] + tempb * d__[i__] - vlag[*npt + i__];
942 s[i__] = tau * bmat[*knew + i__ * bmat_dim1] + alpha * temp;
945 for (k = 1; k <= i__1; ++k) {
948 for (j = 1; j <= i__2; ++j) {
950 sum += xpt[k + j * xpt_dim1] * w[j];
952 temp = (tau * w[*n + k] - alpha * vlag[k]) * sum;
954 for (i__ = 1; i__ <= i__2; ++i__) {
956 s[i__] += temp * xpt[k + i__ * xpt_dim1];
962 for (i__ = 1; i__ <= i__2; ++i__) {
963 /* Computing 2nd power */
967 ds += d__[i__] * s[i__];
969 ssden = dd * ss - ds * ds;
970 if (ssden >= dd * 1e-8 * ss) {
974 /* Set the vector W before the RETURN from the subroutine. */
978 for (k = 1; k <= i__2; ++k) {
980 for (j = 1; j <= 5; ++j) {
982 w[k] += wvec[k + j * wvec_dim1] * par[j - 1];
989 /*************************************************************************/
994 double *hcol, *xpt, *bmat, *xopt;
998 /* the Lagrange function, whose absolute value biglag maximizes */
999 static double lag(int n, const double *dx, double *grad, void *data)
1001 lag_data *d = (lag_data *) data;
1002 int i, j, npt = d->npt, ndim = d->ndim;
1003 const double *hcol = d->hcol, *xpt = d->xpt, *bmat = d->bmat, *xopt = d->xopt;
1005 for (j = 0; j < n; ++j) {
1006 val += bmat[j * ndim] * (xopt[j] + dx[j]);
1007 if (grad) grad[j] = bmat[j * ndim];
1009 for (i = 0; i < npt; ++i) {
1011 for (j = 0; j < n; ++j)
1012 dot += xpt[i + j * npt] * (xopt[j] + dx[j]);
1013 val += 0.5 * hcol[i] * (dot * dot);
1015 if (grad) for (j = 0; j < n; ++j)
1016 grad[j] += dot * xpt[i + j * npt];
1020 if (grad) for (j = 0; j < n; ++j) grad[j] = -grad[j];
1026 static void biglag_(int *n, int *npt, double *xopt,
1027 double *xpt, double *bmat, double *zmat, int *idz,
1028 int *ndim, int *knew, double *delta, double *d__,
1029 double *alpha, double *hcol, double *gc, double *gd,
1030 double *s, double *w)
1032 /* System generated locals */
1033 int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
1034 zmat_offset, i__1, i__2;
1037 /* Local variables */
1041 double sp, ss, cf1, cf2, cf3, cf4, cf5, dhd, cth, one, tau, sth, sum,
1044 double zero, angle, scale, denom;
1046 double delsq, tempa, tempb, twopi, taubeg, tauold, taumax;
1049 /* N is the number of variables. */
1050 /* NPT is the number of interpolation equations. */
1051 /* XOPT is the best interpolation point so far. */
1052 /* XPT contains the coordinates of the current interpolation points. */
1053 /* BMAT provides the last N columns of H. */
1054 /* ZMAT and IDZ give a factorization of the first NPT by NPT submatrix of H. */
1055 /* NDIM is the first dimension of BMAT and has the value NPT+N. */
1056 /* KNEW is the index of the interpolation point that is going to be moved. */
1057 /* DELTA is the current trust region bound. */
1058 /* D will be set to the step from XOPT to the new point. */
1059 /* ALPHA will be set to the KNEW-th diagonal element of the H matrix. */
1060 /* HCOL, GC, GD, S and W will be used for working space. */
1062 /* The step D is calculated in a way that attempts to maximize the modulus */
1063 /* of LFUNC(XOPT+D), subject to the bound ||D|| .LE. DELTA, where LFUNC is */
1064 /* the KNEW-th Lagrange function. */
1066 /* Set some constants. */
1068 /* Parameter adjustments */
1070 zmat_offset = 1 + zmat_dim1;
1071 zmat -= zmat_offset;
1073 xpt_offset = 1 + xpt_dim1;
1077 bmat_offset = 1 + bmat_dim1;
1078 bmat -= bmat_offset;
1090 twopi = atan(one) * 8.;
1091 delsq = *delta * *delta;
1092 nptm = *npt - *n - 1;
1094 /* Set the first NPT components of HCOL to the leading elements of the */
1095 /* KNEW-th column of H. */
1099 for (k = 1; k <= i__1; ++k) {
1104 for (j = 1; j <= i__1; ++j) {
1105 temp = zmat[*knew + j * zmat_dim1];
1110 for (k = 1; k <= i__2; ++k) {
1112 hcol[k] += temp * zmat[k + j * zmat_dim1];
1115 *alpha = hcol[*knew];
1117 /* Set the unscaled initial direction D. Form the gradient of LFUNC at */
1118 /* XOPT, and multiply D by the second derivative matrix of LFUNC. */
1122 for (i__ = 1; i__ <= i__2; ++i__) {
1123 d__[i__] = xpt[*knew + i__ * xpt_dim1] - xopt[i__];
1124 gc[i__] = bmat[*knew + i__ * bmat_dim1];
1127 /* Computing 2nd power */
1132 for (k = 1; k <= i__2; ++k) {
1136 for (j = 1; j <= i__1; ++j) {
1137 temp += xpt[k + j * xpt_dim1] * xopt[j];
1139 sum += xpt[k + j * xpt_dim1] * d__[j];
1141 temp = hcol[k] * temp;
1142 sum = hcol[k] * sum;
1144 for (i__ = 1; i__ <= i__1; ++i__) {
1145 gc[i__] += temp * xpt[k + i__ * xpt_dim1];
1147 gd[i__] += sum * xpt[k + i__ * xpt_dim1];
1151 /* Scale D and GD, with a sign change if required. Set S to another */
1152 /* vector in the initial two dimensional subspace. */
1158 for (i__ = 1; i__ <= i__1; ++i__) {
1159 /* Computing 2nd power */
1162 sp += d__[i__] * gc[i__];
1164 dhd += d__[i__] * gd[i__];
1166 scale = *delta / sqrt(dd);
1167 if (sp * dhd < zero) {
1171 if (sp * sp > dd * .99 * gg) {
1174 tau = scale * (fabs(sp) + half * scale * fabs(dhd));
1175 if (gg * delsq < tau * .01 * tau) {
1179 for (i__ = 1; i__ <= i__1; ++i__) {
1180 d__[i__] = scale * d__[i__];
1181 gd[i__] = scale * gd[i__];
1183 s[i__] = gc[i__] + temp * gd[i__];
1187 double minf, *lb, *ub;
1193 ld.xpt = &xpt[1 + 1 * xpt_dim1];
1194 ld.bmat = &bmat[*knew + 1 * bmat_dim1];
1197 lb = &gc[1]; ub = &gd[1];
1198 for (j = 0; j < *n; ++j)
1199 lb[j] = -(ub[j] = *delta);
1200 ld.flipsign = lag(*n, &d__[1], 0, &ld) > 0; /* maximize if > 0 */
1201 nlopt_minimize_constrained(NLOPT_LD_MMA, *n, lag, &ld,
1202 1, rho_constraint, delta, sizeof(double),
1203 lb, ub, &d__[1], &minf, -HUGE_VAL,
1204 0., 0., 1e-5, 0, 1000, 0.);
1206 printf("biglag nlopt converged to %g in %d iters\n", minf, ld.iter);
1207 for (j = 1; j <= *n; ++j)
1208 printf(" d[%d] = %g\n", j, d__[j]);
1212 /* Begin the iteration by overwriting S with a vector that has the */
1213 /* required length and direction, except that termination occurs if */
1214 /* the given D and S are nearly parallel. */
1222 for (i__ = 1; i__ <= i__1; ++i__) {
1223 /* Computing 2nd power */
1226 sp += d__[i__] * s[i__];
1228 /* Computing 2nd power */
1232 temp = dd * ss - sp * sp;
1233 if (temp <= dd * 1e-8 * ss) {
1238 for (i__ = 1; i__ <= i__1; ++i__) {
1239 s[i__] = (dd * s[i__] - sp * d__[i__]) / denom;
1244 /* Calculate the coefficients of the objective function on the circle, */
1245 /* beginning with the multiplication of S by the second derivative matrix. */
1248 for (k = 1; k <= i__1; ++k) {
1251 for (j = 1; j <= i__2; ++j) {
1253 sum += xpt[k + j * xpt_dim1] * s[j];
1255 sum = hcol[k] * sum;
1257 for (i__ = 1; i__ <= i__2; ++i__) {
1259 w[i__] += sum * xpt[k + i__ * xpt_dim1];
1268 for (i__ = 1; i__ <= i__2; ++i__) {
1269 cf1 += s[i__] * w[i__];
1270 cf2 += d__[i__] * gc[i__];
1271 cf3 += s[i__] * gc[i__];
1272 cf4 += d__[i__] * gd[i__];
1274 cf5 += s[i__] * gd[i__];
1277 cf4 = half * cf4 - cf1;
1279 /* Seek the value of the angle that maximizes the modulus of TAU. */
1281 taubeg = cf1 + cf2 + cf4;
1286 temp = twopi / (double) (iu + 1);
1288 for (i__ = 1; i__ <= i__2; ++i__) {
1289 angle = (double) i__ * temp;
1292 tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
1293 if (fabs(tau) > fabs(taumax)) {
1297 } else if (i__ == isave + 1) {
1310 if (tempa != tempb) {
1313 step = half * (tempa - tempb) / (tempa + tempb);
1315 angle = temp * ((double) isave + step);
1317 /* Calculate the new D and GD. Then test for convergence. */
1321 tau = cf1 + (cf2 + cf4 * cth) * cth + (cf3 + cf5 * cth) * sth;
1323 for (i__ = 1; i__ <= i__2; ++i__) {
1324 d__[i__] = cth * d__[i__] + sth * s[i__];
1325 gd[i__] = cth * gd[i__] + sth * w[i__];
1327 s[i__] = gc[i__] + gd[i__];
1329 if (fabs(tau) <= fabs(taubeg) * 1.1) {
1341 /*************************************************************************/
1344 static void update_(int *n, int *npt, double *bmat,
1345 double *zmat, int *idz, int *ndim, double *vlag,
1346 double *beta, int *knew, double *w)
1348 /* System generated locals */
1349 int bmat_dim1, bmat_offset, zmat_dim1, zmat_offset, i__1, i__2;
1352 /* Local variables */
1353 int i__, j, ja, jb, jl, jp;
1354 double one, tau, temp;
1358 double scala, scalb_, alpha, denom, tempa, tempb, tausq;
1361 /* The arrays BMAT and ZMAT with IDZ are updated, in order to shift the */
1362 /* interpolation point that has index KNEW. On entry, VLAG contains the */
1363 /* components of the vector Theta*Wcheck+e_b of the updating formula */
1364 /* (6.11), and BETA holds the value of the parameter that has this name. */
1365 /* The vector W is used for working space. */
1367 /* Set some constants. */
1369 /* Parameter adjustments */
1371 zmat_offset = 1 + zmat_dim1;
1372 zmat -= zmat_offset;
1374 bmat_offset = 1 + bmat_dim1;
1375 bmat -= bmat_offset;
1382 nptm = *npt - *n - 1;
1384 /* Apply the rotations that put zeros in the KNEW-th row of ZMAT. */
1388 for (j = 2; j <= i__1; ++j) {
1391 } else if (zmat[*knew + j * zmat_dim1] != zero) {
1392 /* Computing 2nd power */
1393 d__1 = zmat[*knew + jl * zmat_dim1];
1394 /* Computing 2nd power */
1395 d__2 = zmat[*knew + j * zmat_dim1];
1396 temp = sqrt(d__1 * d__1 + d__2 * d__2);
1397 tempa = zmat[*knew + jl * zmat_dim1] / temp;
1398 tempb = zmat[*knew + j * zmat_dim1] / temp;
1400 for (i__ = 1; i__ <= i__2; ++i__) {
1401 temp = tempa * zmat[i__ + jl * zmat_dim1] + tempb * zmat[i__
1403 zmat[i__ + j * zmat_dim1] = tempa * zmat[i__ + j * zmat_dim1]
1404 - tempb * zmat[i__ + jl * zmat_dim1];
1406 zmat[i__ + jl * zmat_dim1] = temp;
1408 zmat[*knew + j * zmat_dim1] = zero;
1413 /* Put the first NPT components of the KNEW-th column of HLAG into W, */
1414 /* and calculate the parameters of the updating formula. */
1416 tempa = zmat[*knew + zmat_dim1];
1421 tempb = zmat[*knew + jl * zmat_dim1];
1424 for (i__ = 1; i__ <= i__1; ++i__) {
1425 w[i__] = tempa * zmat[i__ + zmat_dim1];
1427 w[i__] += tempb * zmat[i__ + jl * zmat_dim1];
1434 denom = alpha * *beta + tausq;
1437 /* Complete the updating of ZMAT when there is only one nonzero element */
1438 /* in the KNEW-th row of the new matrix ZMAT, but, if IFLAG is set to one, */
1439 /* then the first column of ZMAT will be exchanged with another one later. */
1443 temp = sqrt((fabs(denom)));
1444 tempb = tempa / temp;
1447 for (i__ = 1; i__ <= i__1; ++i__) {
1449 zmat[i__ + zmat_dim1] = tempa * zmat[i__ + zmat_dim1] - tempb *
1452 if (*idz == 1 && temp < zero) {
1455 if (*idz >= 2 && temp >= zero) {
1460 /* Complete the updating of ZMAT in the alternative case. */
1463 if (*beta >= zero) {
1467 temp = zmat[*knew + jb * zmat_dim1] / denom;
1468 tempa = temp * *beta;
1470 temp = zmat[*knew + ja * zmat_dim1];
1471 scala = one / sqrt(fabs(*beta) * temp * temp + tausq);
1472 scalb_ = scala * sqrt((fabs(denom)));
1474 for (i__ = 1; i__ <= i__1; ++i__) {
1475 zmat[i__ + ja * zmat_dim1] = scala * (tau * zmat[i__ + ja *
1476 zmat_dim1] - temp * vlag[i__]);
1478 zmat[i__ + jb * zmat_dim1] = scalb_ * (zmat[i__ + jb * zmat_dim1]
1479 - tempa * w[i__] - tempb * vlag[i__]);
1481 if (denom <= zero) {
1485 if (*beta >= zero) {
1491 /* IDZ is reduced in the following case, and usually the first column */
1492 /* of ZMAT is exchanged with a later one. */
1497 for (i__ = 1; i__ <= i__1; ++i__) {
1498 temp = zmat[i__ + zmat_dim1];
1499 zmat[i__ + zmat_dim1] = zmat[i__ + *idz * zmat_dim1];
1501 zmat[i__ + *idz * zmat_dim1] = temp;
1505 /* Finally, update the matrix BMAT. */
1508 for (j = 1; j <= i__1; ++j) {
1510 w[jp] = bmat[*knew + j * bmat_dim1];
1511 tempa = (alpha * vlag[jp] - tau * w[jp]) / denom;
1512 tempb = (-(*beta) * w[jp] - tau * vlag[jp]) / denom;
1514 for (i__ = 1; i__ <= i__2; ++i__) {
1515 bmat[i__ + j * bmat_dim1] = bmat[i__ + j * bmat_dim1] + tempa *
1516 vlag[i__] + tempb * w[i__];
1518 bmat[jp + (i__ - *npt) * bmat_dim1] = bmat[i__ + j *
1528 /*************************************************************************/
1531 static nlopt_result newuob_(int *n, int *npt, double *x,
1533 nlopt_stopping *stop, double *minf,
1534 newuoa_func calfun, void *calfun_data,
1535 double *xbase, double *xopt, double *xnew,
1536 double *xpt, double *fval, double *gq, double *hq,
1537 double *pq, double *bmat, double *zmat, int *ndim,
1538 double *d__, double *vlag, double *w)
1540 /* System generated locals */
1541 int xpt_dim1, xpt_offset, bmat_dim1, bmat_offset, zmat_dim1,
1542 zmat_offset, i__1, i__2, i__3;
1543 double d__1, d__2, d__3;
1545 /* Local variables */
1547 int i__, j, k, ih, nf, nh, ip, jp;
1554 double sum, fbeg, diff, half, beta;
1558 double temp, suma, sumb, fopt = HUGE_VAL, bsum, gqsq;
1560 double zero, xipt, xjpt, sumz, diffa, diffb, diffc, hdiag, alpha,
1561 delta, recip, reciq, fsave;
1562 int ksave, nfsav, itemp;
1563 double dnorm, ratio, dstep, tenth, vquad;
1568 double detrat, crvmin;
1572 nlopt_result rc = NLOPT_SUCCESS;
1574 /* SGJ, 2008: compute rhoend from NLopt stop info */
1575 rhoend = stop->xtol_rel * (*rhobeg);
1576 for (j = 0; j < *n; ++j)
1577 if (rhoend < stop->xtol_abs[j])
1578 rhoend = stop->xtol_abs[j];
1580 /* The arguments N, NPT, X, RHOBEG, RHOEND, IPRINT and MAXFUN are identical */
1581 /* to the corresponding arguments in SUBROUTINE NEWUOA. */
1582 /* XBASE will hold a shift of origin that should reduce the contributions */
1583 /* from rounding errors to values of the model and Lagrange functions. */
1584 /* XOPT will be set to the displacement from XBASE of the vector of */
1585 /* variables that provides the least calculated F so far. */
1586 /* XNEW will be set to the displacement from XBASE of the vector of */
1587 /* variables for the current calculation of F. */
1588 /* XPT will contain the interpolation point coordinates relative to XBASE. */
1589 /* FVAL will hold the values of F at the interpolation points. */
1590 /* GQ will hold the gradient of the quadratic model at XBASE. */
1591 /* HQ will hold the explicit second derivatives of the quadratic model. */
1592 /* PQ will contain the parameters of the implicit second derivatives of */
1593 /* the quadratic model. */
1594 /* BMAT will hold the last N columns of H. */
1595 /* ZMAT will hold the factorization of the leading NPT by NPT submatrix of */
1596 /* H, this factorization being ZMAT times Diag(DZ) times ZMAT^T, where */
1597 /* the elements of DZ are plus or minus one, as specified by IDZ. */
1598 /* NDIM is the first dimension of BMAT and has the value NPT+N. */
1599 /* D is reserved for trial steps from XOPT. */
1600 /* VLAG will contain the values of the Lagrange functions at a new point X. */
1601 /* They are part of a product that requires VLAG to be of length NDIM. */
1602 /* The array W will be used for working space. Its length must be at least */
1603 /* 10*NDIM = 10*(NPT+N). */
1605 /* Set some constants. */
1607 /* Parameter adjustments */
1609 zmat_offset = 1 + zmat_dim1;
1610 zmat -= zmat_offset;
1612 xpt_offset = 1 + xpt_dim1;
1623 bmat_offset = 1 + bmat_dim1;
1624 bmat -= bmat_offset;
1638 /* Set the initial elements of XPT, BMAT, HQ, PQ and ZMAT to zero. */
1641 for (j = 1; j <= i__1; ++j) {
1644 for (k = 1; k <= i__2; ++k) {
1646 xpt[k + j * xpt_dim1] = zero;
1649 for (i__ = 1; i__ <= i__2; ++i__) {
1651 bmat[i__ + j * bmat_dim1] = zero;
1655 for (ih = 1; ih <= i__2; ++ih) {
1660 for (k = 1; k <= i__2; ++k) {
1663 for (j = 1; j <= i__1; ++j) {
1665 zmat[k + j * zmat_dim1] = zero;
1669 /* Begin the initialization procedure. NF becomes one more than the number */
1670 /* of function values so far. The coordinates of the displacement of the */
1671 /* next initial interpolation point from XBASE are set in XPT(NF,.). */
1673 rhosq = *rhobeg * *rhobeg;
1674 recip = one / rhosq;
1675 reciq = sqrt(half) / rhosq;
1681 if (nfm <= *n << 1) {
1682 if (nfm >= 1 && nfm <= *n) {
1683 xpt[nf + nfm * xpt_dim1] = *rhobeg;
1684 } else if (nfm > *n) {
1685 xpt[nf + nfmm * xpt_dim1] = -(*rhobeg);
1688 itemp = (nfmm - 1) / *n;
1689 jpt = nfm - itemp * *n - *n;
1697 if (fval[ipt + np] < fval[ipt + 1]) {
1701 if (fval[jpt + np] < fval[jpt + 1]) {
1704 xpt[nf + ipt * xpt_dim1] = xipt;
1705 xpt[nf + jpt * xpt_dim1] = xjpt;
1708 /* Calculate the next value of F, label 70 being reached immediately */
1709 /* after this calculation. The least function value so far and its index */
1713 for (j = 1; j <= i__1; ++j) {
1715 x[j] = xpt[nf + j * xpt_dim1] + xbase[j];
1724 } else if (f < fopt) {
1729 /* Set the nonzero initial elements of BMAT and the quadratic model in */
1730 /* the cases when NF is at most 2*N+1. */
1732 if (nfm <= *n << 1) {
1733 if (nfm >= 1 && nfm <= *n) {
1734 gq[nfm] = (f - fbeg) / *rhobeg;
1735 if (*npt < nf + *n) {
1736 bmat[nfm * bmat_dim1 + 1] = -one / *rhobeg;
1737 bmat[nf + nfm * bmat_dim1] = one / *rhobeg;
1738 bmat[*npt + nfm + nfm * bmat_dim1] = -half * rhosq;
1740 } else if (nfm > *n) {
1741 bmat[nf - *n + nfmm * bmat_dim1] = half / *rhobeg;
1742 bmat[nf + nfmm * bmat_dim1] = -half / *rhobeg;
1743 zmat[nfmm * zmat_dim1 + 1] = -reciq - reciq;
1744 zmat[nf - *n + nfmm * zmat_dim1] = reciq;
1745 zmat[nf + nfmm * zmat_dim1] = reciq;
1746 ih = nfmm * (nfmm + 1) / 2;
1747 temp = (fbeg - f) / *rhobeg;
1748 hq[ih] = (gq[nfmm] - temp) / *rhobeg;
1749 gq[nfmm] = half * (gq[nfmm] + temp);
1752 /* Set the off-diagonal second derivatives of the Lagrange functions and */
1753 /* the initial quadratic model. */
1756 ih = ipt * (ipt - 1) / 2 + jpt;
1763 zmat[nfmm * zmat_dim1 + 1] = recip;
1764 zmat[nf + nfmm * zmat_dim1] = recip;
1765 zmat[ipt + 1 + nfmm * zmat_dim1] = -recip;
1766 zmat[jpt + 1 + nfmm * zmat_dim1] = -recip;
1767 hq[ih] = (fbeg - fval[ipt + 1] - fval[jpt + 1] + f) / (xipt * xjpt);
1773 /* Begin the iterative procedure, because the initial model is complete. */
1783 for (i__ = 1; i__ <= i__1; ++i__) {
1784 xopt[i__] = xpt[kopt + i__ * xpt_dim1];
1786 /* Computing 2nd power */
1788 xoptsq += d__1 * d__1;
1793 /* Generate the next trust region step and test its length. Set KNEW */
1794 /* to -1 if the purpose of the next F will be to improve the model. */
1798 trsapp_(n, npt, &xopt[1], &xpt[xpt_offset], &gq[1], &hq[1], &pq[1], &
1799 delta, &d__[1], &w[1], &w[np], &w[np + *n], &w[np + (*n << 1)], &
1803 for (i__ = 1; i__ <= i__1; ++i__) {
1805 /* Computing 2nd power */
1810 d__1 = delta, d__2 = sqrt(dsq);
1811 dnorm = min(d__1,d__2);
1812 if (dnorm < half * rho) {
1814 delta = tenth * delta;
1816 if (delta <= rho * 1.5) {
1819 if (nf <= nfsav + 2) {
1822 temp = crvmin * .125 * rho * rho;
1824 d__1 = max(diffa,diffb);
1825 if (temp <= max(d__1,diffc)) {
1831 /* Shift XBASE if XOPT may be too far from XBASE. First make the changes */
1832 /* to BMAT that do not depend on ZMAT. */
1835 if (dsq <= xoptsq * .001) {
1836 tempq = xoptsq * .25;
1838 for (k = 1; k <= i__1; ++k) {
1841 for (i__ = 1; i__ <= i__2; ++i__) {
1843 sum += xpt[k + i__ * xpt_dim1] * xopt[i__];
1846 sum -= half * xoptsq;
1849 for (i__ = 1; i__ <= i__2; ++i__) {
1850 gq[i__] += temp * xpt[k + i__ * xpt_dim1];
1851 xpt[k + i__ * xpt_dim1] -= half * xopt[i__];
1852 vlag[i__] = bmat[k + i__ * bmat_dim1];
1853 w[i__] = sum * xpt[k + i__ * xpt_dim1] + tempq * xopt[i__];
1856 for (j = 1; j <= i__3; ++j) {
1858 bmat[ip + j * bmat_dim1] = bmat[ip + j * bmat_dim1] +
1859 vlag[i__] * w[j] + w[i__] * vlag[j];
1864 /* Then the revisions of BMAT that depend on ZMAT are calculated. */
1867 for (k = 1; k <= i__3; ++k) {
1870 for (i__ = 1; i__ <= i__2; ++i__) {
1871 sumz += zmat[i__ + k * zmat_dim1];
1873 w[i__] = w[*npt + i__] * zmat[i__ + k * zmat_dim1];
1876 for (j = 1; j <= i__2; ++j) {
1877 sum = tempq * sumz * xopt[j];
1879 for (i__ = 1; i__ <= i__1; ++i__) {
1881 sum += w[i__] * xpt[i__ + j * xpt_dim1];
1888 for (i__ = 1; i__ <= i__1; ++i__) {
1890 bmat[i__ + j * bmat_dim1] += sum * zmat[i__ + k *
1895 for (i__ = 1; i__ <= i__1; ++i__) {
1902 for (j = 1; j <= i__2; ++j) {
1904 bmat[ip + j * bmat_dim1] += temp * vlag[j];
1909 /* The following instructions complete the shift of XBASE, including */
1910 /* the changes to the parameters of the quadratic model. */
1914 for (j = 1; j <= i__2; ++j) {
1917 for (k = 1; k <= i__1; ++k) {
1918 w[j] += pq[k] * xpt[k + j * xpt_dim1];
1920 xpt[k + j * xpt_dim1] -= half * xopt[j];
1923 for (i__ = 1; i__ <= i__1; ++i__) {
1926 gq[j] += hq[ih] * xopt[i__];
1928 gq[i__] += hq[ih] * xopt[j];
1929 hq[ih] = hq[ih] + w[i__] * xopt[j] + xopt[i__] * w[j];
1931 bmat[*npt + i__ + j * bmat_dim1] = bmat[*npt + j + i__ *
1936 for (j = 1; j <= i__1; ++j) {
1937 xbase[j] += xopt[j];
1944 /* Pick the model step if KNEW is positive. A different choice of D */
1945 /* may be made later, if the choice of D by BIGLAG causes substantial */
1946 /* cancellation in DENOM. */
1949 biglag_(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset], &zmat[
1950 zmat_offset], &idz, ndim, &knew, &dstep, &d__[1], &alpha, &
1951 vlag[1], &vlag[*npt + 1], &w[1], &w[np], &w[np + *n]);
1954 /* Calculate VLAG and BETA for the current choice of D. The first NPT */
1955 /* components of W_check will be held in W. */
1958 for (k = 1; k <= i__1; ++k) {
1963 for (j = 1; j <= i__2; ++j) {
1964 suma += xpt[k + j * xpt_dim1] * d__[j];
1965 sumb += xpt[k + j * xpt_dim1] * xopt[j];
1967 sum += bmat[k + j * bmat_dim1] * d__[j];
1969 w[k] = suma * (half * suma + sumb);
1975 for (k = 1; k <= i__1; ++k) {
1978 for (i__ = 1; i__ <= i__2; ++i__) {
1980 sum += zmat[i__ + k * zmat_dim1] * w[i__];
1989 for (i__ = 1; i__ <= i__2; ++i__) {
1991 vlag[i__] += sum * zmat[i__ + k * zmat_dim1];
1997 for (j = 1; j <= i__2; ++j) {
2000 for (i__ = 1; i__ <= i__1; ++i__) {
2002 sum += w[i__] * bmat[i__ + j * bmat_dim1];
2004 bsum += sum * d__[j];
2007 for (k = 1; k <= i__1; ++k) {
2009 sum += bmat[jp + k * bmat_dim1] * d__[k];
2012 bsum += sum * d__[j];
2014 dx += d__[j] * xopt[j];
2016 beta = dx * dx + dsq * (xoptsq + dx + dx + half * dsq) + beta - bsum;
2019 /* If KNEW is positive and if the cancellation in DENOM is unacceptable, */
2020 /* then BIGDEN calculates an alternative model step, XNEW being used for */
2021 /* working space. */
2024 /* Computing 2nd power */
2026 temp = one + alpha * beta / (d__1 * d__1);
2027 if (fabs(temp) <= .8) {
2028 bigden_(n, npt, &xopt[1], &xpt[xpt_offset], &bmat[bmat_offset], &
2029 zmat[zmat_offset], &idz, ndim, &kopt, &knew, &d__[1], &w[
2030 1], &vlag[1], &beta, &xnew[1], &w[*ndim + 1], &w[*ndim *
2035 /* Calculate the next value of the objective function. */
2039 for (i__ = 1; i__ <= i__2; ++i__) {
2040 xnew[i__] = xopt[i__] + d__[i__];
2042 x[i__] = xbase[i__] + xnew[i__];
2046 if (nlopt_stop_evals(stop)) rc = NLOPT_MAXEVAL_REACHED;
2047 else if (nlopt_stop_time(stop)) rc = NLOPT_MAXTIME_REACHED;
2048 if (rc != NLOPT_SUCCESS) goto L530;
2051 f = calfun(*n, &x[1], calfun_data);
2052 if (f < stop->minf_max) {
2053 rc = NLOPT_MINF_MAX_REACHED;
2064 /* Use the quadratic model to predict the change in F due to the step D, */
2065 /* and set DIFF to the error of this prediction. */
2070 for (j = 1; j <= i__2; ++j) {
2071 vquad += d__[j] * gq[j];
2073 for (i__ = 1; i__ <= i__1; ++i__) {
2075 temp = d__[i__] * xnew[j] + d__[j] * xopt[i__];
2080 vquad += temp * hq[ih];
2084 for (k = 1; k <= i__1; ++k) {
2086 vquad += pq[k] * w[k];
2088 diff = f - fopt - vquad;
2096 /* Update FOPT and XOPT if the new F is the least value of the objective */
2097 /* function so far. The branch when KNEW is positive occurs if D is not */
2098 /* a trust region step. */
2105 for (i__ = 1; i__ <= i__1; ++i__) {
2106 xopt[i__] = xnew[i__];
2108 /* Computing 2nd power */
2110 xoptsq += d__1 * d__1;
2112 if (nlopt_stop_ftol(stop, fopt, fsave)) {
2113 rc = NLOPT_FTOL_REACHED;
2123 /* Pick the next value of DELTA after a trust region step. */
2125 if (vquad >= zero) {
2128 ratio = (f - fsave) / vquad;
2129 if (ratio <= tenth) {
2130 delta = half * dnorm;
2131 } else if (ratio <= .7) {
2133 d__1 = half * delta;
2134 delta = max(d__1,dnorm);
2137 d__1 = half * delta, d__2 = dnorm + dnorm;
2138 delta = max(d__1,d__2);
2140 if (delta <= rho * 1.5) {
2144 /* Set KNEW to the index of the next interpolation point to be deleted. */
2147 d__2 = tenth * delta;
2148 /* Computing 2nd power */
2149 d__1 = max(d__2,rho);
2150 rhosq = d__1 * d__1;
2158 for (k = 1; k <= i__1; ++k) {
2161 for (j = 1; j <= i__2; ++j) {
2167 /* Computing 2nd power */
2168 d__1 = zmat[k + j * zmat_dim1];
2169 hdiag += temp * (d__1 * d__1);
2171 /* Computing 2nd power */
2173 temp = (d__1 = beta * hdiag + d__2 * d__2, fabs(d__1));
2176 for (j = 1; j <= i__2; ++j) {
2178 /* Computing 2nd power */
2179 d__1 = xpt[k + j * xpt_dim1] - xopt[j];
2180 distsq += d__1 * d__1;
2182 if (distsq > rhosq) {
2183 /* Computing 3rd power */
2184 d__1 = distsq / rhosq;
2185 temp *= d__1 * (d__1 * d__1);
2187 if (temp > detrat && k != ktemp) {
2197 /* Update BMAT, ZMAT and IDZ, so that the KNEW-th interpolation point */
2198 /* can be moved. Begin the updating of the quadratic model, starting */
2199 /* with the explicit second derivative term. */
2202 update_(n, npt, &bmat[bmat_offset], &zmat[zmat_offset], &idz, ndim, &vlag[
2203 1], &beta, &knew, &w[1]);
2207 for (i__ = 1; i__ <= i__1; ++i__) {
2208 temp = pq[knew] * xpt[knew + i__ * xpt_dim1];
2210 for (j = 1; j <= i__2; ++j) {
2213 hq[ih] += temp * xpt[knew + j * xpt_dim1];
2218 /* Update the other second derivative parameters, and then the gradient */
2219 /* vector of the model. Also include the new interpolation point. */
2222 for (j = 1; j <= i__2; ++j) {
2223 temp = diff * zmat[knew + j * zmat_dim1];
2228 for (k = 1; k <= i__1; ++k) {
2230 pq[k] += temp * zmat[k + j * zmat_dim1];
2235 for (i__ = 1; i__ <= i__1; ++i__) {
2236 gq[i__] += diff * bmat[knew + i__ * bmat_dim1];
2237 /* Computing 2nd power */
2239 gqsq += d__1 * d__1;
2241 xpt[knew + i__ * xpt_dim1] = xnew[i__];
2244 /* If a trust region step makes a small change to the objective function, */
2245 /* then calculate the gradient of the least Frobenius norm interpolant at */
2246 /* XBASE, and store it in W, using VLAG for a vector of right hand sides. */
2248 if (ksave == 0 && delta == rho) {
2249 if (fabs(ratio) > .01) {
2253 for (k = 1; k <= i__1; ++k) {
2255 vlag[k] = fval[k] - fval[kopt];
2259 for (i__ = 1; i__ <= i__1; ++i__) {
2262 for (k = 1; k <= i__2; ++k) {
2264 sum += bmat[k + i__ * bmat_dim1] * vlag[k];
2271 /* Test whether to replace the new quadratic model by the least Frobenius */
2272 /* norm interpolant, making the replacement if the test is satisfied. */
2275 if (gqsq < gisq * 100.) {
2280 for (i__ = 1; i__ <= i__1; ++i__) {
2285 for (ih = 1; ih <= i__1; ++ih) {
2290 for (j = 1; j <= i__1; ++j) {
2293 for (k = 1; k <= i__2; ++k) {
2295 w[j] += vlag[k] * zmat[k + j * zmat_dim1];
2303 for (k = 1; k <= i__1; ++k) {
2306 for (j = 1; j <= i__2; ++j) {
2308 pq[k] += zmat[k + j * zmat_dim1] * w[j];
2319 /* If a trust region step has provided a sufficient decrease in F, then */
2320 /* branch for another trust region calculation. The case KSAVE>0 occurs */
2321 /* when the new function value was calculated by a model step. */
2323 if (f <= fsave + tenth * vquad) {
2330 /* Alternatively, find out if the interpolation points are close enough */
2331 /* to the best point so far. */
2335 distsq = delta * 4. * delta;
2337 for (k = 1; k <= i__2; ++k) {
2340 for (j = 1; j <= i__1; ++j) {
2342 /* Computing 2nd power */
2343 d__1 = xpt[k + j * xpt_dim1] - xopt[j];
2353 /* If KNEW is positive, then set DSTEP, and branch back for the next */
2354 /* iteration, which will generate a "model step". */
2359 d__2 = tenth * sqrt(distsq), d__3 = half * delta;
2360 d__1 = min(d__2,d__3);
2361 dstep = max(d__1,rho);
2362 dsq = dstep * dstep;
2368 if (max(delta,dnorm) > rho) {
2372 /* The calculations with the current value of RHO are complete. Pick the */
2373 /* next values of RHO and DELTA. */
2378 ratio = rho / rhoend;
2381 } else if (ratio <= 250.) {
2382 rho = sqrt(ratio) * rhoend;
2386 delta = max(delta,rho);
2390 /* Return from the calculation, after another Newton-Raphson step, if */
2391 /* it is too short to have been tried before. */
2396 rc = NLOPT_XTOL_REACHED;
2400 for (i__ = 1; i__ <= i__2; ++i__) {
2402 x[i__] = xbase[i__] + xopt[i__];
2410 /*************************************************************************/
2413 nlopt_result newuoa(int n, int npt, double *x,
2414 double rhobeg, nlopt_stopping *stop, double *minf,
2415 newuoa_func calfun, void *calfun_data)
2417 /* Local variables */
2418 int id, np, iw, igq, ihq, ixb, ifv, ipq, ivl, ixn, ixo, ixp, ndim,
2423 /* This subroutine seeks the least value of a function of many variables, */
2424 /* by a trust region method that forms quadratic models by interpolation. */
2425 /* There can be some freedom in the interpolation conditions, which is */
2426 /* taken up by minimizing the Frobenius norm of the change to the second */
2427 /* derivative of the quadratic model, beginning with a zero matrix. The */
2428 /* arguments of the subroutine are as follows. */
2430 /* N must be set to the number of variables and must be at least two. */
2431 /* NPT is the number of interpolation conditions. Its value must be in the */
2432 /* interval [N+2,(N+1)(N+2)/2]. */
2433 /* Initial values of the variables must be set in X(1),X(2),...,X(N). They */
2434 /* will be changed to the values that give the least calculated F. */
2435 /* RHOBEG and RHOEND must be set to the initial and final values of a trust */
2436 /* region radius, so both must be positive with RHOEND<=RHOBEG. Typically */
2437 /* RHOBEG should be about one tenth of the greatest expected change to a */
2438 /* variable, and RHOEND should indicate the accuracy that is required in */
2439 /* the final values of the variables. */
2440 /* The value of IPRINT should be set to 0, 1, 2 or 3, which controls the */
2441 /* amount of printing. Specifically, there is no output if IPRINT=0 and */
2442 /* there is output only at the return if IPRINT=1. Otherwise, each new */
2443 /* value of RHO is printed, with the best vector of variables so far and */
2444 /* the corresponding value of the objective function. Further, each new */
2445 /* value of F with its variables are output if IPRINT=3. */
2446 /* MAXFUN must be set to an upper bound on the number of calls of CALFUN. */
2447 /* The array W will be used for working space. Its length must be at least */
2448 /* (NPT+13)*(NPT+N)+3*N*(N+3)/2. */
2450 /* SUBROUTINE CALFUN (N,X,F) must be provided by the user. It must set F to */
2451 /* the value of the objective function for the variables X(1),X(2),...,X(N). */
2453 /* Partition the working space array, so that different parts of it can be */
2454 /* treated separately by the subroutine that performs the main calculation. */
2456 /* Parameter adjustments */
2462 if (n < 2 || npt < n + 2 || npt > (n + 2) * np / 2) {
2463 return NLOPT_INVALID_ARGS;
2470 ifv = ixp + n * npt;
2473 ipq = ihq + n * np / 2;
2475 izmat = ibmat + ndim * n;
2476 id = izmat + npt * nptm;
2480 w = (double *) malloc(sizeof(double) * ((npt+13)*(npt+n) + 3*(n*(n+3))/2));
2481 if (!w) return NLOPT_OUT_OF_MEMORY;
2484 /* The above settings provide a partition of W for subroutine NEWUOB. */
2485 /* The partition requires the first NPT*(NPT+N)+5*N*(N+3)/2 elements of */
2486 /* W plus the space that is needed by the last array of NEWUOB. */
2488 ret = newuob_(&n, &npt, &x[1], &rhobeg, stop, minf, calfun, calfun_data,
2489 &w[ixb], &w[ixo], &w[ixn], &w[ixp], &w[ifv],
2490 &w[igq], &w[ihq], &w[ipq], &w[ibmat], &w[izmat],
2491 &ndim, &w[id], &w[ivl], &w[iw]);
2498 /*************************************************************************/
2499 /*************************************************************************/