/* Subroutine */ int check0_(doublereal *sfac) { /* Initialized data */ static doublereal ds1[8] = { .8,.6,.8,-.6,.8,0.,1.,0. }; static doublereal datrue[8] = { .5,.5,.5,-.5,-.5,0.,1.,1. }; static doublereal dbtrue[8] = { 0.,.6,0.,-.6,0.,0.,1.,0. }; static doublereal da1[8] = { .3,.4,-.3,-.4,-.3,0.,0.,1. }; static doublereal db1[8] = { .4,.3,.4,.3,-.4,0.,1.,0. }; static doublereal dc1[8] = { .6,.8,-.6,.8,.6,1.,0.,1. }; /* Builtin functions */ integer s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen), e_wsle(void); /* Subroutine */ int s_stop(char *, ftnlen); /* Local variables */ static integer k; extern /* Subroutine */ int drotg_(doublereal *, doublereal *, doublereal *, doublereal *), stest1_(doublereal *, doublereal *, doublereal * , doublereal *); static doublereal sa, sb, sc, ss; /* Fortran I/O blocks */ static cilist io___19 = { 0, 6, 0, 0, 0 }; /* Compute true values which cannot be prestored in decimal notation */ dbtrue[0] = 1.6666666666666667; dbtrue[2] = -1.6666666666666667; dbtrue[4] = 1.6666666666666667; for (k = 1; k <= 8; ++k) { combla_1.n = k; if (combla_1.icase == 3) { if (k > 8) { goto L40; } sa = da1[k - 1]; sb = db1[k - 1]; drotg_(&sa, &sb, &sc, &ss); stest1_(&sa, &datrue[k - 1], &datrue[k - 1], sfac); stest1_(&sb, &dbtrue[k - 1], &dbtrue[k - 1], sfac); stest1_(&sc, &dc1[k - 1], &dc1[k - 1], sfac); stest1_(&ss, &ds1[k - 1], &ds1[k - 1], sfac); } else { s_wsle(&io___19); do_lio(&c__9, &c__1, " Shouldn't be here in CHECK0", (ftnlen)28); e_wsle(); s_stop("", (ftnlen)0); } /* L20: */ } L40: return 0; } /* check0_
int f2c_drotg(doublereal* a, doublereal* b, doublereal* c, doublereal* s) { drotg_(a, b, c, s); return 0; }
/* Subroutine */ int dsvdc_(doublereal *x, integer *ldx, integer *n, integer * p, doublereal *s, doublereal *e, doublereal *u, integer *ldu, doublereal *v, integer *ldv, doublereal *work, integer *job, integer * info) { /* System generated locals */ integer x_dim1, x_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3; doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7; /* Builtin functions */ double d_sign(doublereal *, doublereal *), sqrt(doublereal); /* Local variables */ static doublereal b, c__, f, g; static integer i__, j, k, l, m; static doublereal t, t1, el; static integer kk; static doublereal cs; static integer ll, mm, ls; static doublereal sl; static integer lu; static doublereal sm, sn; static integer lm1, mm1, lp1, mp1, nct, ncu, lls, nrt; static doublereal emm1, smm1; static integer kase; extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *, integer *); static integer jobu, iter; extern /* Subroutine */ int drot_(integer *, doublereal *, integer *, doublereal *, integer *, doublereal *, doublereal *); static doublereal test; extern doublereal dnrm2_(integer *, doublereal *, integer *); static integer nctp1, nrtp1; extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *, integer *); static doublereal scale, shift; extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, doublereal *, integer *), drotg_(doublereal *, doublereal *, doublereal *, doublereal *); static integer maxit; extern /* Subroutine */ int daxpy_(integer *, doublereal *, doublereal *, integer *, doublereal *, integer *); static logical wantu, wantv; static doublereal ztest; /* dsvdc is a subroutine to reduce a double precision nxp matrix x */ /* by orthogonal transformations u and v to diagonal form. the */ /* diagonal elements s(i) are the singular values of x. the */ /* columns of u are the corresponding left singular vectors, */ /* and the columns of v the right singular vectors. */ /* on entry */ /* x double precision(ldx,p), where ldx.ge.n. */ /* x contains the matrix whose singular value */ /* decomposition is to be computed. x is */ /* destroyed by dsvdc. */ /* ldx integer. */ /* ldx is the leading dimension of the array x. */ /* n integer. */ /* n is the number of rows of the matrix x. */ /* p integer. */ /* p is the number of columns of the matrix x. */ /* ldu integer. */ /* ldu is the leading dimension of the array u. */ /* (see below). */ /* ldv integer. */ /* ldv is the leading dimension of the array v. */ /* (see below). */ /* work double precision(n). */ /* work is a scratch array. */ /* job integer. */ /* job controls the computation of the singular */ /* vectors. it has the decimal expansion ab */ /* with the following meaning */ /* a.eq.0 do not compute the left singular */ /* vectors. */ /* a.eq.1 return the n left singular vectors */ /* in u. */ /* a.ge.2 return the first min(n,p) singular */ /* vectors in u. */ /* b.eq.0 do not compute the right singular */ /* vectors. */ /* b.eq.1 return the right singular vectors */ /* in v. */ /* on return */ /* s double precision(mm), where mm=min(n+1,p). */ /* the first min(n,p) entries of s contain the */ /* singular values of x arranged in descending */ /* order of magnitude. */ /* e double precision(p), */ /* e ordinarily contains zeros. however see the */ /* discussion of info for exceptions. */ /* u double precision(ldu,k), where ldu.ge.n. if */ /* joba.eq.1 then k.eq.n, if joba.ge.2 */ /* then k.eq.min(n,p). */ /* u contains the matrix of left singular vectors. */ /* u is not referenced if joba.eq.0. if n.le.p */ /* or if joba.eq.2, then u may be identified with x */ /* in the subroutine call. */ /* v double precision(ldv,p), where ldv.ge.p. */ /* v contains the matrix of right singular vectors. */ /* v is not referenced if job.eq.0. if p.le.n, */ /* then v may be identified with x in the */ /* subroutine call. */ /* info integer. */ /* the singular values (and their corresponding */ /* singular vectors) s(info+1),s(info+2),...,s(m) */ /* are correct (here m=min(n,p)). thus if */ /* info.eq.0, all the singular values and their */ /* vectors are correct. in any event, the matrix */ /* b = trans(u)*x*v is the bidiagonal matrix */ /* with the elements of s on its diagonal and the */ /* elements of e on its super-diagonal (trans(u) */ /* is the transpose of u). thus the singular */ /* values of x and b are the same. */ /* linpack. this version dated 08/14/78 . */ /* correction made to shift 2/84. */ /* g.w. stewart, university of maryland, argonne national lab. */ /* dsvdc uses the following functions and subprograms. */ /* external drot */ /* blas daxpy,ddot,dscal,dswap,dnrm2,drotg */ /* fortran dabs,dmax1,max0,min0,mod,dsqrt */ /* internal variables */ /* set the maximum number of iterations. */ /* Parameter adjustments */ x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --s; --e; u_dim1 = *ldu; u_offset = 1 + u_dim1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1; v -= v_offset; --work; /* Function Body */ maxit = 30; /* determine what is to be computed. */ wantu = FALSE_; wantv = FALSE_; jobu = *job % 100 / 10; ncu = *n; if (jobu > 1) { ncu = min(*n,*p); } if (jobu != 0) { wantu = TRUE_; } if (*job % 10 != 0) { wantv = TRUE_; } /* reduce x to bidiagonal form, storing the diagonal elements */ /* in s and the super-diagonal elements in e. */ *info = 0; /* Computing MIN */ i__1 = *n - 1; nct = min(i__1,*p); /* Computing MAX */ /* Computing MIN */ i__3 = *p - 2; i__1 = 0, i__2 = min(i__3,*n); nrt = max(i__1,i__2); lu = max(nct,nrt); if (lu < 1) { goto L170; } i__1 = lu; for (l = 1; l <= i__1; ++l) { lp1 = l + 1; if (l > nct) { goto L20; } /* compute the transformation for the l-th column and */ /* place the l-th diagonal in s(l). */ i__2 = *n - l + 1; s[l] = dnrm2_(&i__2, &x[l + l * x_dim1], &c__1); if (s[l] == 0.) { goto L10; } if (x[l + l * x_dim1] != 0.) { s[l] = d_sign(&s[l], &x[l + l * x_dim1]); } i__2 = *n - l + 1; d__1 = 1. / s[l]; dscal_(&i__2, &d__1, &x[l + l * x_dim1], &c__1); x[l + l * x_dim1] += 1.; L10: s[l] = -s[l]; L20: if (*p < lp1) { goto L50; } i__2 = *p; for (j = lp1; j <= i__2; ++j) { if (l > nct) { goto L30; } if (s[l] == 0.) { goto L30; } /* apply the transformation. */ i__3 = *n - l + 1; t = -ddot_(&i__3, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1], & c__1) / x[l + l * x_dim1]; i__3 = *n - l + 1; daxpy_(&i__3, &t, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1], & c__1); L30: /* place the l-th row of x into e for the */ /* subsequent calculation of the row transformation. */ e[j] = x[l + j * x_dim1]; /* L40: */ } L50: if (! wantu || l > nct) { goto L70; } /* place the transformation in u for subsequent back */ /* multiplication. */ i__2 = *n; for (i__ = l; i__ <= i__2; ++i__) { u[i__ + l * u_dim1] = x[i__ + l * x_dim1]; /* L60: */ } L70: if (l > nrt) { goto L150; } /* compute the l-th row transformation and place the */ /* l-th super-diagonal in e(l). */ i__2 = *p - l; e[l] = dnrm2_(&i__2, &e[lp1], &c__1); if (e[l] == 0.) { goto L80; } if (e[lp1] != 0.) { e[l] = d_sign(&e[l], &e[lp1]); } i__2 = *p - l; d__1 = 1. / e[l]; dscal_(&i__2, &d__1, &e[lp1], &c__1); e[lp1] += 1.; L80: e[l] = -e[l]; if (lp1 > *n || e[l] == 0.) { goto L120; } /* apply the transformation. */ i__2 = *n; for (i__ = lp1; i__ <= i__2; ++i__) { work[i__] = 0.; /* L90: */ } i__2 = *p; for (j = lp1; j <= i__2; ++j) { i__3 = *n - l; daxpy_(&i__3, &e[j], &x[lp1 + j * x_dim1], &c__1, &work[lp1], & c__1); /* L100: */ } i__2 = *p; for (j = lp1; j <= i__2; ++j) { i__3 = *n - l; d__1 = -e[j] / e[lp1]; daxpy_(&i__3, &d__1, &work[lp1], &c__1, &x[lp1 + j * x_dim1], & c__1); /* L110: */ } L120: if (! wantv) { goto L140; } /* place the transformation in v for subsequent */ /* back multiplication. */ i__2 = *p; for (i__ = lp1; i__ <= i__2; ++i__) { v[i__ + l * v_dim1] = e[i__]; /* L130: */ } L140: L150: /* L160: */ ; } L170: /* set up the final bidiagonal matrix or order m. */ /* Computing MIN */ i__1 = *p, i__2 = *n + 1; m = min(i__1,i__2); nctp1 = nct + 1; nrtp1 = nrt + 1; if (nct < *p) { s[nctp1] = x[nctp1 + nctp1 * x_dim1]; } if (*n < m) { s[m] = 0.; } if (nrtp1 < m) { e[nrtp1] = x[nrtp1 + m * x_dim1]; } e[m] = 0.; /* if required, generate u. */ if (! wantu) { goto L300; } if (ncu < nctp1) { goto L200; } i__1 = ncu; for (j = nctp1; j <= i__1; ++j) { i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { u[i__ + j * u_dim1] = 0.; /* L180: */ } u[j + j * u_dim1] = 1.; /* L190: */ } L200: if (nct < 1) { goto L290; } i__1 = nct; for (ll = 1; ll <= i__1; ++ll) { l = nct - ll + 1; if (s[l] == 0.) { goto L250; } lp1 = l + 1; if (ncu < lp1) { goto L220; } i__2 = ncu; for (j = lp1; j <= i__2; ++j) { i__3 = *n - l + 1; t = -ddot_(&i__3, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1], & c__1) / u[l + l * u_dim1]; i__3 = *n - l + 1; daxpy_(&i__3, &t, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1], & c__1); /* L210: */ } L220: i__2 = *n - l + 1; dscal_(&i__2, &c_b44, &u[l + l * u_dim1], &c__1); u[l + l * u_dim1] += 1.; lm1 = l - 1; if (lm1 < 1) { goto L240; } i__2 = lm1; for (i__ = 1; i__ <= i__2; ++i__) { u[i__ + l * u_dim1] = 0.; /* L230: */ } L240: goto L270; L250: i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { u[i__ + l * u_dim1] = 0.; /* L260: */ } u[l + l * u_dim1] = 1.; L270: /* L280: */ ; } L290: L300: /* if it is required, generate v. */ if (! wantv) { goto L350; } i__1 = *p; for (ll = 1; ll <= i__1; ++ll) { l = *p - ll + 1; lp1 = l + 1; if (l > nrt) { goto L320; } if (e[l] == 0.) { goto L320; } i__2 = *p; for (j = lp1; j <= i__2; ++j) { i__3 = *p - l; t = -ddot_(&i__3, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1) / v[lp1 + l * v_dim1]; i__3 = *p - l; daxpy_(&i__3, &t, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1); /* L310: */ } L320: i__2 = *p; for (i__ = 1; i__ <= i__2; ++i__) { v[i__ + l * v_dim1] = 0.; /* L330: */ } v[l + l * v_dim1] = 1.; /* L340: */ } L350: /* main iteration loop for the singular values. */ mm = m; iter = 0; L360: /* quit if all the singular values have been found. */ /* ...exit */ if (m == 0) { goto L620; } /* if too many iterations have been performed, set */ /* flag and return. */ if (iter < maxit) { goto L370; } *info = m; /* ......exit */ goto L620; L370: /* this section of the program inspects for */ /* negligible elements in the s and e arrays. on */ /* completion the variables kase and l are set as follows. */ /* kase = 1 if s(m) and e(l-1) are negligible and l.lt.m */ /* kase = 2 if s(l) is negligible and l.lt.m */ /* kase = 3 if e(l-1) is negligible, l.lt.m, and */ /* s(l), ..., s(m) are not negligible (qr step). */ /* kase = 4 if e(m-1) is negligible (convergence). */ i__1 = m; for (ll = 1; ll <= i__1; ++ll) { l = m - ll; /* ...exit */ if (l == 0) { goto L400; } test = (d__1 = s[l], abs(d__1)) + (d__2 = s[l + 1], abs(d__2)); ztest = test + (d__1 = e[l], abs(d__1)); if (ztest != test) { goto L380; } e[l] = 0.; /* ......exit */ goto L400; L380: /* L390: */ ; } L400: if (l != m - 1) { goto L410; } kase = 4; goto L480; L410: lp1 = l + 1; mp1 = m + 1; i__1 = mp1; for (lls = lp1; lls <= i__1; ++lls) { ls = m - lls + lp1; /* ...exit */ if (ls == l) { goto L440; } test = 0.; if (ls != m) { test += (d__1 = e[ls], abs(d__1)); } if (ls != l + 1) { test += (d__1 = e[ls - 1], abs(d__1)); } ztest = test + (d__1 = s[ls], abs(d__1)); if (ztest != test) { goto L420; } s[ls] = 0.; /* ......exit */ goto L440; L420: /* L430: */ ; } L440: if (ls != l) { goto L450; } kase = 3; goto L470; L450: if (ls != m) { goto L460; } kase = 1; goto L470; L460: kase = 2; l = ls; L470: L480: ++l; /* perform the task indicated by kase. */ switch (kase) { case 1: goto L490; case 2: goto L520; case 3: goto L540; case 4: goto L570; } /* deflate negligible s(m). */ L490: mm1 = m - 1; f = e[m - 1]; e[m - 1] = 0.; i__1 = mm1; for (kk = l; kk <= i__1; ++kk) { k = mm1 - kk + l; t1 = s[k]; drotg_(&t1, &f, &cs, &sn); s[k] = t1; if (k == l) { goto L500; } f = -sn * e[k - 1]; e[k - 1] = cs * e[k - 1]; L500: if (wantv) { drot_(p, &v[k * v_dim1 + 1], &c__1, &v[m * v_dim1 + 1], &c__1, & cs, &sn); } /* L510: */ } goto L610; /* split at negligible s(l). */ L520: f = e[l - 1]; e[l - 1] = 0.; i__1 = m; for (k = l; k <= i__1; ++k) { t1 = s[k]; drotg_(&t1, &f, &cs, &sn); s[k] = t1; f = -sn * e[k]; e[k] = cs * e[k]; if (wantu) { drot_(n, &u[k * u_dim1 + 1], &c__1, &u[(l - 1) * u_dim1 + 1], & c__1, &cs, &sn); } /* L530: */ } goto L610; /* perform one qr step. */ L540: /* calculate the shift. */ /* Computing MAX */ d__6 = (d__1 = s[m], abs(d__1)), d__7 = (d__2 = s[m - 1], abs(d__2)), d__6 = max(d__6,d__7), d__7 = (d__3 = e[m - 1], abs(d__3)), d__6 = max(d__6,d__7), d__7 = (d__4 = s[l], abs(d__4)), d__6 = max(d__6, d__7), d__7 = (d__5 = e[l], abs(d__5)); scale = max(d__6,d__7); sm = s[m] / scale; smm1 = s[m - 1] / scale; emm1 = e[m - 1] / scale; sl = s[l] / scale; el = e[l] / scale; /* Computing 2nd power */ d__1 = emm1; b = ((smm1 + sm) * (smm1 - sm) + d__1 * d__1) / 2.; /* Computing 2nd power */ d__1 = sm * emm1; c__ = d__1 * d__1; shift = 0.; if (b == 0. && c__ == 0.) { goto L550; } /* Computing 2nd power */ d__1 = b; shift = sqrt(d__1 * d__1 + c__); if (b < 0.) { shift = -shift; } shift = c__ / (b + shift); L550: f = (sl + sm) * (sl - sm) + shift; g = sl * el; /* chase zeros. */ mm1 = m - 1; i__1 = mm1; for (k = l; k <= i__1; ++k) { drotg_(&f, &g, &cs, &sn); if (k != l) { e[k - 1] = f; } f = cs * s[k] + sn * e[k]; e[k] = cs * e[k] - sn * s[k]; g = sn * s[k + 1]; s[k + 1] = cs * s[k + 1]; if (wantv) { drot_(p, &v[k * v_dim1 + 1], &c__1, &v[(k + 1) * v_dim1 + 1], & c__1, &cs, &sn); } drotg_(&f, &g, &cs, &sn); s[k] = f; f = cs * e[k] + sn * s[k + 1]; s[k + 1] = -sn * e[k] + cs * s[k + 1]; g = sn * e[k + 1]; e[k + 1] = cs * e[k + 1]; if (wantu && k < *n) { drot_(n, &u[k * u_dim1 + 1], &c__1, &u[(k + 1) * u_dim1 + 1], & c__1, &cs, &sn); } /* L560: */ } e[m - 1] = f; ++iter; goto L610; /* convergence. */ L570: /* make the singular value positive. */ if (s[l] >= 0.) { goto L580; } s[l] = -s[l]; if (wantv) { dscal_(p, &c_b44, &v[l * v_dim1 + 1], &c__1); } L580: /* order the singular value. */ L590: if (l == mm) { goto L600; } /* ...exit */ if (s[l] >= s[l + 1]) { goto L600; } t = s[l]; s[l] = s[l + 1]; s[l + 1] = t; if (wantv && l < *p) { dswap_(p, &v[l * v_dim1 + 1], &c__1, &v[(l + 1) * v_dim1 + 1], &c__1); } if (wantu && l < *n) { dswap_(n, &u[l * u_dim1 + 1], &c__1, &u[(l + 1) * u_dim1 + 1], &c__1); } ++l; goto L590; L600: iter = 0; --m; L610: goto L360; L620: return 0; } /* dsvdc_ */
/* DECK DBOLSM */ /* Subroutine */ int dbolsm_(doublereal *w, integer *mdw, integer *minput, integer *ncols, doublereal *bl, doublereal *bu, integer *ind, integer *iopt, doublereal *x, doublereal *rnorm, integer *mode, doublereal * rw, doublereal *ww, doublereal *scl, integer *ibasis, integer *ibb) { /* System generated locals */ address a__1[3], a__2[4], a__3[6], a__4[5], a__5[2], a__6[7]; integer w_dim1, w_offset, i__1[3], i__2[4], i__3, i__4[6], i__5[5], i__6[ 2], i__7[7], i__8, i__9, i__10; doublereal d__1, d__2; char ch__1[47], ch__2[50], ch__3[79], ch__4[53], ch__5[94], ch__6[75], ch__7[83], ch__8[92], ch__9[105], ch__10[102], ch__11[61], ch__12[ 110], ch__13[134], ch__14[44], ch__15[76]; /* Local variables */ static integer i__, j; static doublereal t, t1, t2, sc; static integer ip, jp, lp; static doublereal ss, wt, cl1, cl2, cl3, fac, big; static integer lds; static doublereal bou, beta; static integer jbig, jmag, ioff, jcol; static doublereal wbig; extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *, integer *); static doublereal wmag; static integer mval, iter; extern /* Subroutine */ int drot_(integer *, doublereal *, integer *, doublereal *, integer *, doublereal *, doublereal *); static doublereal xnew; extern doublereal dnrm2_(integer *, doublereal *, integer *); static char xern1[8], xern2[8], xern3[16], xern4[16]; static doublereal alpha; static logical found; static integer nsetb; extern /* Subroutine */ int drotg_(doublereal *, doublereal *, doublereal *, doublereal *), dcopy_(integer *, doublereal *, integer *, doublereal *, integer *); static integer igopr, itmax, itemp; extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, doublereal *, integer *), daxpy_(integer *, doublereal *, doublereal *, integer *, doublereal *, integer *); static integer lgopr; extern /* Subroutine */ int dmout_(integer *, integer *, integer *, doublereal *, char *, integer *, ftnlen); static integer jdrop; extern doublereal d1mach_(integer *); extern /* Subroutine */ int dvout_(integer *, doublereal *, char *, integer *, ftnlen), ivout_(integer *, integer *, char *, integer * , ftnlen); static integer mrows, jdrop1, jdrop2, jlarge; static doublereal colabv, colblo, wlarge, tolind; extern /* Subroutine */ int xermsg_(char *, char *, char *, integer *, integer *, ftnlen, ftnlen, ftnlen); static integer iprint; static logical constr; static doublereal tolsze; /* Fortran I/O blocks */ static icilist io___2 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___3 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___4 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___6 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___8 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___9 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___10 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___12 = { 0, xern3, 0, "(1PD15.6)", 16, 1 }; static icilist io___14 = { 0, xern4, 0, "(1PD15.6)", 16, 1 }; static icilist io___15 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___16 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___17 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___18 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___31 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___32 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___33 = { 0, xern3, 0, "(1PD15.6)", 16, 1 }; static icilist io___34 = { 0, xern4, 0, "(1PD15.6)", 16, 1 }; static icilist io___35 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___36 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___37 = { 0, xern3, 0, "(1PD15.6)", 16, 1 }; static icilist io___38 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___39 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___40 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___41 = { 0, xern3, 0, "(1PD15.6)", 16, 1 }; static icilist io___42 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___43 = { 0, xern2, 0, "(I8)", 8, 1 }; static icilist io___44 = { 0, xern3, 0, "(1PD15.6)", 16, 1 }; static icilist io___45 = { 0, xern1, 0, "(I8)", 8, 1 }; static icilist io___54 = { 0, xern1, 0, "(I8)", 8, 1 }; /* ***BEGIN PROLOGUE DBOLSM */ /* ***SUBSIDIARY */ /* ***PURPOSE Subsidiary to DBOCLS and DBOLS */ /* ***LIBRARY SLATEC */ /* ***TYPE DOUBLE PRECISION (SBOLSM-S, DBOLSM-D) */ /* ***AUTHOR (UNKNOWN) */ /* ***DESCRIPTION */ /* **** Double Precision Version of SBOLSM **** */ /* **** All INPUT and OUTPUT real variables are DOUBLE PRECISION **** */ /* Solve E*X = F (least squares sense) with bounds on */ /* selected X values. */ /* The user must have DIMENSION statements of the form: */ /* DIMENSION W(MDW,NCOLS+1), BL(NCOLS), BU(NCOLS), */ /* * X(NCOLS+NX), RW(NCOLS), WW(NCOLS), SCL(NCOLS) */ /* INTEGER IND(NCOLS), IOPT(1+NI), IBASIS(NCOLS), IBB(NCOLS) */ /* (Here NX=number of extra locations required for options 1,...,7; */ /* NX=0 for no options; here NI=number of extra locations possibly */ /* required for options 1-7; NI=0 for no options; NI=14 if all the */ /* options are simultaneously in use.) */ /* INPUT */ /* ----- */ /* -------------------- */ /* W(MDW,*),MINPUT,NCOLS */ /* -------------------- */ /* The array W(*,*) contains the matrix [E:F] on entry. The matrix */ /* [E:F] has MINPUT rows and NCOLS+1 columns. This data is placed in */ /* the array W(*,*) with E occupying the first NCOLS columns and the */ /* right side vector F in column NCOLS+1. The row dimension, MDW, of */ /* the array W(*,*) must satisfy the inequality MDW .ge. MINPUT. */ /* Other values of MDW are errors. The values of MINPUT and NCOLS */ /* must be positive. Other values are errors. */ /* ------------------ */ /* BL(*),BU(*),IND(*) */ /* ------------------ */ /* These arrays contain the information about the bounds that the */ /* solution values are to satisfy. The value of IND(J) tells the */ /* type of bound and BL(J) and BU(J) give the explicit values for */ /* the respective upper and lower bounds. */ /* 1. For IND(J)=1, require X(J) .ge. BL(J). */ /* 2. For IND(J)=2, require X(J) .le. BU(J). */ /* 3. For IND(J)=3, require X(J) .ge. BL(J) and */ /* X(J) .le. BU(J). */ /* 4. For IND(J)=4, no bounds on X(J) are required. */ /* The values of BL(*),BL(*) are modified by the subprogram. Values */ /* other than 1,2,3 or 4 for IND(J) are errors. In the case IND(J)=3 */ /* (upper and lower bounds) the condition BL(J) .gt. BU(J) is an */ /* error. */ /* ------- */ /* IOPT(*) */ /* ------- */ /* This is the array where the user can specify nonstandard options */ /* for DBOLSM. Most of the time this feature can be ignored by */ /* setting the input value IOPT(1)=99. Occasionally users may have */ /* needs that require use of the following subprogram options. For */ /* details about how to use the options see below: IOPT(*) CONTENTS. */ /* Option Number Brief Statement of Purpose */ /* ----- ------ ----- --------- -- ------- */ /* 1 Move the IOPT(*) processing pointer. */ /* 2 Change rank determination tolerance. */ /* 3 Change blow-up factor that determines the */ /* size of variables being dropped from active */ /* status. */ /* 4 Reset the maximum number of iterations to use */ /* in solving the problem. */ /* 5 The data matrix is triangularized before the */ /* problem is solved whenever (NCOLS/MINPUT) .lt. */ /* FAC. Change the value of FAC. */ /* 6 Redefine the weighting matrix used for */ /* linear independence checking. */ /* 7 Debug output is desired. */ /* 99 No more options to change. */ /* ---- */ /* X(*) */ /* ---- */ /* This array is used to pass data associated with options 1,2,3 and */ /* 5. Ignore this input parameter if none of these options are used. */ /* Otherwise see below: IOPT(*) CONTENTS. */ /* ---------------- */ /* IBASIS(*),IBB(*) */ /* ---------------- */ /* These arrays must be initialized by the user. The values */ /* IBASIS(J)=J, J=1,...,NCOLS */ /* IBB(J) =1, J=1,...,NCOLS */ /* are appropriate except when using nonstandard features. */ /* ------ */ /* SCL(*) */ /* ------ */ /* This is the array of scaling factors to use on the columns of the */ /* matrix E. These values must be defined by the user. To suppress */ /* any column scaling set SCL(J)=1.0, J=1,...,NCOLS. */ /* OUTPUT */ /* ------ */ /* ---------- */ /* X(*),RNORM */ /* ---------- */ /* The array X(*) contains a solution (if MODE .ge. 0 or .eq. -22) */ /* for the constrained least squares problem. The value RNORM is the */ /* minimum residual vector length. */ /* ---- */ /* MODE */ /* ---- */ /* The sign of mode determines whether the subprogram has completed */ /* normally, or encountered an error condition or abnormal status. */ /* A value of MODE .ge. 0 signifies that the subprogram has completed */ /* normally. The value of MODE (.ge. 0) is the number of variables */ /* in an active status: not at a bound nor at the value ZERO, for */ /* the case of free variables. A negative value of MODE will be one */ /* of the 18 cases -38,-37,...,-22, or -1. Values .lt. -1 correspond */ /* to an abnormal completion of the subprogram. To understand the */ /* abnormal completion codes see below: ERROR MESSAGES for DBOLSM */ /* An approximate solution will be returned to the user only when */ /* maximum iterations is reached, MODE=-22. */ /* ----------- */ /* RW(*),WW(*) */ /* ----------- */ /* These are working arrays each with NCOLS entries. The array RW(*) */ /* contains the working (scaled, nonactive) solution values. The */ /* array WW(*) contains the working (scaled, active) gradient vector */ /* values. */ /* ---------------- */ /* IBASIS(*),IBB(*) */ /* ---------------- */ /* These arrays contain information about the status of the solution */ /* when MODE .ge. 0. The indices IBASIS(K), K=1,...,MODE, show the */ /* nonactive variables; indices IBASIS(K), K=MODE+1,..., NCOLS are */ /* the active variables. The value (IBB(J)-1) is the number of times */ /* variable J was reflected from its upper bound. (Normally the user */ /* can ignore these parameters.) */ /* IOPT(*) CONTENTS */ /* ------- -------- */ /* The option array allows a user to modify internal variables in */ /* the subprogram without recompiling the source code. A central */ /* goal of the initial software design was to do a good job for most */ /* people. Thus the use of options will be restricted to a select */ /* group of users. The processing of the option array proceeds as */ /* follows: a pointer, here called LP, is initially set to the value */ /* 1. The value is updated as the options are processed. At the */ /* pointer position the option number is extracted and used for */ /* locating other information that allows for options to be changed. */ /* The portion of the array IOPT(*) that is used for each option is */ /* fixed; the user and the subprogram both know how many locations */ /* are needed for each option. A great deal of error checking is */ /* done by the subprogram on the contents of the option array. */ /* Nevertheless it is still possible to give the subprogram optional */ /* input that is meaningless. For example, some of the options use */ /* the location X(NCOLS+IOFF) for passing data. The user must manage */ /* the allocation of these locations when more than one piece of */ /* option data is being passed to the subprogram. */ /* 1 */ /* - */ /* Move the processing pointer (either forward or backward) to the */ /* location IOPT(LP+1). The processing pointer is moved to location */ /* LP+2 of IOPT(*) in case IOPT(LP)=-1. For example to skip over */ /* locations 3,...,NCOLS+2 of IOPT(*), */ /* IOPT(1)=1 */ /* IOPT(2)=NCOLS+3 */ /* (IOPT(I), I=3,...,NCOLS+2 are not defined here.) */ /* IOPT(NCOLS+3)=99 */ /* CALL DBOLSM */ /* CAUTION: Misuse of this option can yield some very hard-to-find */ /* bugs. Use it with care. */ /* 2 */ /* - */ /* The algorithm that solves the bounded least squares problem */ /* iteratively drops columns from the active set. This has the */ /* effect of joining a new column vector to the QR factorization of */ /* the rectangular matrix consisting of the partially triangularized */ /* nonactive columns. After triangularizing this matrix a test is */ /* made on the size of the pivot element. The column vector is */ /* rejected as dependent if the magnitude of the pivot element is */ /* .le. TOL* magnitude of the column in components strictly above */ /* the pivot element. Nominally the value of this (rank) tolerance */ /* is TOL = SQRT(R1MACH(4)). To change only the value of TOL, for */ /* example, */ /* X(NCOLS+1)=TOL */ /* IOPT(1)=2 */ /* IOPT(2)=1 */ /* IOPT(3)=99 */ /* CALL DBOLSM */ /* Generally, if LP is the processing pointer for IOPT(*), */ /* X(NCOLS+IOFF)=TOL */ /* IOPT(LP)=2 */ /* IOPT(LP+1)=IOFF */ /* . */ /* CALL DBOLSM */ /* The required length of IOPT(*) is increased by 2 if option 2 is */ /* used; The required length of X(*) is increased by 1. A value of */ /* IOFF .le. 0 is an error. A value of TOL .le. R1MACH(4) gives a */ /* warning message; it is not considered an error. */ /* 3 */ /* - */ /* A solution component is left active (not used) if, roughly */ /* speaking, it seems too large. Mathematically the new component is */ /* left active if the magnitude is .ge.((vector norm of F)/(matrix */ /* norm of E))/BLOWUP. Nominally the factor BLOWUP = SQRT(R1MACH(4)). */ /* To change only the value of BLOWUP, for example, */ /* X(NCOLS+2)=BLOWUP */ /* IOPT(1)=3 */ /* IOPT(2)=2 */ /* IOPT(3)=99 */ /* CALL DBOLSM */ /* Generally, if LP is the processing pointer for IOPT(*), */ /* X(NCOLS+IOFF)=BLOWUP */ /* IOPT(LP)=3 */ /* IOPT(LP+1)=IOFF */ /* . */ /* CALL DBOLSM */ /* The required length of IOPT(*) is increased by 2 if option 3 is */ /* used; the required length of X(*) is increased by 1. A value of */ /* IOFF .le. 0 is an error. A value of BLOWUP .le. 0.0 is an error. */ /* 4 */ /* - */ /* Normally the algorithm for solving the bounded least squares */ /* problem requires between NCOLS/3 and NCOLS drop-add steps to */ /* converge. (this remark is based on examining a small number of */ /* test cases.) The amount of arithmetic for such problems is */ /* typically about twice that required for linear least squares if */ /* there are no bounds and if plane rotations are used in the */ /* solution method. Convergence of the algorithm, while */ /* mathematically certain, can be much slower than indicated. To */ /* avoid this potential but unlikely event ITMAX drop-add steps are */ /* permitted. Nominally ITMAX=5*(MAX(MINPUT,NCOLS)). To change the */ /* value of ITMAX, for example, */ /* IOPT(1)=4 */ /* IOPT(2)=ITMAX */ /* IOPT(3)=99 */ /* CALL DBOLSM */ /* Generally, if LP is the processing pointer for IOPT(*), */ /* IOPT(LP)=4 */ /* IOPT(LP+1)=ITMAX */ /* . */ /* CALL DBOLSM */ /* The value of ITMAX must be .gt. 0. Other values are errors. Use */ /* of this option increases the required length of IOPT(*) by 2. */ /* 5 */ /* - */ /* For purposes of increased efficiency the MINPUT by NCOLS+1 data */ /* matrix [E:F] is triangularized as a first step whenever MINPUT */ /* satisfies FAC*MINPUT .gt. NCOLS. Nominally FAC=0.75. To change the */ /* value of FAC, */ /* X(NCOLS+3)=FAC */ /* IOPT(1)=5 */ /* IOPT(2)=3 */ /* IOPT(3)=99 */ /* CALL DBOLSM */ /* Generally, if LP is the processing pointer for IOPT(*), */ /* X(NCOLS+IOFF)=FAC */ /* IOPT(LP)=5 */ /* IOPT(LP+1)=IOFF */ /* . */ /* CALL DBOLSM */ /* The value of FAC must be nonnegative. Other values are errors. */ /* Resetting FAC=0.0 suppresses the initial triangularization step. */ /* Use of this option increases the required length of IOPT(*) by 2; */ /* The required length of of X(*) is increased by 1. */ /* 6 */ /* - */ /* The norm used in testing the magnitudes of the pivot element */ /* compared to the mass of the column above the pivot line can be */ /* changed. The type of change that this option allows is to weight */ /* the components with an index larger than MVAL by the parameter */ /* WT. Normally MVAL=0 and WT=1. To change both the values MVAL and */ /* WT, where LP is the processing pointer for IOPT(*), */ /* X(NCOLS+IOFF)=WT */ /* IOPT(LP)=6 */ /* IOPT(LP+1)=IOFF */ /* IOPT(LP+2)=MVAL */ /* Use of this option increases the required length of IOPT(*) by 3. */ /* The length of X(*) is increased by 1. Values of MVAL must be */ /* nonnegative and not greater than MINPUT. Other values are errors. */ /* The value of WT must be positive. Any other value is an error. If */ /* either error condition is present a message will be printed. */ /* 7 */ /* - */ /* Debug output, showing the detailed add-drop steps for the */ /* constrained least squares problem, is desired. This option is */ /* intended to be used to locate suspected bugs. */ /* 99 */ /* -- */ /* There are no more options to change. */ /* The values for options are 1,...,7,99, and are the only ones */ /* permitted. Other values are errors. Options -99,-1,...,-7 mean */ /* that the repective options 99,1,...,7 are left at their default */ /* values. An example is the option to modify the (rank) tolerance: */ /* X(NCOLS+1)=TOL */ /* IOPT(1)=-2 */ /* IOPT(2)=1 */ /* IOPT(3)=99 */ /* Error Messages for DBOLSM */ /* ----- -------- --- --------- */ /* -22 MORE THAN ITMAX = ... ITERATIONS SOLVING BOUNDED LEAST */ /* SQUARES PROBLEM. */ /* -23 THE OPTION NUMBER = ... IS NOT DEFINED. */ /* -24 THE OFFSET = ... BEYOND POSTION NCOLS = ... MUST BE POSITIVE */ /* FOR OPTION NUMBER 2. */ /* -25 THE TOLERANCE FOR RANK DETERMINATION = ... IS LESS THAN */ /* MACHINE PRECISION = .... */ /* -26 THE OFFSET = ... BEYOND POSITION NCOLS = ... MUST BE POSTIVE */ /* FOR OPTION NUMBER 3. */ /* -27 THE RECIPROCAL OF THE BLOW-UP FACTOR FOR REJECTING VARIABLES */ /* MUST BE POSITIVE. NOW = .... */ /* -28 THE MAXIMUM NUMBER OF ITERATIONS = ... MUST BE POSITIVE. */ /* -29 THE OFFSET = ... BEYOND POSITION NCOLS = ... MUST BE POSTIVE */ /* FOR OPTION NUMBER 5. */ /* -30 THE FACTOR (NCOLS/MINPUT) WHERE PRETRIANGULARIZING IS */ /* PERFORMED MUST BE NONNEGATIVE. NOW = .... */ /* -31 THE NUMBER OF ROWS = ... MUST BE POSITIVE. */ /* -32 THE NUMBER OF COLUMNS = ... MUST BE POSTIVE. */ /* -33 THE ROW DIMENSION OF W(,) = ... MUST BE .GE. THE NUMBER OF */ /* ROWS = .... */ /* -34 FOR J = ... THE CONSTRAINT INDICATOR MUST BE 1-4. */ /* -35 FOR J = ... THE LOWER BOUND = ... IS .GT. THE UPPER BOUND = */ /* .... */ /* -36 THE INPUT ORDER OF COLUMNS = ... IS NOT BETWEEN 1 AND NCOLS */ /* = .... */ /* -37 THE BOUND POLARITY FLAG IN COMPONENT J = ... MUST BE */ /* POSITIVE. NOW = .... */ /* -38 THE ROW SEPARATOR TO APPLY WEIGHTING (...) MUST LIE BETWEEN */ /* 0 AND MINPUT = .... WEIGHT = ... MUST BE POSITIVE. */ /* ***SEE ALSO DBOCLS, DBOLS */ /* ***ROUTINES CALLED D1MACH, DAXPY, DCOPY, DDOT, DMOUT, DNRM2, DROT, */ /* DROTG, DSWAP, DVOUT, IVOUT, XERMSG */ /* ***REVISION HISTORY (YYMMDD) */ /* 821220 DATE WRITTEN */ /* 891214 Prologue converted to Version 4.0 format. (BAB) */ /* 900328 Added TYPE section. (WRB) */ /* 900510 Convert XERRWV calls to XERMSG calls. (RWC) */ /* 920422 Fixed usage of MINPUT. (WRB) */ /* 901009 Editorial changes, code now reads from top to bottom. (RWC) */ /* ***END PROLOGUE DBOLSM */ /* PURPOSE */ /* ------- */ /* THIS IS THE MAIN SUBPROGRAM THAT SOLVES THE BOUNDED */ /* LEAST SQUARES PROBLEM. THE PROBLEM SOLVED HERE IS: */ /* SOLVE E*X = F (LEAST SQUARES SENSE) */ /* WITH BOUNDS ON SELECTED X VALUES. */ /* TO CHANGE THIS SUBPROGRAM FROM SINGLE TO DOUBLE PRECISION BEGIN */ /* EDITING AT THE CARD 'C++'. */ /* CHANGE THE SUBPROGRAM NAME TO DBOLSM AND THE STRINGS */ /* /SAXPY/ TO /DAXPY/, /SCOPY/ TO /DCOPY/, */ /* /SDOT/ TO /DDOT/, /SNRM2/ TO /DNRM2/, */ /* /SROT/ TO /DROT/, /SROTG/ TO /DROTG/, /R1MACH/ TO /D1MACH/, */ /* /SVOUT/ TO /DVOUT/, /SMOUT/ TO /DMOUT/, */ /* /SSWAP/ TO /DSWAP/, /E0/ TO /D0/, */ /* /REAL / TO /DOUBLE PRECISION/. */ /* ++ */ /* ***FIRST EXECUTABLE STATEMENT DBOLSM */ /* Verify that the problem dimensions are defined properly. */ /* Parameter adjustments */ w_dim1 = *mdw; w_offset = 1 + w_dim1; w -= w_offset; --bl; --bu; --ind; --iopt; --x; --rw; --ww; --scl; --ibasis; --ibb; /* Function Body */ if (*minput <= 0) { s_wsfi(&io___2); do_fio(&c__1, (char *)&(*minput), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 21, a__1[0] = "THE NUMBER OF ROWS = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 18, a__1[2] = " MUST BE POSITIVE."; s_cat(ch__1, a__1, i__1, &c__3, (ftnlen)47); xermsg_("SLATEC", "DBOLSM", ch__1, &c__31, &c__1, (ftnlen)6, (ftnlen) 6, (ftnlen)47); *mode = -31; return 0; } if (*ncols <= 0) { s_wsfi(&io___3); do_fio(&c__1, (char *)&(*ncols), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 24, a__1[0] = "THE NUMBER OF COLUMNS = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 18, a__1[2] = " MUST BE POSITIVE."; s_cat(ch__2, a__1, i__1, &c__3, (ftnlen)50); xermsg_("SLATEC", "DBOLSM", ch__2, &c__32, &c__1, (ftnlen)6, (ftnlen) 6, (ftnlen)50); *mode = -32; return 0; } if (*mdw < *minput) { s_wsfi(&io___4); do_fio(&c__1, (char *)&(*mdw), (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___6); do_fio(&c__1, (char *)&(*minput), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__2[0] = 28, a__2[0] = "THE ROW DIMENSION OF W(,) = "; i__2[1] = 8, a__2[1] = xern1; i__2[2] = 35, a__2[2] = " MUST BE .GE. THE NUMBER OF ROWS = "; i__2[3] = 8, a__2[3] = xern2; s_cat(ch__3, a__2, i__2, &c__4, (ftnlen)79); xermsg_("SLATEC", "DBOLSM", ch__3, &c__33, &c__1, (ftnlen)6, (ftnlen) 6, (ftnlen)79); *mode = -33; return 0; } /* Verify that bound information is correct. */ i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (ind[j] < 1 || ind[j] > 4) { s_wsfi(&io___8); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___9); do_fio(&c__1, (char *)&ind[j], (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 8, a__1[0] = "FOR J = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 37, a__1[2] = " THE CONSTRAINT INDICATOR MUST BE 1-4"; s_cat(ch__4, a__1, i__1, &c__3, (ftnlen)53); xermsg_("SLATEC", "DBOLSM", ch__4, &c__34, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)53); *mode = -34; return 0; } /* L10: */ } i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (ind[j] == 3) { if (bu[j] < bl[j]) { s_wsfi(&io___10); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___12); do_fio(&c__1, (char *)&bl[j], (ftnlen)sizeof(doublereal)); e_wsfi(); s_wsfi(&io___14); do_fio(&c__1, (char *)&bu[j], (ftnlen)sizeof(doublereal)); e_wsfi(); /* Writing concatenation */ i__4[0] = 8, a__3[0] = "FOR J = "; i__4[1] = 8, a__3[1] = xern1; i__4[2] = 19, a__3[2] = " THE LOWER BOUND = "; i__4[3] = 16, a__3[3] = xern3; i__4[4] = 27, a__3[4] = " IS .GT. THE UPPER BOUND = "; i__4[5] = 16, a__3[5] = xern4; s_cat(ch__5, a__3, i__4, &c__6, (ftnlen)94); xermsg_("SLATEC", "DBOLSM", ch__5, &c__35, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)94); *mode = -35; return 0; } } /* L20: */ } /* Check that permutation and polarity arrays have been set. */ i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (ibasis[j] < 1 || ibasis[j] > *ncols) { s_wsfi(&io___15); do_fio(&c__1, (char *)&ibasis[j], (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___16); do_fio(&c__1, (char *)&(*ncols), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__2[0] = 29, a__2[0] = "THE INPUT ORDER OF COLUMNS = "; i__2[1] = 8, a__2[1] = xern1; i__2[2] = 30, a__2[2] = " IS NOT BETWEEN 1 AND NCOLS = "; i__2[3] = 8, a__2[3] = xern2; s_cat(ch__6, a__2, i__2, &c__4, (ftnlen)75); xermsg_("SLATEC", "DBOLSM", ch__6, &c__36, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)75); *mode = -36; return 0; } if (ibb[j] <= 0) { s_wsfi(&io___17); do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___18); do_fio(&c__1, (char *)&ibb[j], (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__2[0] = 41, a__2[0] = "THE BOUND POLARITY FLAG IN COMPONENT J " "= "; i__2[1] = 8, a__2[1] = xern1; i__2[2] = 26, a__2[2] = " MUST BE POSITIVE.$$NOW = "; i__2[3] = 8, a__2[3] = xern2; s_cat(ch__7, a__2, i__2, &c__4, (ftnlen)83); xermsg_("SLATEC", "DBOLSM", ch__7, &c__37, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)83); *mode = -37; return 0; } /* L30: */ } /* Process the option array. */ fac = .75; tolind = sqrt(d1mach_(&c__4)); tolsze = sqrt(d1mach_(&c__4)); itmax = max(*minput,*ncols) * 5; wt = 1.; mval = 0; iprint = 0; /* Changes to some parameters can occur through the option array, */ /* IOPT(*). Process this array looking carefully for input data */ /* errors. */ lp = 0; lds = 0; /* Test for no more options. */ L590: lp += lds; ip = iopt[lp + 1]; jp = abs(ip); if (ip == 99) { goto L470; } else if (jp == 99) { lds = 1; } else if (jp == 1) { /* Move the IOPT(*) processing pointer. */ if (ip > 0) { lp = iopt[lp + 2] - 1; lds = 0; } else { lds = 2; } } else if (jp == 2) { /* Change tolerance for rank determination. */ if (ip > 0) { ioff = iopt[lp + 2]; if (ioff <= 0) { s_wsfi(&io___31); do_fio(&c__1, (char *)&ioff, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___32); do_fio(&c__1, (char *)&(*ncols), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__5[0] = 13, a__4[0] = "THE OFFSET = "; i__5[1] = 8, a__4[1] = xern1; i__5[2] = 25, a__4[2] = " BEYOND POSITION NCOLS = "; i__5[3] = 8, a__4[3] = xern2; i__5[4] = 38, a__4[4] = " MUST BE POSITIVE FOR OPTION NUMBER" " 2."; s_cat(ch__8, a__4, i__5, &c__5, (ftnlen)92); xermsg_("SLATEC", "DBOLSM", ch__8, &c__24, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)92); *mode = -24; return 0; } tolind = x[*ncols + ioff]; if (tolind < d1mach_(&c__4)) { s_wsfi(&io___33); do_fio(&c__1, (char *)&tolind, (ftnlen)sizeof(doublereal)); e_wsfi(); s_wsfi(&io___34); d__1 = d1mach_(&c__4); do_fio(&c__1, (char *)&d__1, (ftnlen)sizeof(doublereal)); e_wsfi(); /* Writing concatenation */ i__2[0] = 39, a__2[0] = "THE TOLERANCE FOR RANK DETERMINATIO" "N = "; i__2[1] = 16, a__2[1] = xern3; i__2[2] = 34, a__2[2] = " IS LESS THAN MACHINE PRECISION = "; i__2[3] = 16, a__2[3] = xern4; s_cat(ch__9, a__2, i__2, &c__4, (ftnlen)105); xermsg_("SLATEC", "DBOLSM", ch__9, &c__25, &c__0, (ftnlen)6, ( ftnlen)6, (ftnlen)105); *mode = -25; } } lds = 2; } else if (jp == 3) { /* Change blowup factor for allowing variables to become */ /* inactive. */ if (ip > 0) { ioff = iopt[lp + 2]; if (ioff <= 0) { s_wsfi(&io___35); do_fio(&c__1, (char *)&ioff, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___36); do_fio(&c__1, (char *)&(*ncols), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__5[0] = 13, a__4[0] = "THE OFFSET = "; i__5[1] = 8, a__4[1] = xern1; i__5[2] = 25, a__4[2] = " BEYOND POSITION NCOLS = "; i__5[3] = 8, a__4[3] = xern2; i__5[4] = 38, a__4[4] = " MUST BE POSITIVE FOR OPTION NUMBER" " 3."; s_cat(ch__8, a__4, i__5, &c__5, (ftnlen)92); xermsg_("SLATEC", "DBOLSM", ch__8, &c__26, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)92); *mode = -26; return 0; } tolsze = x[*ncols + ioff]; if (tolsze <= 0.) { s_wsfi(&io___37); do_fio(&c__1, (char *)&tolsze, (ftnlen)sizeof(doublereal)); e_wsfi(); /* Writing concatenation */ i__6[0] = 86, a__5[0] = "THE RECIPROCAL OF THE BLOW-UP FACTO" "R FOR REJECTING VARIABLES MUST BE POSITIVE.$$NOW = "; i__6[1] = 16, a__5[1] = xern3; s_cat(ch__10, a__5, i__6, &c__2, (ftnlen)102); xermsg_("SLATEC", "DBOLSM", ch__10, &c__27, &c__1, (ftnlen)6, (ftnlen)6, (ftnlen)102); *mode = -27; return 0; } } lds = 2; } else if (jp == 4) { /* Change the maximum number of iterations allowed. */ if (ip > 0) { itmax = iopt[lp + 2]; if (itmax <= 0) { s_wsfi(&io___38); do_fio(&c__1, (char *)&itmax, (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 35, a__1[0] = "THE MAXIMUM NUMBER OF ITERATIONS = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 18, a__1[2] = " MUST BE POSITIVE."; s_cat(ch__11, a__1, i__1, &c__3, (ftnlen)61); xermsg_("SLATEC", "DBOLSM", ch__11, &c__28, &c__1, (ftnlen)6, (ftnlen)6, (ftnlen)61); *mode = -28; return 0; } } lds = 2; } else if (jp == 5) { /* Change the factor for pretriangularizing the data matrix. */ if (ip > 0) { ioff = iopt[lp + 2]; if (ioff <= 0) { s_wsfi(&io___39); do_fio(&c__1, (char *)&ioff, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___40); do_fio(&c__1, (char *)&(*ncols), (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__5[0] = 13, a__4[0] = "THE OFFSET = "; i__5[1] = 8, a__4[1] = xern1; i__5[2] = 25, a__4[2] = " BEYOND POSITION NCOLS = "; i__5[3] = 8, a__4[3] = xern2; i__5[4] = 38, a__4[4] = " MUST BE POSITIVE FOR OPTION NUMBER" " 5."; s_cat(ch__8, a__4, i__5, &c__5, (ftnlen)92); xermsg_("SLATEC", "DBOLSM", ch__8, &c__29, &c__1, (ftnlen)6, ( ftnlen)6, (ftnlen)92); *mode = -29; return 0; } fac = x[*ncols + ioff]; if (fac < 0.) { s_wsfi(&io___41); do_fio(&c__1, (char *)&fac, (ftnlen)sizeof(doublereal)); e_wsfi(); /* Writing concatenation */ i__6[0] = 94, a__5[0] = "THE FACTOR (NCOLS/MINPUT) WHERE PRE" "-TRIANGULARIZING IS PERFORMED MUST BE NON-NEGATIVE.$" "$NOW = "; i__6[1] = 16, a__5[1] = xern3; s_cat(ch__12, a__5, i__6, &c__2, (ftnlen)110); xermsg_("SLATEC", "DBOLSM", ch__12, &c__30, &c__0, (ftnlen)6, (ftnlen)6, (ftnlen)110); *mode = -30; return 0; } } lds = 2; } else if (jp == 6) { /* Change the weighting factor (from 1.0) to apply to components */ /* numbered .gt. MVAL (initially set to 1.) This trick is needed */ /* for applications of this subprogram to the heavily weighted */ /* least squares problem that come from equality constraints. */ if (ip > 0) { ioff = iopt[lp + 2]; mval = iopt[lp + 3]; wt = x[*ncols + ioff]; } if (mval < 0 || mval > *minput || wt <= 0.) { s_wsfi(&io___42); do_fio(&c__1, (char *)&mval, (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___43); do_fio(&c__1, (char *)&(*minput), (ftnlen)sizeof(integer)); e_wsfi(); s_wsfi(&io___44); do_fio(&c__1, (char *)&wt, (ftnlen)sizeof(doublereal)); e_wsfi(); /* Writing concatenation */ i__7[0] = 38, a__6[0] = "THE ROW SEPARATOR TO APPLY WEIGHTING ("; i__7[1] = 8, a__6[1] = xern1; i__7[2] = 34, a__6[2] = ") MUST LIE BETWEEN 0 AND MINPUT = "; i__7[3] = 8, a__6[3] = xern2; i__7[4] = 12, a__6[4] = ".$$WEIGHT = "; i__7[5] = 16, a__6[5] = xern3; i__7[6] = 18, a__6[6] = " MUST BE POSITIVE."; s_cat(ch__13, a__6, i__7, &c__7, (ftnlen)134); xermsg_("SLATEC", "DBOLSM", ch__13, &c__38, &c__0, (ftnlen)6, ( ftnlen)6, (ftnlen)134); *mode = -38; return 0; } lds = 3; } else if (jp == 7) { /* Turn on debug output. */ if (ip > 0) { iprint = 1; } lds = 2; } else { s_wsfi(&io___45); do_fio(&c__1, (char *)&ip, (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 20, a__1[0] = "THE OPTION NUMBER = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 16, a__1[2] = " IS NOT DEFINED."; s_cat(ch__14, a__1, i__1, &c__3, (ftnlen)44); xermsg_("SLATEC", "DBOLSM", ch__14, &c__23, &c__1, (ftnlen)6, (ftnlen) 6, (ftnlen)44); *mode = -23; return 0; } goto L590; /* Pretriangularize rectangular arrays of certain sizes for */ /* increased efficiency. */ L470: if (fac * *minput > (doublereal) (*ncols)) { i__3 = *ncols + 1; for (j = 1; j <= i__3; ++j) { i__8 = j + mval + 1; for (i__ = *minput; i__ >= i__8; --i__) { drotg_(&w[i__ - 1 + j * w_dim1], &w[i__ + j * w_dim1], &sc, & ss); w[i__ + j * w_dim1] = 0.; i__9 = *ncols - j + 1; drot_(&i__9, &w[i__ - 1 + (j + 1) * w_dim1], mdw, &w[i__ + (j + 1) * w_dim1], mdw, &sc, &ss); /* L480: */ } /* L490: */ } mrows = *ncols + mval + 1; } else { mrows = *minput; } /* Set the X(*) array to zero so all components are defined. */ dcopy_(ncols, &c_b185, &c__0, &x[1], &c__1); /* The arrays IBASIS(*) and IBB(*) are initialized by the calling */ /* program and the column scaling is defined in the calling program. */ /* 'BIG' is plus infinity on this machine. */ big = d1mach_(&c__2); i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (ind[j] == 1) { bu[j] = big; } else if (ind[j] == 2) { bl[j] = -big; } else if (ind[j] == 4) { bl[j] = -big; bu[j] = big; } /* L550: */ } i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (bl[j] <= 0. && 0. <= bu[j] && (d__1 = bu[j], abs(d__1)) < (d__2 = bl[j], abs(d__2)) || bu[j] < 0.) { t = bu[j]; bu[j] = -bl[j]; bl[j] = -t; scl[j] = -scl[j]; i__8 = mrows; for (i__ = 1; i__ <= i__8; ++i__) { w[i__ + j * w_dim1] = -w[i__ + j * w_dim1]; /* L560: */ } } /* Indices in set T(=TIGHT) are denoted by negative values */ /* of IBASIS(*). */ if (bl[j] >= 0.) { ibasis[j] = -ibasis[j]; t = -bl[j]; bu[j] += t; daxpy_(&mrows, &t, &w[j * w_dim1 + 1], &c__1, &w[(*ncols + 1) * w_dim1 + 1], &c__1); } /* L570: */ } nsetb = 0; iter = 0; if (iprint > 0) { i__3 = *ncols + 1; dmout_(&mrows, &i__3, mdw, &w[w_offset], "(' PRETRI. INPUT MATRIX')", &c_n4, (ftnlen)25); dvout_(ncols, &bl[1], "(' LOWER BOUNDS')", &c_n4, (ftnlen)17); dvout_(ncols, &bu[1], "(' UPPER BOUNDS')", &c_n4, (ftnlen)17); } L580: ++iter; if (iter > itmax) { s_wsfi(&io___54); do_fio(&c__1, (char *)&itmax, (ftnlen)sizeof(integer)); e_wsfi(); /* Writing concatenation */ i__1[0] = 18, a__1[0] = "MORE THAN ITMAX = "; i__1[1] = 8, a__1[1] = xern1; i__1[2] = 50, a__1[2] = " ITERATIONS SOLVING BOUNDED LEAST SQUARES P" "ROBLEM."; s_cat(ch__15, a__1, i__1, &c__3, (ftnlen)76); xermsg_("SLATEC", "DBOLSM", ch__15, &c__22, &c__1, (ftnlen)6, (ftnlen) 6, (ftnlen)76); *mode = -22; /* Rescale and translate variables. */ igopr = 1; goto L130; } /* Find a variable to become non-active. */ /* T */ /* Compute (negative) of gradient vector, W = E *(F-E*X). */ dcopy_(ncols, &c_b185, &c__0, &ww[1], &c__1); i__3 = *ncols; for (j = nsetb + 1; j <= i__3; ++j) { jcol = (i__8 = ibasis[j], abs(i__8)); i__8 = mrows - nsetb; /* Computing MIN */ i__9 = nsetb + 1; /* Computing MIN */ i__10 = nsetb + 1; ww[j] = ddot_(&i__8, &w[min(i__9,mrows) + j * w_dim1], &c__1, &w[min( i__10,mrows) + (*ncols + 1) * w_dim1], &c__1) * (d__1 = scl[ jcol], abs(d__1)); /* L200: */ } if (iprint > 0) { dvout_(ncols, &ww[1], "(' GRADIENT VALUES')", &c_n4, (ftnlen)20); ivout_(ncols, &ibasis[1], "(' INTERNAL VARIABLE ORDER')", &c_n4, ( ftnlen)28); ivout_(ncols, &ibb[1], "(' BOUND POLARITY')", &c_n4, (ftnlen)19); } /* If active set = number of total rows, quit. */ L210: if (nsetb == mrows) { found = FALSE_; goto L120; } /* Choose an extremal component of gradient vector for a candidate */ /* to become non-active. */ wlarge = -big; wmag = -big; i__3 = *ncols; for (j = nsetb + 1; j <= i__3; ++j) { t = ww[j]; if (t == big) { goto L220; } itemp = ibasis[j]; jcol = abs(itemp); i__8 = mval - nsetb; /* Computing MIN */ i__9 = nsetb + 1; t1 = dnrm2_(&i__8, &w[min(i__9,mrows) + j * w_dim1], &c__1); if (itemp < 0) { if (ibb[jcol] % 2 == 0) { t = -t; } if (t < 0.) { goto L220; } if (mval > nsetb) { t = t1; } if (t > wlarge) { wlarge = t; jlarge = j; } } else { if (mval > nsetb) { t = t1; } if (abs(t) > wmag) { wmag = abs(t); jmag = j; } } L220: ; } /* Choose magnitude of largest component of gradient for candidate. */ jbig = 0; wbig = 0.; if (wlarge > 0.) { jbig = jlarge; wbig = wlarge; } if (wmag >= wbig) { jbig = jmag; wbig = wmag; } if (jbig == 0) { found = FALSE_; if (iprint > 0) { ivout_(&c__0, &i__, "(' FOUND NO VARIABLE TO ENTER')", &c_n4, ( ftnlen)31); } goto L120; } /* See if the incoming column is sufficiently independent. This */ /* test is made before an elimination is performed. */ if (iprint > 0) { ivout_(&c__1, &jbig, "(' TRY TO BRING IN THIS COL.')", &c_n4, (ftnlen) 30); } if (mval <= nsetb) { cl1 = dnrm2_(&mval, &w[jbig * w_dim1 + 1], &c__1); i__3 = nsetb - mval; /* Computing MIN */ i__8 = mval + 1; cl2 = abs(wt) * dnrm2_(&i__3, &w[min(i__8,mrows) + jbig * w_dim1], & c__1); i__3 = mrows - nsetb; /* Computing MIN */ i__8 = nsetb + 1; cl3 = abs(wt) * dnrm2_(&i__3, &w[min(i__8,mrows) + jbig * w_dim1], & c__1); drotg_(&cl1, &cl2, &sc, &ss); colabv = abs(cl1); colblo = cl3; } else { cl1 = dnrm2_(&nsetb, &w[jbig * w_dim1 + 1], &c__1); i__3 = mval - nsetb; /* Computing MIN */ i__8 = nsetb + 1; cl2 = dnrm2_(&i__3, &w[min(i__8,mrows) + jbig * w_dim1], &c__1); i__3 = mrows - mval; /* Computing MIN */ i__8 = mval + 1; cl3 = abs(wt) * dnrm2_(&i__3, &w[min(i__8,mrows) + jbig * w_dim1], & c__1); colabv = cl1; drotg_(&cl2, &cl3, &sc, &ss); colblo = abs(cl2); } if (colblo <= tolind * colabv) { ww[jbig] = big; if (iprint > 0) { ivout_(&c__0, &i__, "(' VARIABLE IS DEPENDENT, NOT USED.')", & c_n4, (ftnlen)37); } goto L210; } /* Swap matrix columns NSETB+1 and JBIG, plus pointer information, */ /* and gradient values. */ ++nsetb; if (nsetb != jbig) { dswap_(&mrows, &w[nsetb * w_dim1 + 1], &c__1, &w[jbig * w_dim1 + 1], & c__1); dswap_(&c__1, &ww[nsetb], &c__1, &ww[jbig], &c__1); itemp = ibasis[nsetb]; ibasis[nsetb] = ibasis[jbig]; ibasis[jbig] = itemp; } /* Eliminate entries below the pivot line in column NSETB. */ if (mrows > nsetb) { i__3 = nsetb + 1; for (i__ = mrows; i__ >= i__3; --i__) { if (i__ == mval + 1) { goto L230; } drotg_(&w[i__ - 1 + nsetb * w_dim1], &w[i__ + nsetb * w_dim1], & sc, &ss); w[i__ + nsetb * w_dim1] = 0.; i__8 = *ncols - nsetb + 1; drot_(&i__8, &w[i__ - 1 + (nsetb + 1) * w_dim1], mdw, &w[i__ + ( nsetb + 1) * w_dim1], mdw, &sc, &ss); L230: ; } if (mval >= nsetb && mval < mrows) { drotg_(&w[nsetb + nsetb * w_dim1], &w[mval + 1 + nsetb * w_dim1], &sc, &ss); w[mval + 1 + nsetb * w_dim1] = 0.; i__3 = *ncols - nsetb + 1; drot_(&i__3, &w[nsetb + (nsetb + 1) * w_dim1], mdw, &w[mval + 1 + (nsetb + 1) * w_dim1], mdw, &sc, &ss); } } if (w[nsetb + nsetb * w_dim1] == 0.) { ww[nsetb] = big; --nsetb; if (iprint > 0) { ivout_(&c__0, &i__, "(' PIVOT IS ZERO, NOT USED.')", &c_n4, ( ftnlen)29); } goto L210; } /* Check that new variable is moving in the right direction. */ itemp = ibasis[nsetb]; jcol = abs(itemp); xnew = w[nsetb + (*ncols + 1) * w_dim1] / w[nsetb + nsetb * w_dim1] / ( d__1 = scl[jcol], abs(d__1)); if (itemp < 0) { /* IF(WW(NSETB).GE.ZERO.AND.XNEW.LE.ZERO) exit(quit) */ /* IF(WW(NSETB).LE.ZERO.AND.XNEW.GE.ZERO) exit(quit) */ if (ww[nsetb] >= 0. && xnew <= 0. || ww[nsetb] <= 0. && xnew >= 0.) { goto L240; } } found = TRUE_; goto L120; L240: ww[nsetb] = big; --nsetb; if (iprint > 0) { ivout_(&c__0, &i__, "(' VARIABLE HAS BAD DIRECTION, NOT USED.')", & c_n4, (ftnlen)42); } goto L210; /* Solve the triangular system. */ L270: dcopy_(&nsetb, &w[(*ncols + 1) * w_dim1 + 1], &c__1, &rw[1], &c__1); for (j = nsetb; j >= 1; --j) { rw[j] /= w[j + j * w_dim1]; jcol = (i__3 = ibasis[j], abs(i__3)); t = rw[j]; if (ibb[jcol] % 2 == 0) { rw[j] = -rw[j]; } i__3 = j - 1; d__1 = -t; daxpy_(&i__3, &d__1, &w[j * w_dim1 + 1], &c__1, &rw[1], &c__1); rw[j] /= (d__1 = scl[jcol], abs(d__1)); /* L280: */ } if (iprint > 0) { dvout_(&nsetb, &rw[1], "(' SOLN. VALUES')", &c_n4, (ftnlen)17); ivout_(&nsetb, &ibasis[1], "(' COLS. USED')", &c_n4, (ftnlen)15); } if (lgopr == 2) { dcopy_(&nsetb, &rw[1], &c__1, &x[1], &c__1); i__3 = nsetb; for (j = 1; j <= i__3; ++j) { itemp = ibasis[j]; jcol = abs(itemp); if (itemp < 0) { bou = 0.; } else { bou = bl[jcol]; } if (-bou != big) { bou /= (d__1 = scl[jcol], abs(d__1)); } if (x[j] <= bou) { jdrop1 = j; goto L340; } bou = bu[jcol]; if (bou != big) { bou /= (d__1 = scl[jcol], abs(d__1)); } if (x[j] >= bou) { jdrop2 = j; goto L340; } /* L450: */ } goto L340; } /* See if the unconstrained solution (obtained by solving the */ /* triangular system) satisfies the problem bounds. */ alpha = 2.; beta = 2.; x[nsetb] = 0.; i__3 = nsetb; for (j = 1; j <= i__3; ++j) { itemp = ibasis[j]; jcol = abs(itemp); t1 = 2.; t2 = 2.; if (itemp < 0) { bou = 0.; } else { bou = bl[jcol]; } if (-bou != big) { bou /= (d__1 = scl[jcol], abs(d__1)); } if (rw[j] <= bou) { t1 = (x[j] - bou) / (x[j] - rw[j]); } bou = bu[jcol]; if (bou != big) { bou /= (d__1 = scl[jcol], abs(d__1)); } if (rw[j] >= bou) { t2 = (bou - x[j]) / (rw[j] - x[j]); } /* If not, then compute a step length so that the variables remain */ /* feasible. */ if (t1 < alpha) { alpha = t1; jdrop1 = j; } if (t2 < beta) { beta = t2; jdrop2 = j; } /* L310: */ } constr = alpha < 2. || beta < 2.; if (! constr) { /* Accept the candidate because it satisfies the stated bounds */ /* on the variables. */ dcopy_(&nsetb, &rw[1], &c__1, &x[1], &c__1); goto L580; } /* Take a step that is as large as possible with all variables */ /* remaining feasible. */ i__3 = nsetb; for (j = 1; j <= i__3; ++j) { x[j] += min(alpha,beta) * (rw[j] - x[j]); /* L330: */ } if (alpha <= beta) { jdrop2 = 0; } else { jdrop1 = 0; } L340: if (jdrop1 + jdrop2 <= 0 || nsetb <= 0) { goto L580; } /* L350: */ jdrop = jdrop1 + jdrop2; itemp = ibasis[jdrop]; jcol = abs(itemp); if (jdrop2 > 0) { /* Variable is at an upper bound. Subtract multiple of this */ /* column from right hand side. */ t = bu[jcol]; if (itemp > 0) { bu[jcol] = t - bl[jcol]; bl[jcol] = -t; itemp = -itemp; scl[jcol] = -scl[jcol]; i__3 = jdrop; for (i__ = 1; i__ <= i__3; ++i__) { w[i__ + jdrop * w_dim1] = -w[i__ + jdrop * w_dim1]; /* L360: */ } } else { ++ibb[jcol]; if (ibb[jcol] % 2 == 0) { t = -t; } } /* Variable is at a lower bound. */ } else { if ((doublereal) itemp < 0.) { t = 0.; } else { t = -bl[jcol]; bu[jcol] += t; itemp = -itemp; } } daxpy_(&jdrop, &t, &w[jdrop * w_dim1 + 1], &c__1, &w[(*ncols + 1) * w_dim1 + 1], &c__1); /* Move certain columns left to achieve upper Hessenberg form. */ dcopy_(&jdrop, &w[jdrop * w_dim1 + 1], &c__1, &rw[1], &c__1); i__3 = nsetb; for (j = jdrop + 1; j <= i__3; ++j) { ibasis[j - 1] = ibasis[j]; x[j - 1] = x[j]; dcopy_(&j, &w[j * w_dim1 + 1], &c__1, &w[(j - 1) * w_dim1 + 1], &c__1) ; /* L370: */ } ibasis[nsetb] = itemp; w[nsetb * w_dim1 + 1] = 0.; i__3 = mrows - jdrop; dcopy_(&i__3, &w[nsetb * w_dim1 + 1], &c__0, &w[jdrop + 1 + nsetb * w_dim1], &c__1); dcopy_(&jdrop, &rw[1], &c__1, &w[nsetb * w_dim1 + 1], &c__1); /* Transform the matrix from upper Hessenberg form to upper */ /* triangular form. */ --nsetb; i__3 = nsetb; for (i__ = jdrop; i__ <= i__3; ++i__) { /* Look for small pivots and avoid mixing weighted and */ /* nonweighted rows. */ if (i__ == mval) { t = 0.; i__8 = nsetb; for (j = i__; j <= i__8; ++j) { jcol = (i__9 = ibasis[j], abs(i__9)); t1 = (d__1 = w[i__ + j * w_dim1] * scl[jcol], abs(d__1)); if (t1 > t) { jbig = j; t = t1; } /* L380: */ } goto L400; } drotg_(&w[i__ + i__ * w_dim1], &w[i__ + 1 + i__ * w_dim1], &sc, &ss); w[i__ + 1 + i__ * w_dim1] = 0.; i__8 = *ncols - i__ + 1; drot_(&i__8, &w[i__ + (i__ + 1) * w_dim1], mdw, &w[i__ + 1 + (i__ + 1) * w_dim1], mdw, &sc, &ss); /* L390: */ } goto L430; /* The triangularization is completed by giving up the Hessenberg */ /* form and triangularizing a rectangular matrix. */ L400: dswap_(&mrows, &w[i__ * w_dim1 + 1], &c__1, &w[jbig * w_dim1 + 1], &c__1); dswap_(&c__1, &ww[i__], &c__1, &ww[jbig], &c__1); dswap_(&c__1, &x[i__], &c__1, &x[jbig], &c__1); itemp = ibasis[i__]; ibasis[i__] = ibasis[jbig]; ibasis[jbig] = itemp; jbig = i__; i__3 = nsetb; for (j = jbig; j <= i__3; ++j) { i__8 = mrows; for (i__ = j + 1; i__ <= i__8; ++i__) { drotg_(&w[j + j * w_dim1], &w[i__ + j * w_dim1], &sc, &ss); w[i__ + j * w_dim1] = 0.; i__9 = *ncols - j + 1; drot_(&i__9, &w[j + (j + 1) * w_dim1], mdw, &w[i__ + (j + 1) * w_dim1], mdw, &sc, &ss); /* L410: */ } /* L420: */ } /* See if the remaining coefficients are feasible. They should be */ /* because of the way MIN(ALPHA,BETA) was chosen. Any that are not */ /* feasible will be set to their bounds and appropriately translated. */ L430: jdrop1 = 0; jdrop2 = 0; lgopr = 2; goto L270; /* Find a variable to become non-active. */ L120: if (found) { lgopr = 1; goto L270; } /* Rescale and translate variables. */ igopr = 2; L130: dcopy_(&nsetb, &x[1], &c__1, &rw[1], &c__1); dcopy_(ncols, &c_b185, &c__0, &x[1], &c__1); i__3 = nsetb; for (j = 1; j <= i__3; ++j) { jcol = (i__8 = ibasis[j], abs(i__8)); x[jcol] = rw[j] * (d__1 = scl[jcol], abs(d__1)); /* L140: */ } i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (ibb[j] % 2 == 0) { x[j] = bu[j] - x[j]; } /* L150: */ } i__3 = *ncols; for (j = 1; j <= i__3; ++j) { jcol = ibasis[j]; if (jcol < 0) { x[-jcol] = bl[-jcol] + x[-jcol]; } /* L160: */ } i__3 = *ncols; for (j = 1; j <= i__3; ++j) { if (scl[j] < 0.) { x[j] = -x[j]; } /* L170: */ } i__ = max(nsetb,mval); i__3 = mrows - i__; /* Computing MIN */ i__8 = i__ + 1; *rnorm = dnrm2_(&i__3, &w[min(i__8,mrows) + (*ncols + 1) * w_dim1], &c__1) ; if (igopr == 2) { *mode = nsetb; } return 0; } /* dbolsm_ */
void drotg(double *A, double *B, double *C, double *S) { drotg_(A, B, C, S); }
GURLS_EXPORT void rotg(double *a, double *b, double *c, double *s) { drotg_(a, b, c, s); }
void cblas_drotg( double *a, double *b, double *c, double *s) { drotg_(a,b,c,s); }
/*< subroutine dsvdc(x,ldx,n,p,s,e,u,ldu,v,ldv,work,job,info) >*/ /* Subroutine */ int dsvdc_(doublereal *x, integer *ldx, integer *n, integer * p, doublereal *s, doublereal *e, doublereal *u, integer *ldu, doublereal *v, integer *ldv, doublereal *work, integer *job, integer * info) { /* System generated locals */ integer x_dim1, x_offset, u_dim1, u_offset, v_dim1, v_offset, i__1, i__2, i__3; doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7; /* Builtin functions */ double d_sign(doublereal *, doublereal *), sqrt(doublereal); /* Local variables */ doublereal b, c__, f, g; integer i__, j, k, l=0, m; doublereal t, t1, el; integer kk; doublereal cs; integer ll, mm, ls=0; doublereal sl; integer lu; doublereal sm, sn; integer lm1, mm1, lp1, mp1, nct, ncu, lls, nrt; doublereal emm1, smm1; integer kase; extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *, integer *); integer jobu, iter; extern /* Subroutine */ int drot_(integer *, doublereal *, integer *, doublereal *, integer *, doublereal *, doublereal *); doublereal test; extern doublereal dnrm2_(integer *, doublereal *, integer *); integer nctp1, nrtp1; extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *, integer *); doublereal scale, shift; extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *, doublereal *, integer *), drotg_(doublereal *, doublereal *, doublereal *, doublereal *); integer maxit; extern /* Subroutine */ int daxpy_(integer *, doublereal *, doublereal *, integer *, doublereal *, integer *); logical wantu, wantv; doublereal ztest; /*< integer ldx,n,p,ldu,ldv,job,info >*/ /*< double precision x(ldx,1),s(1),e(1),u(ldu,1),v(ldv,1),work(1) >*/ /* dsvdc is a subroutine to reduce a double precision nxp matrix x */ /* by orthogonal transformations u and v to diagonal form. the */ /* diagonal elements s(i) are the singular values of x. the */ /* columns of u are the corresponding left singular vectors, */ /* and the columns of v the right singular vectors. */ /* on entry */ /* x double precision(ldx,p), where ldx.ge.n. */ /* x contains the matrix whose singular value */ /* decomposition is to be computed. x is */ /* destroyed by dsvdc. */ /* ldx integer. */ /* ldx is the leading dimension of the array x. */ /* n integer. */ /* n is the number of rows of the matrix x. */ /* p integer. */ /* p is the number of columns of the matrix x. */ /* ldu integer. */ /* ldu is the leading dimension of the array u. */ /* (see below). */ /* ldv integer. */ /* ldv is the leading dimension of the array v. */ /* (see below). */ /* work double precision(n). */ /* work is a scratch array. */ /* job integer. */ /* job controls the computation of the singular */ /* vectors. it has the decimal expansion ab */ /* with the following meaning */ /* a.eq.0 do not compute the left singular */ /* vectors. */ /* a.eq.1 return the n left singular vectors */ /* in u. */ /* a.ge.2 return the first min(n,p) singular */ /* vectors in u. */ /* b.eq.0 do not compute the right singular */ /* vectors. */ /* b.eq.1 return the right singular vectors */ /* in v. */ /* on return */ /* s double precision(mm), where mm=min(n+1,p). */ /* the first min(n,p) entries of s contain the */ /* singular values of x arranged in descending */ /* order of magnitude. */ /* e double precision(p), */ /* e ordinarily contains zeros. however see the */ /* discussion of info for exceptions. */ /* u double precision(ldu,k), where ldu.ge.n. if */ /* joba.eq.1 then k.eq.n, if joba.ge.2 */ /* then k.eq.min(n,p). */ /* u contains the matrix of left singular vectors. */ /* u is not referenced if joba.eq.0. if n.le.p */ /* or if joba.eq.2, then u may be identified with x */ /* in the subroutine call. */ /* v double precision(ldv,p), where ldv.ge.p. */ /* v contains the matrix of right singular vectors. */ /* v is not referenced if job.eq.0. if p.le.n, */ /* then v may be identified with x in the */ /* subroutine call. */ /* info integer. */ /* the singular values (and their corresponding */ /* singular vectors) s(info+1),s(info+2),...,s(m) */ /* are correct (here m=min(n,p)). thus if */ /* info.eq.0, all the singular values and their */ /* vectors are correct. in any event, the matrix */ /* b = trans(u)*x*v is the bidiagonal matrix */ /* with the elements of s on its diagonal and the */ /* elements of e on its super-diagonal (trans(u) */ /* is the transpose of u). thus the singular */ /* values of x and b are the same. */ /* linpack. this version dated 08/14/78 . */ /* correction made to shift 2/84. */ /* g.w. stewart, university of maryland, argonne national lab. */ /* dsvdc uses the following functions and subprograms. */ /* external drot */ /* blas daxpy,ddot,dscal,dswap,dnrm2,drotg */ /* fortran dabs,dmax1,max0,min0,mod,dsqrt */ /* internal variables */ /*< >*/ /*< double precision ddot,t,r >*/ /*< >*/ /*< logical wantu,wantv >*/ /* set the maximum number of iterations. */ /*< maxit = 1000 >*/ /* Parameter adjustments */ x_dim1 = *ldx; x_offset = 1 + x_dim1; x -= x_offset; --s; --e; u_dim1 = *ldu; u_offset = 1 + u_dim1; u -= u_offset; v_dim1 = *ldv; v_offset = 1 + v_dim1; v -= v_offset; --work; /* Function Body */ maxit = 1000; /* determine what is to be computed. */ /*< wantu = .false. >*/ wantu = FALSE_; /*< wantv = .false. >*/ wantv = FALSE_; /*< jobu = mod(job,100)/10 >*/ jobu = *job % 100 / 10; /*< ncu = n >*/ ncu = *n; /*< if (jobu .gt. 1) ncu = min0(n,p) >*/ if (jobu > 1) { ncu = min(*n,*p); } /*< if (jobu .ne. 0) wantu = .true. >*/ if (jobu != 0) { wantu = TRUE_; } /*< if (mod(job,10) .ne. 0) wantv = .true. >*/ if (*job % 10 != 0) { wantv = TRUE_; } /* reduce x to bidiagonal form, storing the diagonal elements */ /* in s and the super-diagonal elements in e. */ /*< info = 0 >*/ *info = 0; /*< nct = min0(n-1,p) >*/ /* Computing MIN */ i__1 = *n - 1; nct = min(i__1,*p); /*< nrt = max0(0,min0(p-2,n)) >*/ /* Computing MAX */ /* Computing MIN */ i__3 = *p - 2; i__1 = 0, i__2 = min(i__3,*n); nrt = max(i__1,i__2); /*< lu = max0(nct,nrt) >*/ lu = max(nct,nrt); /*< if (lu .lt. 1) go to 170 >*/ if (lu < 1) { goto L170; } /*< do 160 l = 1, lu >*/ i__1 = lu; for (l = 1; l <= i__1; ++l) { /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (l .gt. nct) go to 20 >*/ if (l > nct) { goto L20; } /* compute the transformation for the l-th column and */ /* place the l-th diagonal in s(l). */ /*< s(l) = dnrm2(n-l+1,x(l,l),1) >*/ i__2 = *n - l + 1; s[l] = dnrm2_(&i__2, &x[l + l * x_dim1], &c__1); /*< if (s(l) .eq. 0.0d0) go to 10 >*/ if (s[l] == 0.) { goto L10; } /*< if (x(l,l) .ne. 0.0d0) s(l) = dsign(s(l),x(l,l)) >*/ if (x[l + l * x_dim1] != 0.) { s[l] = d_sign(&s[l], &x[l + l * x_dim1]); } /*< call dscal(n-l+1,1.0d0/s(l),x(l,l),1) >*/ i__2 = *n - l + 1; d__1 = 1. / s[l]; dscal_(&i__2, &d__1, &x[l + l * x_dim1], &c__1); /*< x(l,l) = 1.0d0 + x(l,l) >*/ x[l + l * x_dim1] += 1.; /*< 10 continue >*/ L10: /*< s(l) = -s(l) >*/ s[l] = -s[l]; /*< 20 continue >*/ L20: /*< if (p .lt. lp1) go to 50 >*/ if (*p < lp1) { goto L50; } /*< do 40 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< if (l .gt. nct) go to 30 >*/ if (l > nct) { goto L30; } /*< if (s(l) .eq. 0.0d0) go to 30 >*/ if (s[l] == 0.) { goto L30; } /* apply the transformation. */ /*< t = -ddot(n-l+1,x(l,l),1,x(l,j),1)/x(l,l) >*/ i__3 = *n - l + 1; t = -ddot_(&i__3, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1], & c__1) / x[l + l * x_dim1]; /*< call daxpy(n-l+1,t,x(l,l),1,x(l,j),1) >*/ i__3 = *n - l + 1; daxpy_(&i__3, &t, &x[l + l * x_dim1], &c__1, &x[l + j * x_dim1], & c__1); /*< 30 continue >*/ L30: /* place the l-th row of x into e for the */ /* subsequent calculation of the row transformation. */ /*< e(j) = x(l,j) >*/ e[j] = x[l + j * x_dim1]; /*< 40 continue >*/ /* L40: */ } /*< 50 continue >*/ L50: /*< if (.not.wantu .or. l .gt. nct) go to 70 >*/ if (! wantu || l > nct) { goto L70; } /* place the transformation in u for subsequent back */ /* multiplication. */ /*< do 60 i = l, n >*/ i__2 = *n; for (i__ = l; i__ <= i__2; ++i__) { /*< u(i,l) = x(i,l) >*/ u[i__ + l * u_dim1] = x[i__ + l * x_dim1]; /*< 60 continue >*/ /* L60: */ } /*< 70 continue >*/ L70: /*< if (l .gt. nrt) go to 150 >*/ if (l > nrt) { goto L150; } /* compute the l-th row transformation and place the */ /* l-th super-diagonal in e(l). */ /*< e(l) = dnrm2(p-l,e(lp1),1) >*/ i__2 = *p - l; e[l] = dnrm2_(&i__2, &e[lp1], &c__1); /*< if (e(l) .eq. 0.0d0) go to 80 >*/ if (e[l] == 0.) { goto L80; } /*< if (e(lp1) .ne. 0.0d0) e(l) = dsign(e(l),e(lp1)) >*/ if (e[lp1] != 0.) { e[l] = d_sign(&e[l], &e[lp1]); } /*< call dscal(p-l,1.0d0/e(l),e(lp1),1) >*/ i__2 = *p - l; d__1 = 1. / e[l]; dscal_(&i__2, &d__1, &e[lp1], &c__1); /*< e(lp1) = 1.0d0 + e(lp1) >*/ e[lp1] += 1.; /*< 80 continue >*/ L80: /*< e(l) = -e(l) >*/ e[l] = -e[l]; /*< if (lp1 .gt. n .or. e(l) .eq. 0.0d0) go to 120 >*/ if (lp1 > *n || e[l] == 0.) { goto L120; } /* apply the transformation. */ /*< do 90 i = lp1, n >*/ i__2 = *n; for (i__ = lp1; i__ <= i__2; ++i__) { /*< work(i) = 0.0d0 >*/ work[i__] = 0.; /*< 90 continue >*/ /* L90: */ } /*< do 100 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< call daxpy(n-l,e(j),x(lp1,j),1,work(lp1),1) >*/ i__3 = *n - l; daxpy_(&i__3, &e[j], &x[lp1 + j * x_dim1], &c__1, &work[lp1], & c__1); /*< 100 continue >*/ /* L100: */ } /*< do 110 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< call daxpy(n-l,-e(j)/e(lp1),work(lp1),1,x(lp1,j),1) >*/ i__3 = *n - l; d__1 = -e[j] / e[lp1]; daxpy_(&i__3, &d__1, &work[lp1], &c__1, &x[lp1 + j * x_dim1], & c__1); /*< 110 continue >*/ /* L110: */ } /*< 120 continue >*/ L120: /*< if (.not.wantv) go to 140 >*/ if (! wantv) { goto L140; } /* place the transformation in v for subsequent */ /* back multiplication. */ /*< do 130 i = lp1, p >*/ i__2 = *p; for (i__ = lp1; i__ <= i__2; ++i__) { /*< v(i,l) = e(i) >*/ v[i__ + l * v_dim1] = e[i__]; /*< 130 continue >*/ /* L130: */ } /*< 140 continue >*/ L140: /*< 150 continue >*/ L150: /*< 160 continue >*/ /* L160: */ ; } /*< 170 continue >*/ L170: /* set up the final bidiagonal matrix or order m. */ /*< m = min0(p,n+1) >*/ /* Computing MIN */ i__1 = *p, i__2 = *n + 1; m = min(i__1,i__2); /*< nctp1 = nct + 1 >*/ nctp1 = nct + 1; /*< nrtp1 = nrt + 1 >*/ nrtp1 = nrt + 1; /*< if (nct .lt. p) s(nctp1) = x(nctp1,nctp1) >*/ if (nct < *p) { s[nctp1] = x[nctp1 + nctp1 * x_dim1]; } /*< if (n .lt. m) s(m) = 0.0d0 >*/ if (*n < m) { s[m] = 0.; } /*< if (nrtp1 .lt. m) e(nrtp1) = x(nrtp1,m) >*/ if (nrtp1 < m) { e[nrtp1] = x[nrtp1 + m * x_dim1]; } /*< e(m) = 0.0d0 >*/ e[m] = 0.; /* if required, generate u. */ /*< if (.not.wantu) go to 300 >*/ if (! wantu) { goto L300; } /*< if (ncu .lt. nctp1) go to 200 >*/ if (ncu < nctp1) { goto L200; } /*< do 190 j = nctp1, ncu >*/ i__1 = ncu; for (j = nctp1; j <= i__1; ++j) { /*< do 180 i = 1, n >*/ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,j) = 0.0d0 >*/ u[i__ + j * u_dim1] = 0.; /*< 180 continue >*/ /* L180: */ } /*< u(j,j) = 1.0d0 >*/ u[j + j * u_dim1] = 1.; /*< 190 continue >*/ /* L190: */ } /*< 200 continue >*/ L200: /*< if (nct .lt. 1) go to 290 >*/ if (nct < 1) { goto L290; } /*< do 280 ll = 1, nct >*/ i__1 = nct; for (ll = 1; ll <= i__1; ++ll) { /*< l = nct - ll + 1 >*/ l = nct - ll + 1; /*< if (s(l) .eq. 0.0d0) go to 250 >*/ if (s[l] == 0.) { goto L250; } /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (ncu .lt. lp1) go to 220 >*/ if (ncu < lp1) { goto L220; } /*< do 210 j = lp1, ncu >*/ i__2 = ncu; for (j = lp1; j <= i__2; ++j) { /*< t = -ddot(n-l+1,u(l,l),1,u(l,j),1)/u(l,l) >*/ i__3 = *n - l + 1; t = -ddot_(&i__3, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1], & c__1) / u[l + l * u_dim1]; /*< call daxpy(n-l+1,t,u(l,l),1,u(l,j),1) >*/ i__3 = *n - l + 1; daxpy_(&i__3, &t, &u[l + l * u_dim1], &c__1, &u[l + j * u_dim1], & c__1); /*< 210 continue >*/ /* L210: */ } /*< 220 continue >*/ L220: /*< call dscal(n-l+1,-1.0d0,u(l,l),1) >*/ i__2 = *n - l + 1; dscal_(&i__2, &c_b44, &u[l + l * u_dim1], &c__1); /*< u(l,l) = 1.0d0 + u(l,l) >*/ u[l + l * u_dim1] += 1.; /*< lm1 = l - 1 >*/ lm1 = l - 1; /*< if (lm1 .lt. 1) go to 240 >*/ if (lm1 < 1) { goto L240; } /*< do 230 i = 1, lm1 >*/ i__2 = lm1; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,l) = 0.0d0 >*/ u[i__ + l * u_dim1] = 0.; /*< 230 continue >*/ /* L230: */ } /*< 240 continue >*/ L240: /*< go to 270 >*/ goto L270; /*< 250 continue >*/ L250: /*< do 260 i = 1, n >*/ i__2 = *n; for (i__ = 1; i__ <= i__2; ++i__) { /*< u(i,l) = 0.0d0 >*/ u[i__ + l * u_dim1] = 0.; /*< 260 continue >*/ /* L260: */ } /*< u(l,l) = 1.0d0 >*/ u[l + l * u_dim1] = 1.; /*< 270 continue >*/ L270: /*< 280 continue >*/ /* L280: */ ; } /*< 290 continue >*/ L290: /*< 300 continue >*/ L300: /* if it is required, generate v. */ /*< if (.not.wantv) go to 350 >*/ if (! wantv) { goto L350; } /*< do 340 ll = 1, p >*/ i__1 = *p; for (ll = 1; ll <= i__1; ++ll) { /*< l = p - ll + 1 >*/ l = *p - ll + 1; /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< if (l .gt. nrt) go to 320 >*/ if (l > nrt) { goto L320; } /*< if (e(l) .eq. 0.0d0) go to 320 >*/ if (e[l] == 0.) { goto L320; } /*< do 310 j = lp1, p >*/ i__2 = *p; for (j = lp1; j <= i__2; ++j) { /*< t = -ddot(p-l,v(lp1,l),1,v(lp1,j),1)/v(lp1,l) >*/ i__3 = *p - l; t = -ddot_(&i__3, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1) / v[lp1 + l * v_dim1]; /*< call daxpy(p-l,t,v(lp1,l),1,v(lp1,j),1) >*/ i__3 = *p - l; daxpy_(&i__3, &t, &v[lp1 + l * v_dim1], &c__1, &v[lp1 + j * v_dim1], &c__1); /*< 310 continue >*/ /* L310: */ } /*< 320 continue >*/ L320: /*< do 330 i = 1, p >*/ i__2 = *p; for (i__ = 1; i__ <= i__2; ++i__) { /*< v(i,l) = 0.0d0 >*/ v[i__ + l * v_dim1] = 0.; /*< 330 continue >*/ /* L330: */ } /*< v(l,l) = 1.0d0 >*/ v[l + l * v_dim1] = 1.; /*< 340 continue >*/ /* L340: */ } /*< 350 continue >*/ L350: /* main iteration loop for the singular values. */ /*< mm = m >*/ mm = m; /*< iter = 0 >*/ iter = 0; /*< 360 continue >*/ L360: /* quit if all the singular values have been found. */ /* ...exit */ /*< if (m .eq. 0) go to 620 >*/ if (m == 0) { goto L620; } /* if too many iterations have been performed, set */ /* flag and return. */ /*< if (iter .lt. maxit) go to 370 >*/ if (iter < maxit) { goto L370; } /*< info = m >*/ *info = m; /* ......exit */ /*< go to 620 >*/ goto L620; /*< 370 continue >*/ L370: /* this section of the program inspects for */ /* negligible elements in the s and e arrays. on */ /* completion the variables kase and l are set as follows. */ /* kase = 1 if s(m) and e(l-1) are negligible and l.lt.m */ /* kase = 2 if s(l) is negligible and l.lt.m */ /* kase = 3 if e(l-1) is negligible, l.lt.m, and */ /* s(l), ..., s(m) are not negligible (qr step). */ /* kase = 4 if e(m-1) is negligible (convergence). */ /*< do 390 ll = 1, m >*/ i__1 = m; for (ll = 1; ll <= i__1; ++ll) { /*< l = m - ll >*/ l = m - ll; /* ...exit */ /*< if (l .eq. 0) go to 400 >*/ if (l == 0) { goto L400; } /*< test = dabs(s(l)) + dabs(s(l+1)) >*/ test = (d__1 = s[l], abs(d__1)) + (d__2 = s[l + 1], abs(d__2)); /*< ztest = test + dabs(e(l)) >*/ ztest = test + (d__1 = e[l], abs(d__1)); /*< if (ztest .ne. test) go to 380 >*/ if (ztest != test) { goto L380; } /*< e(l) = 0.0d0 >*/ e[l] = 0.; /* ......exit */ /*< go to 400 >*/ goto L400; /*< 380 continue >*/ L380: /*< 390 continue >*/ /* L390: */ ; } /*< 400 continue >*/ L400: /*< if (l .ne. m - 1) go to 410 >*/ if (l != m - 1) { goto L410; } /*< kase = 4 >*/ kase = 4; /*< go to 480 >*/ goto L480; /*< 410 continue >*/ L410: /*< lp1 = l + 1 >*/ lp1 = l + 1; /*< mp1 = m + 1 >*/ mp1 = m + 1; /*< do 430 lls = lp1, mp1 >*/ i__1 = mp1; for (lls = lp1; lls <= i__1; ++lls) { /*< ls = m - lls + lp1 >*/ ls = m - lls + lp1; /* ...exit */ /*< if (ls .eq. l) go to 440 >*/ if (ls == l) { goto L440; } /*< test = 0.0d0 >*/ test = 0.; /*< if (ls .ne. m) test = test + dabs(e(ls)) >*/ if (ls != m) { test += (d__1 = e[ls], abs(d__1)); } /*< if (ls .ne. l + 1) test = test + dabs(e(ls-1)) >*/ if (ls != l + 1) { test += (d__1 = e[ls - 1], abs(d__1)); } /*< ztest = test + dabs(s(ls)) >*/ ztest = test + (d__1 = s[ls], abs(d__1)); /*< if (ztest .ne. test) go to 420 >*/ if (ztest != test) { goto L420; } /*< s(ls) = 0.0d0 >*/ s[ls] = 0.; /* ......exit */ /*< go to 440 >*/ goto L440; /*< 420 continue >*/ L420: /*< 430 continue >*/ /* L430: */ ; } /*< 440 continue >*/ L440: /*< if (ls .ne. l) go to 450 >*/ if (ls != l) { goto L450; } /*< kase = 3 >*/ kase = 3; /*< go to 470 >*/ goto L470; /*< 450 continue >*/ L450: /*< if (ls .ne. m) go to 460 >*/ if (ls != m) { goto L460; } /*< kase = 1 >*/ kase = 1; /*< go to 470 >*/ goto L470; /*< 460 continue >*/ L460: /*< kase = 2 >*/ kase = 2; /*< l = ls >*/ l = ls; /*< 470 continue >*/ L470: /*< 480 continue >*/ L480: /*< l = l + 1 >*/ ++l; /* perform the task indicated by kase. */ /*< go to (490,520,540,570), kase >*/ switch (kase) { case 1: goto L490; case 2: goto L520; case 3: goto L540; case 4: goto L570; } /* deflate negligible s(m). */ /*< 490 continue >*/ L490: /*< mm1 = m - 1 >*/ mm1 = m - 1; /*< f = e(m-1) >*/ f = e[m - 1]; /*< e(m-1) = 0.0d0 >*/ e[m - 1] = 0.; /*< do 510 kk = l, mm1 >*/ i__1 = mm1; for (kk = l; kk <= i__1; ++kk) { /*< k = mm1 - kk + l >*/ k = mm1 - kk + l; /*< t1 = s(k) >*/ t1 = s[k]; /*< call drotg(t1,f,cs,sn) >*/ drotg_(&t1, &f, &cs, &sn); /*< s(k) = t1 >*/ s[k] = t1; /*< if (k .eq. l) go to 500 >*/ if (k == l) { goto L500; } /*< f = -sn*e(k-1) >*/ f = -sn * e[k - 1]; /*< e(k-1) = cs*e(k-1) >*/ e[k - 1] = cs * e[k - 1]; /*< 500 continue >*/ L500: /*< if (wantv) call drot(p,v(1,k),1,v(1,m),1,cs,sn) >*/ if (wantv) { drot_(p, &v[k * v_dim1 + 1], &c__1, &v[m * v_dim1 + 1], &c__1, & cs, &sn); } /*< 510 continue >*/ /* L510: */ } /*< go to 610 >*/ goto L610; /* split at negligible s(l). */ /*< 520 continue >*/ L520: /*< f = e(l-1) >*/ f = e[l - 1]; /*< e(l-1) = 0.0d0 >*/ e[l - 1] = 0.; /*< do 530 k = l, m >*/ i__1 = m; for (k = l; k <= i__1; ++k) { /*< t1 = s(k) >*/ t1 = s[k]; /*< call drotg(t1,f,cs,sn) >*/ drotg_(&t1, &f, &cs, &sn); /*< s(k) = t1 >*/ s[k] = t1; /*< f = -sn*e(k) >*/ f = -sn * e[k]; /*< e(k) = cs*e(k) >*/ e[k] = cs * e[k]; /*< if (wantu) call drot(n,u(1,k),1,u(1,l-1),1,cs,sn) >*/ if (wantu) { drot_(n, &u[k * u_dim1 + 1], &c__1, &u[(l - 1) * u_dim1 + 1], & c__1, &cs, &sn); } /*< 530 continue >*/ /* L530: */ } /*< go to 610 >*/ goto L610; /* perform one qr step. */ /*< 540 continue >*/ L540: /* calculate the shift. */ /*< >*/ /* Computing MAX */ d__6 = (d__1 = s[m], abs(d__1)), d__7 = (d__2 = s[m - 1], abs(d__2)), d__6 = max(d__6,d__7), d__7 = (d__3 = e[m - 1], abs(d__3)), d__6 = max(d__6,d__7), d__7 = (d__4 = s[l], abs(d__4)), d__6 = max(d__6, d__7), d__7 = (d__5 = e[l], abs(d__5)); scale = max(d__6,d__7); /*< sm = s(m)/scale >*/ sm = s[m] / scale; /*< smm1 = s(m-1)/scale >*/ smm1 = s[m - 1] / scale; /*< emm1 = e(m-1)/scale >*/ emm1 = e[m - 1] / scale; /*< sl = s(l)/scale >*/ sl = s[l] / scale; /*< el = e(l)/scale >*/ el = e[l] / scale; /*< b = ((smm1 + sm)*(smm1 - sm) + emm1**2)/2.0d0 >*/ /* Computing 2nd power */ d__1 = emm1; b = ((smm1 + sm) * (smm1 - sm) + d__1 * d__1) / 2.; /*< c = (sm*emm1)**2 >*/ /* Computing 2nd power */ d__1 = sm * emm1; c__ = d__1 * d__1; /*< shift = 0.0d0 >*/ shift = 0.; /*< if (b .eq. 0.0d0 .and. c .eq. 0.0d0) go to 550 >*/ if (b == 0. && c__ == 0.) { goto L550; } /*< shift = dsqrt(b**2+c) >*/ /* Computing 2nd power */ d__1 = b; shift = sqrt(d__1 * d__1 + c__); /*< if (b .lt. 0.0d0) shift = -shift >*/ if (b < 0.) { shift = -shift; } /*< shift = c/(b + shift) >*/ shift = c__ / (b + shift); /*< 550 continue >*/ L550: /*< f = (sl + sm)*(sl - sm) + shift >*/ f = (sl + sm) * (sl - sm) + shift; /*< g = sl*el >*/ g = sl * el; /* chase zeros. */ /*< mm1 = m - 1 >*/ mm1 = m - 1; /*< do 560 k = l, mm1 >*/ i__1 = mm1; for (k = l; k <= i__1; ++k) { /*< call drotg(f,g,cs,sn) >*/ drotg_(&f, &g, &cs, &sn); /*< if (k .ne. l) e(k-1) = f >*/ if (k != l) { e[k - 1] = f; } /*< f = cs*s(k) + sn*e(k) >*/ f = cs * s[k] + sn * e[k]; /*< e(k) = cs*e(k) - sn*s(k) >*/ e[k] = cs * e[k] - sn * s[k]; /*< g = sn*s(k+1) >*/ g = sn * s[k + 1]; /*< s(k+1) = cs*s(k+1) >*/ s[k + 1] = cs * s[k + 1]; /*< if (wantv) call drot(p,v(1,k),1,v(1,k+1),1,cs,sn) >*/ if (wantv) { drot_(p, &v[k * v_dim1 + 1], &c__1, &v[(k + 1) * v_dim1 + 1], & c__1, &cs, &sn); } /*< call drotg(f,g,cs,sn) >*/ drotg_(&f, &g, &cs, &sn); /*< s(k) = f >*/ s[k] = f; /*< f = cs*e(k) + sn*s(k+1) >*/ f = cs * e[k] + sn * s[k + 1]; /*< s(k+1) = -sn*e(k) + cs*s(k+1) >*/ s[k + 1] = -sn * e[k] + cs * s[k + 1]; /*< g = sn*e(k+1) >*/ g = sn * e[k + 1]; /*< e(k+1) = cs*e(k+1) >*/ e[k + 1] = cs * e[k + 1]; /*< >*/ if (wantu && k < *n) { drot_(n, &u[k * u_dim1 + 1], &c__1, &u[(k + 1) * u_dim1 + 1], & c__1, &cs, &sn); } /*< 560 continue >*/ /* L560: */ } /*< e(m-1) = f >*/ e[m - 1] = f; /*< iter = iter + 1 >*/ ++iter; /*< go to 610 >*/ goto L610; /* convergence. */ /*< 570 continue >*/ L570: /* make the singular value positive. */ /*< if (s(l) .ge. 0.0d0) go to 580 >*/ if (s[l] >= 0.) { goto L580; } /*< s(l) = -s(l) >*/ s[l] = -s[l]; /*< if (wantv) call dscal(p,-1.0d0,v(1,l),1) >*/ if (wantv) { dscal_(p, &c_b44, &v[l * v_dim1 + 1], &c__1); } /*< 580 continue >*/ L580: /* order the singular value. */ /*< 590 if (l .eq. mm) go to 600 >*/ L590: if (l == mm) { goto L600; } /* ...exit */ /*< if (s(l) .ge. s(l+1)) go to 600 >*/ if (s[l] >= s[l + 1]) { goto L600; } /*< t = s(l) >*/ t = s[l]; /*< s(l) = s(l+1) >*/ s[l] = s[l + 1]; /*< s(l+1) = t >*/ s[l + 1] = t; /*< >*/ if (wantv && l < *p) { dswap_(p, &v[l * v_dim1 + 1], &c__1, &v[(l + 1) * v_dim1 + 1], &c__1); } /*< >*/ if (wantu && l < *n) { dswap_(n, &u[l * u_dim1 + 1], &c__1, &u[(l + 1) * u_dim1 + 1], &c__1); } /*< l = l + 1 >*/ ++l; /*< go to 590 >*/ goto L590; /*< 600 continue >*/ L600: /*< iter = 0 >*/ iter = 0; /*< m = m - 1 >*/ --m; /*< 610 continue >*/ L610: /*< go to 360 >*/ goto L360; /*< 620 continue >*/ L620: /*< return >*/ return 0; /*< end >*/ } /* dsvdc_ */
/* Subroutine */ int dbols_(doublereal* w, integer* mdw, integer* mrows, integer* ncols, doublereal* bl, doublereal* bu, integer* ind, integer *iopt, doublereal* x, doublereal* rnorm, integer* mode, doublereal * rw, integer* iw) { /* Initialized data */ static integer igo = 0; /* System generated locals */ integer w_dim1, w_offset, i__1, i__2, i__3; doublereal d__1; /* Local variables */ static integer i__, j; static doublereal sc; static integer ip, jp, lp; static doublereal ss; static integer llb; static doublereal one; static integer lds, llx, ibig, idum, lmdw, lndw, nerr; static real rdum; static integer lenx, lliw, mnew; extern /* Subroutine */ int drot_(integer*, doublereal*, integer*, doublereal*, integer*, doublereal*, doublereal*); static integer lopt; static doublereal zero; static integer llrw; extern doublereal dnrm2_(integer*, doublereal*, integer*); static real rdum2; static integer nchar, level; extern /* Subroutine */ int dcopy_(integer*, doublereal*, integer*, doublereal*, integer*), drotg_(doublereal*, doublereal*, doublereal*, doublereal*); static integer liopt, locacc; static logical checkl; static integer iscale; extern integer idamax_(integer*, doublereal*, integer*); static integer locdim; extern /* Subroutine */ int dbolsm_(doublereal*, integer*, integer*, integer*, doublereal*, doublereal*, integer*, integer*, doublereal*, doublereal*, integer*, doublereal*, doublereal*, doublereal*, integer*, integer*); static integer inrows; extern /* Subroutine */ int xerrwv_(char*, integer*, integer*, integer *, integer*, integer*, integer*, integer*, real*, real*, ftnlen); /* ***BEGIN PROLOGUE DBOLS */ /* ***DATE WRITTEN 821220 (YYMMDD) */ /* ***REVISION DATE 861211 (YYMMDD) */ /* ***CATEGORY NO. K1A2A,G2E,G2H1,G2H2 */ /* ***KEYWORDS LIBRARY=SLATEC,TYPE=DOUBLE PRECISION(SBOLS-S DBOLS-D), */ /* BOUNDS,CONSTRAINTS,INEQUALITY,LEAST SQUARES,LINEAR */ /* ***AUTHOR HANSON, R. J., SNLA */ /* ***PURPOSE Solve the problem */ /* E*X = F (in the least squares sense) */ /* with bounds on selected X values. */ /* ***DESCRIPTION */ /* **** Double Precision Version of SBOLS **** */ /* **** All INPUT and OUTPUT real variables are DOUBLE PRECISION **** */ /* The user must have dimension statements of the form: */ /* DIMENSION W(MDW,NCOLS+1), BL(NCOLS), BU(NCOLS), */ /* * X(NCOLS+NX), RW(5*NCOLS) */ /* INTEGER IND(NCOLS), IOPT(1+NI), IW(2*NCOLS) */ /* (here NX=number of extra locations required for option 4; NX=0 */ /* for no options; NX=NCOLS if this option is in use. Here NI=number */ /* of extra locations required for options 1-6; NI=0 for no */ /* options.) */ /* INPUT */ /* ----- */ /* -------------------- */ /* W(MDW,*),MROWS,NCOLS */ /* -------------------- */ /* The array W(*,*) contains the matrix [E:F] on entry. The matrix */ /* [E:F] has MROWS rows and NCOLS+1 columns. This data is placed in */ /* the array W(*,*) with E occupying the first NCOLS columns and the */ /* right side vector F in column NCOLS+1. The row dimension, MDW, of */ /* the array W(*,*) must satisfy the inequality MDW .ge. MROWS. */ /* Other values of MDW are errrors. The values of MROWS and NCOLS */ /* must be positive. Other values are errors. There is an exception */ /* to this when using option 1 for accumulation of blocks of */ /* equations. In that case MROWS is an OUTPUT variable ONLY, and the */ /* matrix data for [E:F] is placed in W(*,*), one block of rows at a */ /* time. MROWS contains the number of rows in the matrix after */ /* triangularizing several blocks of equations. This is an OUTPUT */ /* parameter ONLY when option 1 is used. See IOPT(*) CONTENTS */ /* for details about option 1. */ /* ------------------ */ /* BL(*),BU(*),IND(*) */ /* ------------------ */ /* These arrays contain the information about the bounds that the */ /* solution values are to satisfy. The value of IND(J) tells the */ /* type of bound and BL(J) and BU(J) give the explicit values for */ /* the respective upper and lower bounds. */ /* 1. For IND(J)=1, require X(J) .ge. BL(J). */ /* (the value of BU(J) is not used.) */ /* 2. For IND(J)=2, require X(J) .le. BU(J). */ /* (the value of BL(J) is not used.) */ /* 3. For IND(J)=3, require X(J) .ge. BL(J) and */ /* X(J) .le. BU(J). */ /* 4. For IND(J)=4, no bounds on X(J) are required. */ /* (the values of BL(J) and BU(J) are not used.) */ /* Values other than 1,2,3 or 4 for IND(J) are errors. In the case */ /* IND(J)=3 (upper and lower bounds) the condition BL(J) .gt. BU(J) */ /* is an error. */ /* ------- */ /* IOPT(*) */ /* ------- */ /* This is the array where the user can specify nonstandard options */ /* for DBOLSM( ). Most of the time this feature can be ignored by */ /* setting the input value IOPT(1)=99. Occasionally users may have */ /* needs that require use of the following subprogram options. For */ /* details about how to use the options see below: IOPT(*) CONTENTS. */ /* Option Number Brief Statement of Purpose */ /* ------ ------ ----- --------- -- ------- */ /* 1 Return to user for accumulation of blocks */ /* of least squares equations. */ /* 2 Check lengths of all arrays used in the */ /* subprogram. */ /* 3 Standard scaling of the data matrix, E. */ /* 4 User provides column scaling for matrix E. */ /* 5 Provide option array to the low-level */ /* subprogram DBOLSM( ). */ /* 6 Move the IOPT(*) processing pointer. */ /* 99 No more options to change. */ /* ---- */ /* X(*) */ /* ---- */ /* This array is used to pass data associated with option 4. Ignore */ /* this parameter if this option is not used. Otherwise see below: */ /* IOPT(*) CONTENTS. */ /* OUTPUT */ /* ------ */ /* ---------- */ /* X(*),RNORM */ /* ---------- */ /* The array X(*) contains a solution (if MODE .ge.0 or .eq.-22) for */ /* the constrained least squares problem. The value RNORM is the */ /* minimum residual vector length. */ /* ---- */ /* MODE */ /* ---- */ /* The sign of MODE determines whether the subprogram has completed */ /* normally, or encountered an error condition or abnormal status. A */ /* value of MODE .ge. 0 signifies that the subprogram has completed */ /* normally. The value of MODE (.GE. 0) is the number of variables */ /* in an active status: not at a bound nor at the value ZERO, for */ /* the case of free variables. A negative value of MODE will be one */ /* of the cases -37,-36,...,-22, or -17,...,-2. Values .lt. -1 */ /* correspond to an abnormal completion of the subprogram. To */ /* understand the abnormal completion codes see below: ERROR */ /* MESSAGES for DBOLS( ). AN approximate solution will be returned */ /* to the user only when max. iterations is reached, MODE=-22. */ /* Values for MODE=-37,...,-22 come from the low-level subprogram */ /* DBOLSM(). See the section ERROR MESSAGES for DBOLSM() in the */ /* documentation for DBOLSM(). */ /* ----------- */ /* RW(*),IW(*) */ /* ----------- */ /* These are working arrays with 5*NCOLS and 2*NCOLS entries. */ /* (normally the user can ignore the contents of these arrays, */ /* but they must be dimensioned properly.) */ /* IOPT(*) CONTENTS */ /* ------- -------- */ /* The option array allows a user to modify internal variables in */ /* the subprogram without recompiling the source code. A central */ /* goal of the initial software design was to do a good job for most */ /* people. Thus the use of options will be restricted to a select */ /* group of users. The processing of the option array proceeds as */ /* follows: a pointer, here called LP, is initially set to the value */ /* 1. This value is updated as each option is processed. At the */ /* pointer position the option number is extracted and used for */ /* locating other information that allows for options to be changed. */ /* The portion of the array IOPT(*) that is used for each option is */ /* fixed; the user and the subprogram both know how many locations */ /* are needed for each option. A great deal of error checking is */ /* done by the subprogram on the contents of the option array. */ /* Nevertheless it is still possible to give the subprogram optional */ /* input that is meaningless. For example option 4 uses the */ /* locations X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1) for passing */ /* scaling data. The user must manage the allocation of these */ /* locations. */ /* 1 */ /* - */ /* This option allows the user to solve problems with a large number */ /* of rows compared to the number of variables. The idea is that the */ /* subprogram returns to the user (perhaps many times) and receives */ /* new least squares equations from the calling program unit. */ /* Eventually the user signals "that's all" and then computes the */ /* solution with one final call to subprogram DBOLS( ). The value of */ /* MROWS is an OUTPUT variable when this option is used. Its value */ /* is always in the range 0 .le. MROWS .le. NCOLS+1. It is equal to */ /* the number of rows after the triangularization of the entire set */ /* of equations. If LP is the processing pointer for IOPT(*), the */ /* usage for the sequential processing of blocks of equations is */ /* IOPT(LP)=1 */ /* Move block of equations to W(*,*) starting at */ /* the first row of W(*,*). */ /* IOPT(LP+3)=# of rows in the block; user defined */ /* The user now calls DBOLS( ) in a loop. The value of IOPT(LP+1) */ /* directs the user's action. The value of IOPT(LP+2) points to */ /* where the subsequent rows are to be placed in W(*,*). */ /* .<LOOP */ /* . CALL DBOLS() */ /* . IF(IOPT(LP+1) .EQ. 1) THEN */ /* . IOPT(LP+3)=# OF ROWS IN THE NEW BLOCK; USER DEFINED */ /* . PLACE NEW BLOCK OF IOPT(LP+3) ROWS IN */ /* . W(*,*) STARTING AT ROW IOPT(LP+2). */ /* . */ /* . IF( THIS IS THE LAST BLOCK OF EQUATIONS ) THEN */ /* . IOPT(LP+1)=2 */ /* .<------CYCLE LOOP */ /* . ELSE IF (IOPT(LP+1) .EQ. 2) THEN */ /* <-------EXIT LOOP SOLUTION COMPUTED IF MODE .GE. 0 */ /* . ELSE */ /* . ERROR CONDITION; SHOULD NOT HAPPEN. */ /* .<END LOOP */ /* Use of this option adds 4 to the required length of IOPT(*). */ /* 2 */ /* - */ /* This option is useful for checking the lengths of all arrays used */ /* by DBOLS() against their actual requirements for this problem. */ /* The idea is simple: the user's program unit passes the declared */ /* dimension information of the arrays. These values are compared */ /* against the problem-dependent needs within the subprogram. If any */ /* of the dimensions are too small an error message is printed and a */ /* negative value of MODE is returned, -11 to -17. The printed error */ /* message tells how long the dimension should be. If LP is the */ /* processing pointer for IOPT(*), */ /* IOPT(LP)=2 */ /* IOPT(LP+1)=Row dimension of W(*,*) */ /* IOPT(LP+2)=Col. dimension of W(*,*) */ /* IOPT(LP+3)=Dimensions of BL(*),BU(*),IND(*) */ /* IOPT(LP+4)=Dimension of X(*) */ /* IOPT(LP+5)=Dimension of RW(*) */ /* IOPT(LP+6)=Dimension of IW(*) */ /* IOPT(LP+7)=Dimension of IOPT(*) */ /* . */ /* CALL DBOLS() */ /* Use of this option adds 8 to the required length of IOPT(*). */ /* 3 */ /* - */ /* This option changes the type of scaling for the data matrix E. */ /* Nominally each nonzero column of E is scaled so that the */ /* magnitude of its largest entry is equal to the value ONE. If LP */ /* is the processing pointer for IOPT(*), */ /* IOPT(LP)=3 */ /* IOPT(LP+1)=1,2 or 3 */ /* 1= Nominal scaling as noted; */ /* 2= Each nonzero column scaled to have length ONE; */ /* 3= Identity scaling; scaling effectively suppressed. */ /* . */ /* CALL DBOLS() */ /* Use of this option adds 2 to the required length of IOPT(*). */ /* 4 */ /* - */ /* This option allows the user to provide arbitrary (positive) */ /* column scaling for the matrix E. If LP is the processing pointer */ /* for IOPT(*), */ /* IOPT(LP)=4 */ /* IOPT(LP+1)=IOFF */ /* X(NCOLS+IOFF),...,X(NCOLS+IOFF+NCOLS-1) */ /* = Positive scale factors for cols. of E. */ /* . */ /* CALL DBOLS() */ /* Use of this option adds 2 to the required length of IOPT(*) and */ /* NCOLS to the required length of X(*). */ /* 5 */ /* - */ /* This option allows the user to provide an option array to the */ /* low-level subprogram DBOLSM(). If LP is the processing pointer */ /* for IOPT(*), */ /* IOPT(LP)=5 */ /* IOPT(LP+1)= Position in IOPT(*) where option array */ /* data for DBOLSM() begins. */ /* . */ /* CALL DBOLS() */ /* Use of this option adds 2 to the required length of IOPT(*). */ /* 6 */ /* - */ /* Move the processing pointer (either forward or backward) to the */ /* location IOPT(LP+1). The processing point is moved to entry */ /* LP+2 of IOPT(*) if the option is left with -6 in IOPT(LP). For */ /* example to skip over locations 3,...,NCOLS+2 of IOPT(*), */ /* IOPT(1)=6 */ /* IOPT(2)=NCOLS+3 */ /* (IOPT(I), I=3,...,NCOLS+2 are not defined here.) */ /* IOPT(NCOLS+3)=99 */ /* CALL DBOLS() */ /* CAUTION: Misuse of this option can yield some very hard */ /* -to-find bugs. Use it with care. */ /* 99 */ /* -- */ /* There are no more options to change. */ /* Only option numbers -99, -6,-5,...,-1, 1,2,...,6, and 99 are */ /* permitted. Other values are errors. Options -99,-1,...,-6 mean */ /* that the repective options 99,1,...,6 are left at their default */ /* values. An example is the option to modify the (rank) tolerance: */ /* IOPT(1)=-3 Option is recognized but not changed */ /* IOPT(2)=2 Scale nonzero cols. to have length ONE */ /* IOPT(3)=99 */ /* ERROR MESSAGES for DBOLS() */ /* ----- -------- --- ------- */ /* WARNING IN... */ /* DBOLS(). MDW=(I1) MUST BE POSITIVE. */ /* IN ABOVE MESSAGE, I1= 0 */ /* ERROR NUMBER = 2 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). NCOLS=(I1) THE NO. OF VARIABLES MUST BE POSITIVE. */ /* IN ABOVE MESSAGE, I1= 0 */ /* ERROR NUMBER = 3 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). FOR J=(I1), IND(J)=(I2) MUST BE 1-4. */ /* IN ABOVE MESSAGE, I1= 1 */ /* IN ABOVE MESSAGE, I2= 0 */ /* ERROR NUMBER = 4 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). FOR J=(I1), BOUND BL(J)=(R1) IS .GT. BU(J)=(R2). */ /* IN ABOVE MESSAGE, I1= 1 */ /* IN ABOVE MESSAGE, R1= 0. */ /* IN ABOVE MESSAGE, R2= ABOVE MESSAGE, I1= 0 */ /* ERROR NUMBER = 6 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). ISCALE OPTION=(I1) MUST BE 1-3. */ /* IN ABOVE MESSAGE, I1= 0 */ /* ERROR NUMBER = 7 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). OFFSET PAST X(NCOLS) (I1) FOR USER-PROVIDED COLUMN SCALING */ /* MUST BE POSITIVE. */ /* IN ABOVE MESSAGE, I1= 0 */ /* ERROR NUMBER = 8 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). EACH PROVIDED COL. SCALE FACTOR MUST BE POSITIVE. */ /* COMPONENT (I1) NOW = (R1). */ /* IN ABOVE MESSAGE, I1= ND. .LE. MDW=(I2). */ /* IN ABOVE MESSAGE, I1= 1 */ /* IN ABOVE MESSAGE, I2= 0 */ /* ERROR NUMBER = 10 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS().THE ROW DIMENSION OF W(,)=(I1) MUST BE .GE.THE NUMBER OF ROWS= */ /* (I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 1 */ /* ERROR NUMBER = 11 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). THE COLUMN DIMENSION OF W(,)=(I1) MUST BE .GE. NCOLS+1=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 2 */ /* ERROR NUMBER = 12 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS().THE DIMENSIONS OF THE ARRAYS BL(),BU(), AND IND()=(I1) MUST BE */ /* .GE. NCOLS=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 1 */ /* ERROR NUMBER = 13 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). THE DIMENSION OF X()=(I1) MUST BE .GE. THE REQD. LENGTH=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 2 */ /* ERROR NUMBER = 14 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS(). THE DIMENSION OF RW()=(I1) MUST BE .GE. 5*NCOLS=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 3 */ /* ERROR NUMBER = 15 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS() THE DIMENSION OF IW()=(I1) MUST BE .GE. 2*NCOLS=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 2 */ /* ERROR NUMBER = 16 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* WARNING IN... */ /* DBOLS() THE DIMENSION OF IOPT()=(I1) MUST BE .GE. THE REQD. LEN.=(I2). */ /* IN ABOVE MESSAGE, I1= 0 */ /* IN ABOVE MESSAGE, I2= 1 */ /* ERROR NUMBER = 17 */ /* (NORMALLY A RETURN TO THE USER TAKES PLACE FOLLOWING THIS MESSAGE.) */ /* ***REFERENCES HANSON, R. J. LINEAR LEAST SQUARES WITH BOUNDS AND */ /* LINEAR CONSTRAINTS, SNLA REPT. SAND82-1517, AUG.,1982 */ /* ***ROUTINES CALLED DBOLSM,DCOPY,DNRM2,DROT,DROTG,IDAMAX,XERRWV */ /* ***END PROLOGUE DBOLS */ /* SOLVE LINEAR LEAST SQUARES SYSTEM WITH BOUNDS ON */ /* SELECTED VARIABLES. */ /* REVISED 850329-1400 */ /* REVISED YYMMDD-HHMM */ /* TO CHANGE THIS SUBPROGRAM FROM SINGLE TO DOUBLE PRECISION BEGIN */ /* EDITING AT THE CARD 'C++'. */ /* CHANGE THIS SUBPROGRAM NAME TO DBOLS AND THE STRINGS */ /* /SCOPY/ TO /DCOPY/, /SBOL/ TO /DBOL/, */ /* /SNRM2/ TO /DNRM2/, /ISAMAX/ TO /IDAMAX/, */ /* /SROTG/ TO /DROTG/, /SROT/ TO /DROT/, /E0/ TO /D0/, */ /* /REAL / TO /DOUBLE PRECISION/. */ /* ++ */ /* THIS VARIABLE SHOULD REMAIN TYPE REAL. */ /* Parameter adjustments */ w_dim1 = *mdw; w_offset = 1 + w_dim1; w -= w_offset; --bl; --bu; --ind; --iopt; --x; --rw; --iw; /* Function Body */ /* ***FIRST EXECUTABLE STATEMENT DBOLS */ level = 1; nerr = 0; *mode = 0; if (igo == 0) { /* DO(CHECK VALIDITY OF INPUT DATA) */ /* PROCEDURE(CHECK VALIDITY OF INPUT DATA) */ /* SEE THAT MDW IS .GT.0. GROSS CHECK ONLY. */ if (*mdw <= 0) { nerr = 2; nchar = 35; xerrwv_("DBOLS(). MDW=(I1) MUST BE POSITIVE.", &nchar, &nerr, & level, &c__1, mdw, &idum, &c__0, &rdum, &rdum, (ftnlen)35) ; /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* SEE THAT NUMBER OF UNKNOWNS IS POSITIVE. */ if (*ncols <= 0) { nerr = 3; nchar = 58; xerrwv_("DBOLS(). NCOLS=(I1) THE NO. OF VARIABLES MUST BE POSITI" "VE.", &nchar, &nerr, &level, &c__1, ncols, &idum, &c__0, & rdum, &rdum, (ftnlen)58); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* SEE THAT CONSTRAINT INDICATORS ARE ALL WELL-DEFINED. */ i__1 = *ncols; for (j = 1; j <= i__1; ++j) { if (ind[j] < 1 || ind[j] > 4) { nerr = 4; nchar = 45; xerrwv_("DBOLS(). FOR J=(I1), IND(J)=(I2) MUST BE 1-4.", & nchar, &nerr, &level, &c__2, &j, &ind[j], &c__0, & rdum, &rdum, (ftnlen)45); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* L10: */ } /* SEE THAT BOUNDS ARE CONSISTENT. */ i__1 = *ncols; for (j = 1; j <= i__1; ++j) { if (ind[j] == 3) { if (bl[j] > bu[j]) { nerr = 5; nchar = 57; rdum2 = (real) bl[j]; rdum = (real) bu[j]; xerrwv_("DBOLS(). FOR J=(I1), BOUND BL(J)=(R1) IS .GT. B" "U(J)=(R2).", &nchar, &nerr, &level, &c__1, &j, & idum, &c__2, &rdum2, &rdum, (ftnlen)57); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } } /* L20: */ } /* END PROCEDURE */ /* DO(PROCESS OPTION ARRAY) */ /* PROCEDURE(PROCESS OPTION ARRAY) */ zero = 0.; one = 1.; checkl = FALSE_; lenx = *ncols; iscale = 1; igo = 2; lopt = 0; lp = 0; lds = 0; L30: lp += lds; ip = iopt[lp + 1]; jp = abs(ip); /* TEST FOR NO MORE OPTIONS. */ if (ip == 99) { if (lopt == 0) { lopt = lp + 1; } goto L50; } else if (jp == 99) { lds = 1; goto L30; } else if (jp == 1) { if (ip > 0) { /* SET UP DIRECTION FLAG, ROW STACKING POINTER */ /* LOCATION, AND LOCATION FOR NUMBER OF NEW ROWS. */ locacc = lp + 2; /* IOPT(LOCACC-1)=OPTION NUMBER FOR SEQ. ACCUMULATION. */ /* CONTENTS.. IOPT(LOCACC )=USER DIRECTION FLAG, 1 OR 2. */ /* IOPT(LOCACC+1)=ROW STACKING POINTER. */ /* IOPT(LOCACC+2)=NUMBER OF NEW ROWS TO PROCESS. */ /* USER ACTION WITH THIS OPTION.. */ /* (SET UP OPTION DATA FOR SEQ. ACCUMULATION IN IOPT(*). */ /* MUST ALSO START PROCESS WITH IOPT(LOCACC)=1.) */ /* (MOVE BLOCK OF EQUATIONS INTO W(*,*) STARTING AT FIRST */ /* ROW OF W(*,*). SET IOPT(LOCACC+2)=NO. OF ROWS IN BLOCK.) */ /* LOOP */ /* CALL DBOLS() */ /* IF(IOPT(LOCACC) .EQ. 1) THEN */ /* STACK EQUAS., STARTING AT ROW IOPT(LOCACC+1), */ /* INTO W(*,*). */ /* SET IOPT(LOCACC+2)=NO. OF EQUAS. */ /* IF LAST BLOCK OF EQUAS., SET IOPT(LOCACC)=2. */ /* ELSE IF IOPT(LOCACC) .EQ. 2) THEN */ /* (PROCESS IS OVER. EXIT LOOP.) */ /* ELSE */ /* (ERROR CONDITION. SHOULD NOT HAPPEN.) */ /* END IF */ /* END LOOP */ /* SET IOPT(LOCACC-1)=-OPTION NUMBER FOR SEQ. ACCUMULATION. */ /* CALL DBOLS( ) */ iopt[locacc + 1] = 1; igo = 1; } lds = 4; goto L30; } else if (jp == 2) { if (ip > 0) { /* GET ACTUAL LENGTHS OF ARRAYS FOR CHECKING AGAINST NEEDS. */ locdim = lp + 2; /* LMDW.GE.MROWS */ /* LNDW.GE.NCOLS+1 */ /* LLB .GE.NCOLS */ /* LLX .GE.NCOLS+EXTRA REQD. IN OPTIONS. */ /* LLRW.GE.5*NCOLS */ /* LLIW.GE.2*NCOLS */ /* LIOP.GE. AMOUNT REQD. FOR IOPTION ARRAY. */ lmdw = iopt[locdim]; lndw = iopt[locdim + 1]; llb = iopt[locdim + 2]; llx = iopt[locdim + 3]; llrw = iopt[locdim + 4]; lliw = iopt[locdim + 5]; liopt = iopt[locdim + 6]; checkl = TRUE_; } lds = 8; goto L30; /* OPTION TO MODIFY THE COLUMN SCALING. */ } else if (jp == 3) { if (ip > 0) { iscale = iopt[lp + 2]; /* SEE THAT ISCALE IS 1 THRU 3. */ if (iscale < 1 || iscale > 3) { nerr = 7; nchar = 40; xerrwv_("DBOLS(). ISCALE OPTION=(I1) MUST BE 1-3.", & nchar, &nerr, &level, &c__1, &iscale, &idum, & c__0, &rdum, &rdum, (ftnlen)40); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } } lds = 2; /* CYCLE FOREVER */ goto L30; /* IN THIS OPTION THE USER HAS PROVIDED SCALING. THE */ /* SCALE FACTORS FOR THE COLUMNS BEGIN IN X(NCOLS+IOPT(LP+2)). */ } else if (jp == 4) { if (ip > 0) { iscale = 4; if (iopt[lp + 2] <= 0) { nerr = 8; nchar = 85; xerrwv_("DBOLS(). OFFSET PAST X(NCOLS) (I1) FOR USER-PRO" "VIDED COLUMN SCALING MUST BE POSITIVE.", &nchar, & nerr, &level, &c__1, &iopt[lp + 2], &idum, &c__0, &rdum, &rdum, (ftnlen)85); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } dcopy_(ncols, &x[*ncols + iopt[lp + 2]], &c__1, &rw[1], &c__1) ; lenx += *ncols; i__1 = *ncols; for (j = 1; j <= i__1; ++j) { if (rw[j] <= zero) { nerr = 9; nchar = 85; rdum2 = (real) rw[j]; xerrwv_("DBOLS(). EACH PROVIDED COL. SCALE FACTOR MU" "ST BE POSITIVE. COMPONENT (I1) NOW = (R1).", & nchar, &nerr, &level, &c__1, &j, &idum, &c__1, &rdum2, &rdum, (ftnlen)85); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* L40: */ } } lds = 2; /* CYCLE FOREVER */ goto L30; /* IN THIS OPTION AN OPTION ARRAY IS PROVIDED TO DBOLSM(). */ } else if (jp == 5) { if (ip > 0) { lopt = iopt[lp + 2]; } lds = 2; /* CYCLE FOREVER */ goto L30; /* THIS OPTION USES THE NEXT LOC OF IOPT(*) AS AN */ /* INCREMENT TO SKIP. */ } else if (jp == 6) { if (ip > 0) { lp = iopt[lp + 2] - 1; lds = 0; } else { lds = 2; } /* CYCLE FOREVER */ goto L30; /* NO VALID OPTION NUMBER WAS NOTED. THIS IS AN ERROR CONDITION. */ } else { nerr = 6; nchar = 47; rdum2 = (real) idum; xerrwv_("DBOLS(). THE OPTION NUMBER=(I1) IS NOT DEFINED.", &nchar, &nerr, &level, &c__1, &jp, &idum, &c__0, &rdum2, &rdum2, (ftnlen)47); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } L50: /* END PROCEDURE */ if (checkl) { /* DO(CHECK LENGTHS OF ARRAYS) */ /* PROCEDURE(CHECK LENGTHS OF ARRAYS) */ /* THIS FEATURE ALLOWS THE USER TO MAKE SURE THAT THE */ /* ARRAYS ARE LONG ENOUGH FOR THE INTENDED PROBLEM SIZE AND USE. */ if (lmdw < *mrows) { nerr = 11; nchar = 76; xerrwv_("DBOLS(). THE ROW DIMENSION OF W(,)=(I1) MUST BE .GE" ".THE NUMBER OF ROWS=(I2).", &nchar, &nerr, &level, & c__2, &lmdw, mrows, &c__0, &rdum, &rdum, (ftnlen)76); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (lndw < *ncols + 1) { nerr = 12; nchar = 69; i__1 = *ncols + 1; xerrwv_("DBOLS(). THE COLUMN DIMENSION OF W(,)=(I1) MUST BE " ".GE. NCOLS+1=(I2).", &nchar, &nerr, &level, &c__2, & lndw, &i__1, &c__0, &rdum, &rdum, (ftnlen)69); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (llb < *ncols) { nerr = 13; nchar = 88; xerrwv_("DBOLS(). THE DIMENSIONS OF THE ARRAYS BL(),BU(), AN" "D IND()=(I1) MUST BE .GE. NCOLS=(I2).", &nchar, &nerr, &level, &c__2, &llb, ncols, &c__0, &rdum, &rdum, ( ftnlen)88); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (llx < lenx) { nerr = 14; nchar = 70; xerrwv_("DBOLS(). THE DIMENSION OF X()=(I1) MUST BE .GE. THE" " REQD. LENGTH=(I2).", &nchar, &nerr, &level, &c__2, & llx, &lenx, &c__0, &rdum, &rdum, (ftnlen)70); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (llrw < *ncols * 5) { nerr = 15; nchar = 62; i__1 = *ncols * 5; xerrwv_("DBOLS(). THE DIMENSION OF RW()=(I1) MUST BE .GE. 5*" "NCOLS=(I2).", &nchar, &nerr, &level, &c__2, &llrw, & i__1, &c__0, &rdum, &rdum, (ftnlen)62); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (lliw < *ncols << 1) { nerr = 16; nchar = 61; i__1 = *ncols << 1; xerrwv_("DBOLS() THE DIMENSION OF IW()=(I1) MUST BE .GE. 2*N" "COLS=(I2).", &nchar, &nerr, &level, &c__2, &lliw, & i__1, &c__0, &rdum, &rdum, (ftnlen)61); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } if (liopt < lp + 1) { nerr = 17; nchar = 71; i__1 = lp + 1; xerrwv_("DBOLS(). THE DIMENSION OF IOPT()=(I1) MUST BE .GE. " "THE REQD. LEN.=(I2).", &nchar, &nerr, &level, &c__2, & liopt, &i__1, &c__0, &rdum, &rdum, (ftnlen)71); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* END PROCEDURE */ } } switch (igo) { case 1: goto L60; case 2: goto L90; } goto L180; /* GO BACK TO THE USER FOR ACCUMULATION OF LEAST SQUARES */ /* EQUATIONS AND DIRECTIONS TO QUIT PROCESSING. */ /* CASE 1 */ L60: /* DO(ACCUMULATE LEAST SQUARES EQUATIONS) */ /* PROCEDURE(ACCUMULATE LEAST SQUARES EQUATIONS) */ *mrows = iopt[locacc + 1] - 1; inrows = iopt[locacc + 2]; mnew = *mrows + inrows; if (mnew < 0 || mnew > *mdw) { nerr = 10; nchar = 61; xerrwv_("DBOLS(). NO. OF ROWS=(I1) MUST BE .GE. 0 .AND. .LE. MDW=(I2" ").", &nchar, &nerr, &level, &c__2, &mnew, mdw, &c__0, &rdum, & rdum, (ftnlen)61); /* DO(RETURN TO USER PROGRAM UNIT) */ goto L190; } /* Computing MIN */ i__2 = *ncols + 1; i__1 = min(i__2,mnew); for (j = 1; j <= i__1; ++j) { i__2 = max(*mrows,j) + 1; for (i__ = mnew; i__ >= i__2; --i__) { i__3 = i__ - j; ibig = idamax_(&i__3, &w[j + j * w_dim1], &c__1) + j - 1; /* PIVOT FOR INCREASED STABILITY. */ drotg_(&w[ibig + j * w_dim1], &w[i__ + j * w_dim1], &sc, &ss); i__3 = *ncols + 1 - j; drot_(&i__3, &w[ibig + (j + 1) * w_dim1], mdw, &w[i__ + (j + 1) * w_dim1], mdw, &sc, &ss); w[i__ + j * w_dim1] = zero; /* L70: */ } /* L80: */ } /* Computing MIN */ i__1 = *ncols + 1; *mrows = min(i__1,mnew); iopt[locacc + 1] = *mrows + 1; igo = iopt[locacc]; /* END PROCEDURE */ if (igo == 2) { igo = 0; } goto L180; /* CASE 2 */ L90: /* DO(INITIALIZE VARIABLES AND DATA VALUES) */ /* PROCEDURE(INITIALIZE VARIABLES AND DATA VALUES) */ i__1 = *ncols; for (j = 1; j <= i__1; ++j) { switch (iscale) { case 1: goto L100; case 2: goto L110; case 3: goto L120; case 4: goto L130; } goto L140; L100: /* CASE 1 */ /* THIS IS THE NOMINAL SCALING. EACH NONZERO */ /* COL. HAS MAX. NORM EQUAL TO ONE. */ ibig = idamax_(mrows, &w[j * w_dim1 + 1], &c__1); rw[j] = (d__1 = w[ibig + j * w_dim1], abs(d__1)); if (rw[j] == zero) { rw[j] = one; } else { rw[j] = one / rw[j]; } goto L140; L110: /* CASE 2 */ /* THIS CHOICE OF SCALING MAKES EACH NONZERO COLUMN */ /* HAVE EUCLIDEAN LENGTH EQUAL TO ONE. */ rw[j] = dnrm2_(mrows, &w[j * w_dim1 + 1], &c__1); if (rw[j] == zero) { rw[j] = one; } else { rw[j] = one / rw[j]; } goto L140; L120: /* CASE 3 */ /* THIS CASE EFFECTIVELY SUPPRESSES SCALING BY SETTING */ /* THE SCALING MATRIX TO THE IDENTITY MATRIX. */ rw[1] = one; dcopy_(ncols, &rw[1], &c__0, &rw[1], &c__1); goto L160; L130: /* CASE 4 */ goto L160; L140: /* L150: */ ; } L160: /* END PROCEDURE */ /* DO(SOLVE BOUNDED LEAST SQUARES PROBLEM) */ /* PROCEDURE(SOLVE BOUNDED LEAST SQUARES PROBLEM) */ /* INITIALIZE IBASIS(*), J=1,NCOLS, AND IBB(*), J=1,NCOLS, */ /* TO =J,AND =1, FOR USE IN DBOLSM( ). */ i__1 = *ncols; for (j = 1; j <= i__1; ++j) { iw[j] = j; iw[j + *ncols] = 1; rw[*ncols * 3 + j] = bl[j]; rw[(*ncols << 2) + j] = bu[j]; /* L170: */ } dbolsm_(&w[w_offset], mdw, mrows, ncols, &rw[*ncols * 3 + 1], &rw[(*ncols << 2) + 1], &ind[1], &iopt[lopt], &x[1], rnorm, mode, &rw[*ncols + 1], &rw[(*ncols << 1) + 1], &rw[1], &iw[1], &iw[*ncols + 1]); /* END PROCEDURE */ igo = 0; L180: return 0; /* PROCEDURE(RETURN TO USER PROGRAM UNIT) */ L190: if (*mode >= 0) { *mode = -nerr; } igo = 0; return 0; /* END PROCEDURE */ } /* dbols_ */
/* Subroutine */ int check0_(doublereal *sfac) { /* Initialized data */ static doublereal ds1[8] = { .8,.6,.8,-.6,.8,0.,1.,0. }; static doublereal datrue[8] = { .5,.5,.5,-.5,-.5,0.,1.,1. }; static doublereal dbtrue[8] = { 0.,.6,0.,-.6,0.,0.,1.,0. }; static doublereal da1[8] = { .3,.4,-.3,-.4,-.3,0.,0.,1. }; static doublereal db1[8] = { .4,.3,.4,.3,-.4,0.,1.,0. }; static doublereal dc1[8] = { .6,.8,-.6,.8,.6,1.,0.,1. }; /* Local variables */ integer k; doublereal sa, sb, sc, ss; /* Fortran I/O blocks */ static cilist io___18 = { 0, 6, 0, 0, 0 }; /* .. Parameters .. */ /* .. Scalar Arguments .. */ /* .. Scalars in Common .. */ /* .. Local Scalars .. */ /* .. Local Arrays .. */ /* .. External Subroutines .. */ /* .. Common blocks .. */ /* .. Data statements .. */ /* .. Executable Statements .. */ /* Compute true values which cannot be prestored */ /* in decimal notation */ dbtrue[0] = 1.6666666666666667; dbtrue[2] = -1.6666666666666667; dbtrue[4] = 1.6666666666666667; for (k = 1; k <= 8; ++k) { /* .. Set N=K for identification in output if any .. */ combla_1.n = k; if (combla_1.icase == 3) { /* .. DROTG .. */ if (k > 8) { goto L40; } sa = da1[k - 1]; sb = db1[k - 1]; drotg_(&sa, &sb, &sc, &ss); stest1_(&sa, &datrue[k - 1], &datrue[k - 1], sfac); stest1_(&sb, &dbtrue[k - 1], &dbtrue[k - 1], sfac); stest1_(&sc, &dc1[k - 1], &dc1[k - 1], sfac); stest1_(&ss, &ds1[k - 1], &ds1[k - 1], sfac); } else { s_wsle(&io___18); do_lio(&c__9, &c__1, " Shouldn't be here in CHECK0", (ftnlen)28); e_wsle(); s_stop("", (ftnlen)0); } /* L20: */ } L40: return 0; } /* check0_ */