--- /dev/null
+/* tensor.f -- translated by f2c (version 20050501).
+ You must link the resulting object file with libf2c:
+ on Microsoft Windows system, link with libf2c.lib;
+ on Linux or Unix systems, link with .../path/to/libf2c.a -lm
+ or, if you install libf2c.a in a standard place, with -lf2c -lm
+ -- in that order, at the end of the command line, as in
+ cc *.o -lf2c -lm
+ Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
+
+ http://www.netlib.org/f2c/libf2c.zip
+*/
+
+#include "f2c.h"
+
+/* Table of constant values */
+
+static integer c__5 = 5;
+static integer c__1 = 1;
+static integer c__9 = 9;
+static integer c__3 = 3;
+static doublereal c_b111 = 2.;
+static doublereal c_b134 = 10.;
+static doublereal c_b250 = .33333333333333331;
+static doublereal c_b324 = 1.;
+static doublereal c_b384 = 3.;
+
+/* ALGORITHM 739, COLLECTED ALGORITHMS FROM ACM. */
+/* THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE, */
+/* VOL. 20, NO. 4, DECEMBER, 1994, P.518-530. */
+/* *** driver.f */
+/* Main program */ int MAIN__(void)
+{
+ /* Format strings */
+ static char fmt_211[] = "(\002 G=\002,999e20.13)";
+
+ /* System generated locals */
+ integer i__1;
+ olist o__1;
+ cllist cl__1;
+ alist al__1, al__2;
+
+ /* Builtin functions */
+ integer f_open(olist *), s_rsle(cilist *), do_lio(integer *, integer *,
+ char *, ftnlen), e_rsle(void), s_wsle(cilist *), e_wsle(void),
+ s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void),
+ f_rew(alist *), f_end(alist *), f_clos(cllist *);
+ /* Subroutine */ int s_stop(char *, ftnlen);
+
+ /* Local variables */
+ doublereal h__[200] /* was [50][4] */;
+ integer i__, n;
+ doublereal x[50];
+ integer nr;
+ extern /* Subroutine */ int fcn_(), grd_();
+ integer msg;
+ extern /* Subroutine */ int hsn_();
+ integer ipr;
+ doublereal wrk[400] /* was [50][8] */, fpls, gpls[50];
+ integer iwrk[4];
+ doublereal xpls[50], typx[50];
+ integer itnno;
+ doublereal fscale;
+ integer grdflg, hesflg;
+ doublereal gradtl;
+ integer ndigit;
+ extern /* Subroutine */ int dfault_(integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *, doublereal *, integer *,
+ integer *, integer *, integer *, integer *, integer *);
+ integer method;
+ extern /* Subroutine */ int prtfcn_(integer *);
+ integer itnlim;
+ extern /* Subroutine */ int tensrd_(integer *, integer *, doublereal *,
+ U_fp, integer *, doublereal *, doublereal *, doublereal *,
+ doublereal *, integer *, doublereal *, integer *), tensor_(
+ integer *, integer *, doublereal *, U_fp, U_fp, U_fp, doublereal *
+ , doublereal *, doublereal *, doublereal *, integer *, doublereal
+ *, integer *, integer *, integer *, integer *, integer *, integer
+ *, doublereal *, doublereal *, doublereal *, doublereal *,
+ integer *, doublereal *, integer *);
+ doublereal steptl, stepmx;
+
+ /* Fortran I/O blocks */
+ static cilist io___3 = { 0, 5, 0, 0, 0 };
+ static cilist io___6 = { 0, 6, 0, 0, 0 };
+ static cilist io___7 = { 0, 6, 0, 0, 0 };
+ static cilist io___8 = { 0, 6, 0, 0, 0 };
+ static cilist io___9 = { 0, 6, 0, 0, 0 };
+ static cilist io___10 = { 0, 6, 0, 0, 0 };
+ static cilist io___11 = { 0, 6, 0, 0, 0 };
+ static cilist io___12 = { 0, 6, 0, 0, 0 };
+ static cilist io___21 = { 0, 6, 0, 0, 0 };
+ static cilist io___22 = { 0, 6, 0, fmt_211, 0 };
+ static cilist io___23 = { 0, 6, 0, 0, 0 };
+ static cilist io___24 = { 0, 6, 0, 0, 0 };
+ static cilist io___25 = { 0, 5, 0, 0, 0 };
+ static cilist io___26 = { 0, 6, 0, 0, 0 };
+ static cilist io___27 = { 0, 6, 0, 0, 0 };
+ static cilist io___28 = { 0, 6, 0, 0, 0 };
+ static cilist io___29 = { 0, 6, 0, 0, 0 };
+ static cilist io___30 = { 0, 6, 0, 0, 0 };
+ static cilist io___31 = { 0, 6, 0, 0, 0 };
+ static cilist io___32 = { 0, 6, 0, 0, 0 };
+ static cilist io___33 = { 0, 6, 0, 0, 0 };
+ static cilist io___45 = { 0, 6, 0, 0, 0 };
+ static cilist io___46 = { 0, 6, 0, fmt_211, 0 };
+ static cilist io___47 = { 0, 6, 0, 0, 0 };
+ static cilist io___48 = { 0, 6, 0, 0, 0 };
+
+
+ nr = 50;
+ o__1.oerr = 0;
+ o__1.ounit = 5;
+ o__1.ofnmlen = 8;
+ o__1.ofnm = "wood.inp";
+ o__1.orl = 0;
+ o__1.osta = 0;
+ o__1.oacc = 0;
+ o__1.ofm = 0;
+ o__1.oblnk = 0;
+ f_open(&o__1);
+ prtfcn_(&n);
+ s_rsle(&io___3);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&x[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_rsle();
+ s_wsle(&io___6);
+ do_lio(&c__9, &c__1, "INITIAL APPROXIMATION TO THE SOLUTION X*:", (ftnlen)
+ 41);
+ e_wsle();
+ s_wsle(&io___7);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&x[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_wsle();
+/* SHORT FORM */
+ s_wsle(&io___8);
+ do_lio(&c__9, &c__1, " ", (ftnlen)1);
+ e_wsle();
+ s_wsle(&io___9);
+ do_lio(&c__9, &c__1, "CALLING TENSRD - ALL INPUT PARAMETERS ARE SET", (
+ ftnlen)46);
+ e_wsle();
+ s_wsle(&io___10);
+ do_lio(&c__9, &c__1, " TO THEIR DEFAULT VALUES.", (ftnlen)
+ 41);
+ e_wsle();
+ s_wsle(&io___11);
+ do_lio(&c__9, &c__1, " OUTPUT WILL BE WRITTEN TO THE STANDARD OUTPUT.", (
+ ftnlen)47);
+ e_wsle();
+ s_wsle(&io___12);
+ do_lio(&c__9, &c__1, " ", (ftnlen)1);
+ e_wsle();
+ tensrd_(&nr, &n, x, (U_fp)fcn_, &msg, xpls, &fpls, gpls, h__, &itnno, wrk,
+ iwrk);
+ s_wsle(&io___21);
+ do_lio(&c__9, &c__1, "RESULTS OF TENSRD:", (ftnlen)18);
+ e_wsle();
+ s_wsfe(&io___22);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&gpls[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ s_wsle(&io___23);
+ do_lio(&c__9, &c__1, "XPLS=", (ftnlen)5);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&xpls[i__ - 1], (ftnlen)sizeof(
+ doublereal));
+ }
+ e_wsle();
+ s_wsle(&io___24);
+ do_lio(&c__9, &c__1, "FPLS=", (ftnlen)5);
+ do_lio(&c__5, &c__1, (char *)&fpls, (ftnlen)sizeof(doublereal));
+ do_lio(&c__9, &c__1, " ITNNO=", (ftnlen)8);
+ do_lio(&c__3, &c__1, (char *)&itnno, (ftnlen)sizeof(integer));
+ do_lio(&c__9, &c__1, " MSG=", (ftnlen)6);
+ do_lio(&c__3, &c__1, (char *)&msg, (ftnlen)sizeof(integer));
+ e_wsle();
+/* LONG FORM */
+ prtfcn_(&n);
+ al__1.aerr = 0;
+ al__1.aunit = 5;
+ f_rew(&al__1);
+ s_rsle(&io___25);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&x[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_rsle();
+ s_wsle(&io___26);
+ do_lio(&c__9, &c__1, "INITIAL APPROXIMATION TO THE SOLUTION X*:", (ftnlen)
+ 41);
+ e_wsle();
+ s_wsle(&io___27);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&x[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_wsle();
+ s_wsle(&io___28);
+ do_lio(&c__9, &c__1, " ", (ftnlen)1);
+ e_wsle();
+ s_wsle(&io___29);
+ do_lio(&c__9, &c__1, "CALLING TENSOR AFTER RESETTING INPUT PARAMETERS", (
+ ftnlen)47);
+ e_wsle();
+ s_wsle(&io___30);
+ do_lio(&c__9, &c__1, "IPR, MSG AND METHOD.", (ftnlen)20);
+ e_wsle();
+ s_wsle(&io___31);
+ do_lio(&c__9, &c__1, "THE STANDARD METHOD IS USED IN THIS EXAMPLE.", (
+ ftnlen)44);
+ e_wsle();
+ s_wsle(&io___32);
+ do_lio(&c__9, &c__1, "ADDITIONAL OUTPUT WILL BE WRITTEN TO FILE 'FORT8'.",
+ (ftnlen)50);
+ e_wsle();
+ s_wsle(&io___33);
+ do_lio(&c__9, &c__1, " ", (ftnlen)1);
+ e_wsle();
+/* L997: */
+ dfault_(&n, typx, &fscale, &gradtl, &steptl, &itnlim, &stepmx, &ipr, &
+ method, &grdflg, &hesflg, &ndigit, &msg);
+ o__1.oerr = 0;
+ o__1.ounit = 8;
+ o__1.ofnmlen = 5;
+ o__1.ofnm = "FORT8";
+ o__1.orl = 0;
+ o__1.osta = 0;
+ o__1.oacc = 0;
+ o__1.ofm = 0;
+ o__1.oblnk = 0;
+ f_open(&o__1);
+ ipr = 8;
+ msg = 2;
+ method = 0;
+ tensor_(&nr, &n, x, (U_fp)fcn_, (U_fp)grd_, (U_fp)hsn_, typx, &fscale, &
+ gradtl, &steptl, &itnlim, &stepmx, &ipr, &method, &grdflg, &
+ hesflg, &ndigit, &msg, xpls, &fpls, gpls, h__, &itnno, wrk, iwrk);
+ s_wsle(&io___45);
+ do_lio(&c__9, &c__1, "RESULTS OF TENSOR:", (ftnlen)18);
+ e_wsle();
+ s_wsfe(&io___46);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&gpls[i__ - 1], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ s_wsle(&io___47);
+ do_lio(&c__9, &c__1, "XPLS=", (ftnlen)5);
+ i__1 = n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_lio(&c__5, &c__1, (char *)&xpls[i__ - 1], (ftnlen)sizeof(
+ doublereal));
+ }
+ e_wsle();
+ s_wsle(&io___48);
+ do_lio(&c__9, &c__1, "FPLS=", (ftnlen)5);
+ do_lio(&c__5, &c__1, (char *)&fpls, (ftnlen)sizeof(doublereal));
+ do_lio(&c__9, &c__1, " ITNNO=", (ftnlen)8);
+ do_lio(&c__3, &c__1, (char *)&itnno, (ftnlen)sizeof(integer));
+ do_lio(&c__9, &c__1, " MSG=", (ftnlen)6);
+ do_lio(&c__3, &c__1, (char *)&msg, (ftnlen)sizeof(integer));
+ e_wsle();
+ al__2.aerr = 0;
+ al__2.aunit = 8;
+ f_end(&al__2);
+ cl__1.cerr = 0;
+ cl__1.cunit = 8;
+ cl__1.csta = 0;
+ f_clos(&cl__1);
+ cl__1.cerr = 0;
+ cl__1.cunit = 5;
+ cl__1.csta = 0;
+ f_clos(&cl__1);
+ s_stop("", (ftnlen)0);
+ return 0;
+} /* MAIN__ */
+
+/* Subroutine */ int fcn_(integer *n, doublereal *x, doublereal *f)
+{
+ /* System generated locals */
+ doublereal d__1, d__2, d__3, d__4, d__5, d__6;
+
+ /* Builtin functions */
+ double pow_dd(doublereal *, doublereal *);
+
+ /* Parameter adjustments */
+ --x;
+
+ /* Function Body */
+ if (*n <= 0) {
+ *n = 4;
+ } else {
+ d__1 = x[1] * x[1] - x[2];
+ d__2 = 1. - x[1];
+ d__3 = x[3] * x[3] - x[4];
+ d__4 = 1. - x[3];
+ d__5 = 1. - x[2];
+ d__6 = 1. - x[4];
+ *f = pow_dd(&d__1, &c_b111) * 100. + pow_dd(&d__2, &c_b111) + pow_dd(&
+ d__3, &c_b111) * 90. + pow_dd(&d__4, &c_b111) + (pow_dd(&d__5,
+ &c_b111) + pow_dd(&d__6, &c_b111)) * 10.1 + (1. - x[2]) *
+ 19.8 * (1. - x[4]);
+ }
+ return 0;
+} /* fcn_ */
+
+/* Subroutine */ int prtfcn_(integer *n)
+{
+ /* Builtin functions */
+ integer s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen),
+ e_wsle(void);
+
+ /* Fortran I/O blocks */
+ static cilist io___49 = { 0, 6, 0, 0, 0 };
+ static cilist io___50 = { 0, 6, 0, 0, 0 };
+ static cilist io___51 = { 0, 6, 0, 0, 0 };
+
+
+ *n = 4;
+ s_wsle(&io___49);
+ do_lio(&c__9, &c__1, "__________________________________________", (
+ ftnlen)42);
+ e_wsle();
+ s_wsle(&io___50);
+ do_lio(&c__9, &c__1, "f(x)= Wood function", (ftnlen)19);
+ e_wsle();
+ s_wsle(&io___51);
+ do_lio(&c__9, &c__1, "__________________________________________", (
+ ftnlen)42);
+ e_wsle();
+ return 0;
+} /* prtfcn_ */
+
+/* ---------------------- */
+/* | G R D | */
+/* ---------------------- */
+/* Subroutine */ int grd_(integer *n, real *x, real *g)
+{
+/* DUMMY ROUTINE */
+ return 0;
+} /* grd_ */
+
+/* ---------------------- */
+/* | H S N | */
+/* ---------------------- */
+/* Subroutine */ int hsn_(integer *nr, integer *n, real *x, real *h__)
+{
+/* DUMMY ROUTINE */
+ return 0;
+} /* hsn_ */
+
+/* *** tensrd.f */
+/* ---------------------- */
+/* | T E N S O R | */
+/* ---------------------- */
+/* Subroutine */ int tensor_(integer *nr, integer *n, doublereal *x, U_fp fcn,
+ U_fp grd, U_fp hsn, doublereal *typx, doublereal *fscale, doublereal
+ *gradtl, doublereal *steptl, integer *itnlim, doublereal *stepmx,
+ integer *ipr, integer *method, integer *grdflg, integer *hesflg,
+ integer *ndigit, integer *msg, doublereal *xpls, doublereal *fpls,
+ doublereal *gpls, doublereal *h__, integer *itnno, doublereal *wrk,
+ integer *iwrk)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, wrk_dim1, wrk_offset;
+
+ /* Local variables */
+ extern /* Subroutine */ int opt_(integer *, integer *, doublereal *, U_fp,
+ U_fp, U_fp, doublereal *, doublereal *, doublereal *, doublereal
+ *, integer *, doublereal *, integer *, integer *, integer *,
+ integer *, integer *, integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, integer *);
+
+
+/* AUTHORS: TA-TUNG CHOW, ELIZABETH ESKOW AND ROBERT B. SCHNABEL */
+
+/* DATE: MARCH 29, 1991 */
+
+/* PURPOSE: */
+/* DERIVATIVE TENSOR METHOD FOR UNCONSTRAINED OPTIMIZATION */
+/* THE METHOD BASES EACH ITERATION ON A SPECIALLY CONSTRUCTED */
+/* FOURTH ORDER MODEL OF THE OBJECTIVE FUNCTION. THE MODEL */
+/* INTERPOLATES THE FUNCTION VALUE AND GRADIENT FROM THE PREVIOUS */
+/* ITERATE AND THE CURRENT FUNCTION VALUE, GRADIENT AND HESSIAN */
+/* MATRIX. */
+
+/* BLAS SUBROUTINES: DCOPY,DDOT,DSCAL */
+/* UNCMIN SUBROUTINES: DFAULT, OPTCHK, GRDCHK, HESCHK, LNSRCH, FSTOFD, */
+/* SNDOFD, BAKSLV, FORSLV, OPTSTP */
+/* MODCHL SUBROUTINES: MODCHL, INIT, GERCH, FIN2X2 */
+
+/* ----------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> INITIAL GUESS (INPUT) AND CURRENT POINT */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION VALUE */
+/* GRD --> NAME OF SUBROUTINE TO EVALUATE ANALYTICAL GRADIENT */
+/* HSN --> NAME OF SUBROUTINE TO EVALUATE ANALYTICAL HESSIAN */
+/* HSN SHOULD FILL ONLY THE LOWER TRIANGULAR PART */
+/* AND DIAGONAL OF H */
+/* TYPX(N) --> TYPICAL SIZE OF EACH COMPONENT OF X */
+/* FSCALE --> ESTIMATE OF SCALE OF OBJECTIVE FUNCTION FCN */
+/* GRADTL --> GRADIENT TOLERANCE */
+/* STEPTL --> STEP TOLERANCE */
+/* ITNLIM --> ITERATION LIMIT */
+/* STEPMX --> MAXIMUM STEP LENGTH ALLOWED */
+/* IPR --> OUTPUT UNIT NUMBER */
+/* METHOD --> IF VALUE IS 0 THEN USE ONLY NEWTON STEP AT */
+/* EACH ITERATION */
+/* IF VALUE IS 1 THEN TRY BOTH TENSOR AND NEWTON */
+/* STEPS AT EACH ITERATION */
+/* GRDFLG --> = 1 OR 2 IF ANALYTICAL GRADIENT IS SUPPLIED */
+/* HESFLG --> = 1 OR 2 IF ANALYTICAL HESSIAN IS SUPPLIED */
+/* NDIGIT --> NUMBER OF GOOD DIGITS IN OPTIMIZATION FUNCTION FCN */
+/* MSG --> OUTPUT MESSAGE CONTROL */
+/* XPLS(N) <-- NEW POINT AND FINAL POINT (OUTPUT) */
+/* FPLS <-- NEW FUNCTION VALUE AND FINAL FUNCTION VALUE (OUTPUT) */
+/* GPLS(N) <-- CURRENT GRADIENT AND GRADIENT AT FINAL POINT (OUTPUT) */
+/* H(N,N) --> HESSIAN */
+/* ITNNO <-- NUMBER OF ITERATIONS */
+/* WRK(N,8)--> WORK SPACE */
+/* IWRK(N) --> WORK SPACE */
+
+
+/* EQUIVALENCE WRK(N,1) = G(N) */
+/* WRK(N,2) = S(N) */
+/* WRK(N,3) = D(N) */
+/* WRK(N,4) = DN(N) */
+/* WRK(N,6) = E(N) */
+/* WRK(N,7) = WK1(N) */
+/* WRK(N,8) = WK2(N) */
+
+ /* Parameter adjustments */
+ wrk_dim1 = *nr;
+ wrk_offset = 1 + wrk_dim1;
+ wrk -= wrk_offset;
+ --iwrk;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+ --gpls;
+ --xpls;
+ --typx;
+ --x;
+
+ /* Function Body */
+ opt_(nr, n, &x[1], (U_fp)fcn, (U_fp)grd, (U_fp)hsn, &typx[1], fscale,
+ gradtl, steptl, itnlim, stepmx, ipr, method, grdflg, hesflg,
+ ndigit, msg, &xpls[1], fpls, &gpls[1], &h__[h_offset], itnno, &
+ wrk[wrk_dim1 + 1], &wrk[(wrk_dim1 << 1) + 1], &wrk[wrk_dim1 * 3 +
+ 1], &wrk[(wrk_dim1 << 2) + 1], &wrk[wrk_dim1 * 6 + 1], &wrk[
+ wrk_dim1 * 7 + 1], &wrk[(wrk_dim1 << 3) + 1], &iwrk[1]);
+ return 0;
+} /* tensor_ */
+
+/* ---------------------- */
+/* | T E N S R D | */
+/* ---------------------- */
+/* Subroutine */ int tensrd_(integer *nr, integer *n, doublereal *x, U_fp fcn,
+ integer *msg, doublereal *xpls, doublereal *fpls, doublereal *gpls,
+ doublereal *h__, integer *itnno, doublereal *wrk, integer *iwrk)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, wrk_dim1, wrk_offset;
+
+ /* Local variables */
+ extern /* Subroutine */ int grd_(integer *, real *, real *), hsn_(integer
+ *, integer *, real *, real *);
+ integer ipr;
+ doublereal fscale;
+ integer grdflg, hesflg;
+ doublereal gradtl;
+ integer ndigit;
+ extern /* Subroutine */ int dfault_(integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *, doublereal *, integer *,
+ integer *, integer *, integer *, integer *, integer *);
+ integer method, itnlim;
+ extern /* Subroutine */ int tensor_(integer *, integer *, doublereal *,
+ U_fp, S_fp, S_fp, doublereal *, doublereal *, doublereal *,
+ doublereal *, integer *, doublereal *, integer *, integer *,
+ integer *, integer *, integer *, integer *, doublereal *,
+ doublereal *, doublereal *, doublereal *, integer *, doublereal *,
+ integer *);
+ doublereal steptl, stepmx;
+
+
+/* PURPOSE: */
+/* SHORT CALLING SEQUENCE SUBROUTINE */
+
+/* ----------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> INITIAL GUESS (INPUT) AND CURRENT POINT */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION VALUE */
+/* MSG --> OUTPUT MESSAGE CONTROL */
+/* XPLS(N) <-- NEW POINT AND FINAL POINT (OUTPUT) */
+/* FPLS <-- NEW FUNCTION VALUE AND FINAL FUNCTION VALUE (OUTPUT) */
+/* GPLS(N) <-- GRADIENT AT FINAL POINT (OUTPUT) */
+/* H(N,N) --> HESSIAN */
+/* ITNNO <-- NUMBER OF ITERATIONS */
+/* WRK(N,8) --> WORK SPACE */
+/* IWRK(N) --> WORK SPACE */
+
+
+/* EQUIVALENCE WRK(N,1) = G(N) */
+/* WRK(N,2) = S(N) */
+/* WRK(N,3) = D(N) */
+/* WRK(N,4) = DN(N) */
+/* WRK(N,5) = TYPX(N) */
+/* WRK(N,6) = E(N) */
+/* WRK(N,7) = WK1(N) */
+/* WRK(N,8) = WK2(N) */
+
+ /* Parameter adjustments */
+ wrk_dim1 = *nr;
+ wrk_offset = 1 + wrk_dim1;
+ wrk -= wrk_offset;
+ --iwrk;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+ --gpls;
+ --xpls;
+ --x;
+
+ /* Function Body */
+ dfault_(n, &wrk[wrk_dim1 * 5 + 1], &fscale, &gradtl, &steptl, &itnlim, &
+ stepmx, &ipr, &method, &grdflg, &hesflg, &ndigit, msg);
+ tensor_(nr, n, &x[1], (U_fp)fcn, (S_fp)grd_, (S_fp)hsn_, &wrk[wrk_dim1 *
+ 5 + 1], &fscale, &gradtl, &steptl, &itnlim, &stepmx, &ipr, &
+ method, &grdflg, &hesflg, &ndigit, msg, &xpls[1], fpls, &gpls[1],
+ &h__[h_offset], itnno, &wrk[wrk_offset], &iwrk[1]);
+ return 0;
+} /* tensrd_ */
+
+/* ---------------------- */
+/* | O P T | */
+/* ---------------------- */
+/* Subroutine */ int opt_(integer *nr, integer *n, doublereal *x, S_fp fcn,
+ S_fp grd, S_fp hsn, doublereal *typx, doublereal *fscale, doublereal *
+ gradtl, doublereal *steptl, integer *itnlim, doublereal *stepmx,
+ integer *ipr, integer *method, integer *grdflg, integer *hesflg,
+ integer *ndigit, integer *msg, doublereal *xpls, doublereal *fpls,
+ doublereal *gpls, doublereal *h__, integer *itnno, doublereal *g,
+ doublereal *s, doublereal *d__, doublereal *dn, doublereal *e,
+ doublereal *wk1, doublereal *wk2, integer *pivot)
+{
+ /* Format strings */
+ static char fmt_25[] = "(\002 INITIAL FUNCTION VALUE F=\002,e20.13)";
+ static char fmt_30[] = "(\002 INITIAL GRADIENT G=\002,999e20.13)";
+ static char fmt_103[] = "(\002 ----------- ITERATION \002,i4,\002 ---"
+ "-------------\002)";
+ static char fmt_104[] = "(\002 X=\002,999e20.13)";
+ static char fmt_105[] = "(\002 F(X)=\002,e20.13)";
+ static char fmt_106[] = "(\002 G(X)=\002,999e20.13)";
+ static char fmt_108[] = "(\002FUNCTION EVAL COUNT:\002,i6,\002 REL. GRAD"
+ ". MAX:\002,e20.13)";
+ static char fmt_110[] = "(\002REL. STEP MAX :\002,e20.13)";
+ static char fmt_370[] = "(\002 FINAL X=\002,999e20.13)";
+ static char fmt_380[] = "(\002 GRADIENT G=\002,999e20.13)";
+ static char fmt_390[] = "(\002 FUNCTION VALUE F(X)=\002,e20.13,\002 AT I"
+ "TERATION \002,i4)";
+ static char fmt_400[] = "(\002FUNCTION EVAL COUNT:\002,i6,\002 REL. GRAD"
+ ". MAX:\002,e20.13)";
+ static char fmt_410[] = "(\002REL. STEP MAX :\002,e20.13)";
+ static char fmt_560[] = "(\002 ----------- ITERATION \002,i4,\002 ---"
+ "-------------\002)";
+ static char fmt_570[] = "(\002 X=\002,999e20.13)";
+ static char fmt_580[] = "(\002 F(X)=\002,e20.13)";
+ static char fmt_590[] = "(\002 G(X)=\002,999e20.13)";
+ static char fmt_600[] = "(\002FUNCTION EVAL COUNT:\002,i6,\002 REL. GRAD"
+ ". MAX:\002,e20.13)";
+ static char fmt_610[] = "(\002REL. STEP MAX :\002,e20.13)";
+
+ /* System generated locals */
+ integer h_dim1, h_offset, i__1, i__2;
+ doublereal d__1, d__2;
+
+ /* Builtin functions */
+ double pow_di(doublereal *, integer *), sqrt(doublereal);
+ integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
+
+ /* Local variables */
+ doublereal f;
+ integer i__;
+ doublereal gd, fn, fp, rnf, eps, rgx, rsx, beta;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ integer imsg;
+ doublereal temp, alpha;
+ extern /* Subroutine */ int mkmdl_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *);
+ integer nfcnt;
+ doublereal finit;
+ extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
+ doublereal *, integer *);
+ logical nomin;
+ doublereal gnorm, addmax;
+ extern /* Subroutine */ int grdchk_(integer *, doublereal *, S_fp,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *, integer *,
+ integer *, integer *), heschk_(integer *, integer *, doublereal *
+ , S_fp, S_fp, S_fp, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *, integer *,
+ doublereal *, doublereal *, doublereal *, integer *, integer *,
+ integer *);
+ integer iretcd;
+ doublereal analtl;
+ extern /* Subroutine */ int choldr_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, integer *, doublereal *, doublereal *,
+ doublereal *), mcheps_(doublereal *), sndofd_(integer *, integer
+ *, doublereal *, S_fp, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, integer *);
+ integer itrmcd;
+ extern /* Subroutine */ int bakslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *), fstofd_(integer *, integer *,
+ integer *, doublereal *, S_fp, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, integer *, integer *);
+ integer icscmx;
+ extern /* Subroutine */ int optchk_(integer *, integer *, integer *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, integer *, integer *, doublereal *, integer *,
+ integer *, integer *, doublereal *, integer *);
+ logical mxtake;
+ extern /* Subroutine */ int lnsrch_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, logical *, integer *, doublereal *, doublereal *,
+ doublereal *, S_fp, doublereal *, integer *), slvmdl_(integer *,
+ integer *, doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, integer *, doublereal *
+ , doublereal *, doublereal *, doublereal *, doublereal *, logical
+ *, doublereal *), forslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *);
+ extern doublereal twonrm_(integer *, doublereal *);
+ extern /* Subroutine */ int optstp_(integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *, integer *, integer *,
+ doublereal *, doublereal *, doublereal *, integer *, integer *,
+ logical *, integer *, integer *, doublereal *, doublereal *);
+
+ /* Fortran I/O blocks */
+ static cilist io___70 = { 0, 0, 0, fmt_25, 0 };
+ static cilist io___71 = { 0, 0, 0, fmt_30, 0 };
+ static cilist io___81 = { 0, 0, 0, fmt_103, 0 };
+ static cilist io___82 = { 0, 0, 0, fmt_104, 0 };
+ static cilist io___83 = { 0, 0, 0, fmt_105, 0 };
+ static cilist io___84 = { 0, 0, 0, fmt_106, 0 };
+ static cilist io___85 = { 0, 0, 0, fmt_108, 0 };
+ static cilist io___86 = { 0, 0, 0, fmt_110, 0 };
+ static cilist io___93 = { 0, 0, 0, fmt_370, 0 };
+ static cilist io___94 = { 0, 0, 0, fmt_380, 0 };
+ static cilist io___95 = { 0, 0, 0, fmt_390, 0 };
+ static cilist io___96 = { 0, 0, 0, fmt_400, 0 };
+ static cilist io___97 = { 0, 0, 0, fmt_410, 0 };
+ static cilist io___98 = { 0, 0, 0, fmt_560, 0 };
+ static cilist io___99 = { 0, 0, 0, fmt_570, 0 };
+ static cilist io___100 = { 0, 0, 0, fmt_580, 0 };
+ static cilist io___101 = { 0, 0, 0, fmt_590, 0 };
+ static cilist io___102 = { 0, 0, 0, fmt_600, 0 };
+ static cilist io___103 = { 0, 0, 0, fmt_610, 0 };
+
+
+
+/* PURPOSE: */
+/* DERIVATIVE TENSOR METHODS FOR UNCONSTRAINED OPTIMIZATION */
+
+/* ----------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> INITIAL GUESS (INPUT) AND CURRENT POINT */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION VALUE */
+/* FCN: R(N) --> R(1) */
+/* GRD --> NAME OF SUBROUTINE TO EVALUATE ANALYTICAL GRADIENT */
+/* FCN: R(N) --> R(N) */
+/* HSN --> NAME OF SUBROUTINE TO EVALUATE ANALYTICAL HESSIAN */
+/* FCN: R(N) --> R(N X N) */
+/* HSN SHOULD FILL ONLY THE LOWER TRIANGULAR PART */
+/* AND DIAGONAL OF H */
+/* TYPX(N) --> TYPICAL SIZE OF EACH COMPONENT OF X */
+/* FSCALE --> ESTIMATE OF SCALE OF OBJECTIVE FUNCTION FCN */
+/* GRADTL --> GRADIENT TOLERANCE */
+/* STEPTL --> STEP TOLERANCE */
+/* ITNLIM --> ITERATION LIMIT */
+/* STEPMX --> MAXIMUM STEP LENGTH ALLOWED */
+/* IPR --> OUTPUT UNIT NUMBER */
+/* METHOD --> IF VALUE IS 0 THEN USE ONLY NEWTON STEP AT */
+/* EACH ITERATION */
+/* GRDFLG --> = 1 OR 2 IF ANALYTICAL GRADIENT IS SUPPLIED */
+/* HESFLG --> = 1 OR 2 IF ANALYTICAL HESSIAN IS SUPPLIED */
+/* NDIGIT --> NUMBER OF GOOD DIGITS IN OPTIMIZATION FUNCTION FCN */
+/* MSG --> OUTPUT MESSAGE CONTRO */
+/* XPLS(N) <-- NEW POINT AND FINAL POINT (OUTPUT) */
+/* FPLS <-- NEW FUNCTION VALUE AND FINAL FUNCTION VALUE (OUTPUT) */
+/* GPLS(N) <-- CURRENT GRADIENT AND GRADIENT AT FINAL POINT (OUTPUT) */
+/* H(N,N) --> HESSIAN */
+/* ITNNO <-- NUMBER OF ITERATIONS */
+/* G(N) --> PREVIOUS GRADIENT */
+/* S --> STEP TO PREVIOUS ITERATE (FOR TENSOR MODEL) */
+/* D --> CURRENT STEP (TENSOR OR NEWTON) */
+/* DN --> NEWTON STEP */
+/* E(N) --> DIAGONAL ADDED TO HESSIAN IN CHOLESKY DECOMPOSITION */
+/* WK1(N) --> WORKSPACE */
+/* WK2(N) --> WORKSPACE */
+/* PIVOT(N)--> PIVOT VECTOR FOR CHOLESKY DECOMPOSITION */
+
+/* -------------------------------- */
+/* INITIALIZATION | */
+/* -------------------------------- */
+
+ /* Parameter adjustments */
+ --pivot;
+ --wk2;
+ --wk1;
+ --e;
+ --dn;
+ --d__;
+ --s;
+ --g;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+ --gpls;
+ --xpls;
+ --typx;
+ --x;
+
+ /* Function Body */
+ *itnno = 0;
+ icscmx = 0;
+ nfcnt = 0;
+ mcheps_(&eps);
+ optchk_(nr, n, msg, &x[1], &typx[1], fscale, gradtl, steptl, itnlim,
+ ndigit, &eps, method, grdflg, hesflg, stepmx, ipr);
+ if (*msg < 0) {
+ return 0;
+ }
+
+/* SCALE X */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ x[i__] /= typx[i__];
+/* L10: */
+ }
+
+/* -------------------------------- */
+/* INITIAL ITERATION | */
+/* -------------------------------- */
+
+/* COMPUTE TYPICAL SIZE OF X */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dn[i__] = 1. / typx[i__];
+/* L15: */
+ }
+/* Computing MAX */
+ i__1 = -(*ndigit);
+ d__1 = pow_di(&c_b134, &i__1);
+ rnf = max(d__1,eps);
+/* Computing MAX */
+ d__1 = .01, d__2 = sqrt(rnf);
+ analtl = max(d__1,d__2);
+/* UNSCALE X AND COMPUTE F AND G */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ wk1[i__] = x[i__] * typx[i__];
+/* L20: */
+ }
+ (*fcn)(n, &wk1[1], &f);
+ ++nfcnt;
+ if (*grdflg >= 1) {
+ (*grd)(n, &wk1[1], &g[1]);
+ if (*grdflg == 1) {
+ *fscale = 1.;
+ grdchk_(n, &wk1[1], (S_fp)fcn, &f, &g[1], &dn[1], &typx[1],
+ fscale, &rnf, &analtl, &wk2[1], msg, ipr, &nfcnt);
+ }
+ } else {
+ fstofd_(&c__1, &c__1, n, &wk1[1], (S_fp)fcn, &f, &g[1], &typx[1], &
+ rnf, &wk2[1], &c__1, &nfcnt);
+ }
+ if (*msg < -20) {
+ return 0;
+ }
+
+ gnorm = twonrm_(n, &g[1]);
+
+/* PRINT OUT 1ST ITERATION? */
+ if (*msg >= 1) {
+ io___70.ciunit = *ipr;
+ s_wsfe(&io___70);
+ do_fio(&c__1, (char *)&f, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___71.ciunit = *ipr;
+ s_wsfe(&io___71);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&g[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ }
+
+/* TEST WHETHER THE INITIAL GUESS SATISFIES THE STOPPING CRITERIA */
+ if (gnorm <= *gradtl) {
+ *fpls = f;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ xpls[i__] = x[i__];
+ gpls[i__] = g[i__];
+/* L40: */
+ }
+ optstp_(n, &xpls[1], fpls, &gpls[1], &x[1], itnno, &icscmx, &itrmcd,
+ gradtl, steptl, fscale, itnlim, &iretcd, &mxtake, ipr, msg, &
+ rgx, &rsx);
+ goto L350;
+ }
+ finit = f;
+
+/* ------------------------ */
+/* ITERATION 1 | */
+/* ------------------------ */
+
+ ++(*itnno);
+
+/* COMPUTE HESSIAN */
+ if (*hesflg == 0) {
+ if (*grdflg == 1) {
+ fstofd_(nr, n, n, &wk1[1], (S_fp)grd, &g[1], &h__[h_offset], &
+ typx[1], &rnf, &wk2[1], &c__3, &nfcnt);
+ } else {
+ sndofd_(nr, n, &wk1[1], (S_fp)fcn, &f, &h__[h_offset], &typx[1], &
+ rnf, &wk2[1], &d__[1], &nfcnt);
+ }
+ } else {
+ if (*hesflg == 2) {
+ (*hsn)(nr, n, &wk1[1], &h__[h_offset]);
+ } else {
+ if (*hesflg == 1) {
+/* IN HESCHK GPLS,XPLS AND E ARE USED AS WORK SPACE */
+ heschk_(nr, n, &wk1[1], (S_fp)fcn, (S_fp)grd, (S_fp)hsn, &f, &
+ g[1], &h__[h_offset], &dn[1], &typx[1], &rnf, &analtl,
+ grdflg, &gpls[1], &xpls[1], &e[1], msg, ipr, &nfcnt);
+ }
+ }
+ }
+ if (*msg < -20) {
+ return 0;
+ }
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ i__2 = i__ - 1;
+ dcopy_(&i__2, &h__[i__ + h_dim1], nr, &h__[i__ * h_dim1 + 1], &c__1);
+/* L50: */
+ }
+
+/* CHOLESKY DECOMPOSITION FOR H (H=LLT) */
+ choldr_(nr, n, &h__[h_offset], &d__[1], &eps, &pivot[1], &e[1], &wk1[1], &
+ addmax);
+
+/* SOLVE FOR NEWTON STEP D */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+/* L60: */
+ wk2[i__] = -g[i__];
+ }
+ forslv_(nr, n, &h__[h_offset], &wk1[1], &wk2[1]);
+ bakslv_(nr, n, &h__[h_offset], &d__[1], &wk1[1]);
+
+/* APPLY LINESEARCH TO THE NEWTON STEP */
+ lnsrch_(nr, n, &x[1], &f, &g[1], &d__[1], &xpls[1], fpls, &mxtake, &
+ iretcd, stepmx, steptl, &typx[1], (S_fp)fcn, &wk1[1], &nfcnt);
+
+/* UPDATE G */
+/* CALL DCOPY(N,GPLS(1),1,GP(1),1) */
+
+/* UNSCALE XPLS AND COMPUTE GPLS */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ wk1[i__] = xpls[i__] * typx[i__];
+/* L80: */
+ }
+ if (*grdflg >= 1) {
+ (*grd)(n, &wk1[1], &gpls[1]);
+ } else {
+ fstofd_(&c__1, &c__1, n, &wk1[1], (S_fp)fcn, fpls, &gpls[1], &typx[1],
+ &rnf, &wk2[1], &c__1, &nfcnt);
+ }
+
+/* CHECK STOPPING CONDITIONS */
+ optstp_(n, &xpls[1], fpls, &gpls[1], &x[1], itnno, &icscmx, &itrmcd,
+ gradtl, steptl, fscale, itnlim, &iretcd, &mxtake, ipr, msg, &rgx,
+ &rsx);
+
+/* IF ITRMCD > 0 THEN STOPPING CONDITIONS SATISFIED */
+ if (itrmcd > 0) {
+ goto L350;
+ }
+
+/* UPDATE X,F AND S FOR TENSOR MODEL */
+ fp = f;
+ f = *fpls;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ temp = xpls[i__];
+ s[i__] = x[i__] - temp;
+ x[i__] = temp;
+/* L90: */
+ }
+
+/* IF MSG >= 2 THEN PRINT OUT EACH ITERATION */
+ if (*msg >= 2) {
+ io___81.ciunit = *ipr;
+ s_wsfe(&io___81);
+ do_fio(&c__1, (char *)&(*itnno), (ftnlen)sizeof(integer));
+ e_wsfe();
+ io___82.ciunit = *ipr;
+ s_wsfe(&io___82);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&x[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ io___83.ciunit = *ipr;
+ s_wsfe(&io___83);
+ do_fio(&c__1, (char *)&(*fpls), (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___84.ciunit = *ipr;
+ s_wsfe(&io___84);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&gpls[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ }
+ if (*msg >= 3) {
+ io___85.ciunit = *ipr;
+ s_wsfe(&io___85);
+ do_fio(&c__1, (char *)&nfcnt, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&rgx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___86.ciunit = *ipr;
+ s_wsfe(&io___86);
+ do_fio(&c__1, (char *)&rsx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ }
+
+/* ------------------------ */
+/* ITERATION > 1 | */
+/* ------------------------ */
+
+/* UNSCALE X AND COMPUTE H */
+L200:
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ wk1[i__] = x[i__] * typx[i__];
+/* L210: */
+ }
+ if (*hesflg == 0) {
+ if (*grdflg == 1) {
+ fstofd_(nr, n, n, &wk1[1], (S_fp)grd, &g[1], &h__[h_offset], &
+ typx[1], &rnf, &wk2[1], &c__3, &nfcnt);
+ } else {
+ sndofd_(nr, n, &wk1[1], (S_fp)fcn, &f, &h__[h_offset], &typx[1], &
+ rnf, &wk2[1], &d__[1], &nfcnt);
+ }
+ } else {
+ (*hsn)(nr, n, &wk1[1], &h__[h_offset]);
+ }
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ i__2 = i__ - 1;
+ dcopy_(&i__2, &h__[i__ + h_dim1], nr, &h__[i__ * h_dim1 + 1], &c__1);
+/* L230: */
+ }
+
+/* IF METHOD = 0 THEN USE NEWTON STEP ONLY */
+ if (*method == 0) {
+
+/* CHOLESKY DECOMPOSITION FOR H */
+ choldr_(nr, n, &h__[h_offset], &wk2[1], &eps, &pivot[1], &e[1], &wk1[
+ 1], &addmax);
+
+/* COMPUTE NEWTON STEP */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ wk1[i__] = -gpls[i__];
+/* L240: */
+ }
+ forslv_(nr, n, &h__[h_offset], &wk2[1], &wk1[1]);
+ bakslv_(nr, n, &h__[h_offset], &d__[1], &wk2[1]);
+
+/* NO TENSOR STEP */
+ nomin = TRUE_;
+ goto L300;
+
+ }
+
+/* FORM TENSOR MODEL */
+ mkmdl_(nr, n, &f, &fp, &gpls[1], &g[1], &s[1], &h__[h_offset], &alpha, &
+ beta, &wk1[1], &d__[1]);
+
+/* SOLVE TENSOR MODEL AND COMPUTE NEWTON STEP */
+/* ON INPUT : SH IS STORED IN WK1 */
+/* A=(G-GPLS-SH-S*BETA/(6*STS)) IS STORED IN D */
+/* ON OUTPUT: NEWTON STEP IS STORED IN DN */
+/* TENSOR STEP IS STORED IN D */
+ slvmdl_(nr, n, &h__[h_offset], &xpls[1], &wk2[1], &e[1], &g[1], &s[1], &
+ gpls[1], &pivot[1], &d__[1], &wk1[1], &dn[1], &alpha, &beta, &
+ nomin, &eps);
+
+/* IF TENSOR MODEL HAS NO MINIMIZER THEN USE NEWTON STEP */
+ if (nomin) {
+ dcopy_(n, &dn[1], &c__1, &d__[1], &c__1);
+ goto L300;
+ }
+
+/* IF TENSOR STEP IS NOT IN DESCENT DIRECTION THEN USE NEWTON STEP */
+ gd = ddot_(n, &gpls[1], &c__1, &d__[1], &c__1);
+ if (gd > 0.) {
+ dcopy_(n, &dn[1], &c__1, &d__[1], &c__1);
+ nomin = TRUE_;
+ }
+
+L300:
+ ++(*itnno);
+ dcopy_(n, &gpls[1], &c__1, &g[1], &c__1);
+
+/* APPLY LINESEARCH TO TENSOR (OR NEWTON) STEP */
+ lnsrch_(nr, n, &x[1], &f, &g[1], &d__[1], &xpls[1], fpls, &mxtake, &
+ iretcd, stepmx, steptl, &typx[1], (S_fp)fcn, &wk1[1], &nfcnt);
+
+ if (! nomin) {
+/* TENSOR STEP IS FOUND AND IN DESCENT DIRECTION, */
+/* APPLY LINESEARCH TO NEWTON STEP */
+/* NEW NEWTON POINT IN WK2 */
+ lnsrch_(nr, n, &x[1], &f, &g[1], &dn[1], &wk2[1], &fn, &mxtake, &
+ iretcd, stepmx, steptl, &typx[1], (S_fp)fcn, &wk1[1], &nfcnt);
+
+/* COMPARE TENSOR STEP TO NEWTON STEP */
+/* IF NEWTON STEP IS BETTER, SET NEXT ITERATE TO NEW NEWTON POINT */
+ if (fn < *fpls) {
+ *fpls = fn;
+ dcopy_(n, &dn[1], &c__1, &d__[1], &c__1);
+ dcopy_(n, &wk2[1], &c__1, &xpls[1], &c__1);
+ }
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ d__[i__] = xpls[i__] - x[i__];
+/* L320: */
+ }
+
+/* UNSCALE XPLS, AND COMPUTE FPLS AND GPLS */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ wk1[i__] = xpls[i__] * typx[i__];
+/* L330: */
+ }
+ (*fcn)(n, &wk1[1], fpls);
+ ++nfcnt;
+ if (*grdflg >= 1) {
+ (*grd)(n, &wk1[1], &gpls[1]);
+ } else {
+ fstofd_(&c__1, &c__1, n, &wk1[1], (S_fp)fcn, fpls, &gpls[1], &typx[1],
+ &rnf, &wk2[1], &c__1, &nfcnt);
+ }
+
+/* CHECK STOPPING CONDITIONS */
+ imsg = *msg;
+ optstp_(n, &xpls[1], fpls, &gpls[1], &x[1], itnno, &icscmx, &itrmcd,
+ gradtl, steptl, fscale, itnlim, &iretcd, &mxtake, ipr, msg, &rgx,
+ &rsx);
+
+/* IF ITRMCD = 0 THEN NOT OVER YET */
+ if (itrmcd == 0) {
+ goto L500;
+ }
+
+/* IF MSG >= 1 THEN PRINT OUT FINAL ITERATION */
+L350:
+ if (imsg >= 1) {
+
+/* TRANSFORM X BACK TO ORIGINAL SPACE */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ xpls[i__] *= typx[i__];
+/* L360: */
+ }
+ io___93.ciunit = *ipr;
+ s_wsfe(&io___93);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&xpls[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ io___94.ciunit = *ipr;
+ s_wsfe(&io___94);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&gpls[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ io___95.ciunit = *ipr;
+ s_wsfe(&io___95);
+ do_fio(&c__1, (char *)&(*fpls), (ftnlen)sizeof(doublereal));
+ do_fio(&c__1, (char *)&(*itnno), (ftnlen)sizeof(integer));
+ e_wsfe();
+ if (imsg >= 3) {
+ io___96.ciunit = *ipr;
+ s_wsfe(&io___96);
+ do_fio(&c__1, (char *)&nfcnt, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&rgx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___97.ciunit = *ipr;
+ s_wsfe(&io___97);
+ do_fio(&c__1, (char *)&rsx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ }
+/* UPDATE THE HESSIAN */
+ if (*hesflg == 0) {
+ if (*grdflg == 1) {
+ fstofd_(nr, n, n, &xpls[1], (S_fp)grd, &gpls[1], &h__[
+ h_offset], &typx[1], &rnf, &wk2[1], &c__3, &nfcnt);
+ } else {
+ sndofd_(nr, n, &xpls[1], (S_fp)fcn, fpls, &h__[h_offset], &
+ typx[1], &rnf, &wk2[1], &d__[1], &nfcnt);
+ }
+ } else {
+ (*hsn)(nr, n, &xpls[1], &h__[h_offset]);
+ }
+ }
+ return 0;
+
+/* UPDATE INFORMATION AT THE CURRENT POINT */
+L500:
+ dcopy_(n, &xpls[1], &c__1, &x[1], &c__1);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ s[i__] = -d__[i__];
+/* L550: */
+ }
+
+/* IF TOO MANY ITERATIONS THEN RETURN */
+ if (*itnno > *itnlim) {
+ goto L350;
+ }
+
+/* IF MSG >= 2 THEN PRINT OUT EACH ITERATION */
+ if (*msg >= 2) {
+ io___98.ciunit = *ipr;
+ s_wsfe(&io___98);
+ do_fio(&c__1, (char *)&(*itnno), (ftnlen)sizeof(integer));
+ e_wsfe();
+ io___99.ciunit = *ipr;
+ s_wsfe(&io___99);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&x[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ io___100.ciunit = *ipr;
+ s_wsfe(&io___100);
+ do_fio(&c__1, (char *)&(*fpls), (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___101.ciunit = *ipr;
+ s_wsfe(&io___101);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&gpls[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ }
+ if (*msg >= 3) {
+ io___102.ciunit = *ipr;
+ s_wsfe(&io___102);
+ do_fio(&c__1, (char *)&nfcnt, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&rgx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ io___103.ciunit = *ipr;
+ s_wsfe(&io___103);
+ do_fio(&c__1, (char *)&rsx, (ftnlen)sizeof(doublereal));
+ e_wsfe();
+ }
+/* UPDATE F */
+ fp = f;
+ f = *fpls;
+
+/* PERFORM NEXT ITERATION */
+ goto L200;
+
+/* END OF ITERATION > 1 */
+
+} /* opt_ */
+
+/* ---------------------- */
+/* | D F A U L T | */
+/* ---------------------- */
+/* Subroutine */ int dfault_(integer *n, doublereal *typx, doublereal *fscale,
+ doublereal *gradtl, doublereal *steptl, integer *itnlim, doublereal *
+ stepmx, integer *ipr, integer *method, integer *grdflg, integer *
+ hesflg, integer *ndigit, integer *msg)
+{
+ /* System generated locals */
+ integer i__1;
+
+ /* Builtin functions */
+ double pow_dd(doublereal *, doublereal *), d_lg10(doublereal *);
+
+ /* Local variables */
+ integer i__;
+ doublereal eps, temp;
+ extern /* Subroutine */ int mcheps_(doublereal *);
+
+ /* Parameter adjustments */
+ --typx;
+
+ /* Function Body */
+ mcheps_(&eps);
+ *method = 1;
+ *fscale = 1.;
+ *grdflg = 0;
+ *hesflg = 0;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ typx[i__] = 1.;
+/* L1: */
+ }
+ temp = pow_dd(&eps, &c_b250);
+ *gradtl = temp;
+ *steptl = temp * temp;
+ *ndigit = (integer) (-d_lg10(&eps));
+/* SET ACTUAL DFAULT VALUE OF STEPMX IN OPTCHK */
+ *stepmx = 0.;
+ *itnlim = 100;
+ *ipr = 6;
+ *msg = 1;
+ return 0;
+} /* dfault_ */
+
+/* ---------------------- */
+/* | O P T C H K | */
+/* ---------------------- */
+/* Subroutine */ int optchk_(integer *nr, integer *n, integer *msg,
+ doublereal *x, doublereal *typx, doublereal *fscale, doublereal *
+ gradtl, doublereal *steptl, integer *itnlim, integer *ndigit,
+ doublereal *eps, integer *method, integer *grdflg, integer *hesflg,
+ doublereal *stepmx, integer *ipr)
+{
+ /* Format strings */
+ static char fmt_901[] = "(\0020OPTCHK ILLEGAL DIMENSION, N=\002,i5)";
+ static char fmt_902[] = "(\002OPTCHK ILLEGAL INPUT VALUES OF: NR=\002"
+ ",i5,\002, N=\002,i5,\002, NR MUST BE <= N.\002)";
+
+ /* System generated locals */
+ integer i__1;
+ doublereal d__1;
+
+ /* Builtin functions */
+ double sqrt(doublereal), pow_dd(doublereal *, doublereal *), d_lg10(
+ doublereal *), pow_di(doublereal *, integer *);
+ integer s_wsfe(cilist *), do_fio(integer *, char *, ftnlen), e_wsfe(void);
+
+ /* Local variables */
+ integer i__;
+ doublereal temp, stpsiz;
+
+ /* Fortran I/O blocks */
+ static cilist io___110 = { 0, 0, 0, fmt_901, 0 };
+ static cilist io___111 = { 0, 0, 0, fmt_902, 0 };
+
+
+
+/* PURPOSE */
+/* ------- */
+/* CHECK INPUT FOR REASONABLENESS */
+
+/* PARAMETERS */
+/* ---------- */
+/* NR <--> ROW DIMENSION OF H AND WRK */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> ON ENTRY, ESTIMATE TO ROOT OF FCN */
+/* TYPX(N) <--> TYPICAL SIZE OF EACH COMPONENT OF X */
+/* FSCALE <--> ESTIMATE OF SCALE OF OBJECTIVE FUNCTION FCN */
+/* GRADTL <--> TOLERANCE AT WHICH GRADIENT CONSIDERED CLOSE */
+/* ENOUGH TO ZERO TO TERMINATE ALGORITHM */
+/* STEPTL <--> TOLERANCE AT WHICH STEP LENGTH CONSIDERED CLOSE */
+/* ENOUGH TO ZERO TO TERMINATE ALGORITHM */
+/* ITNLIM <--> MAXIMUM NUMBER OF ALLOWABLE ITERATIONS */
+/* NDIGIT <--> NUMBER OF GOOD DIGITS IN OPTIMIZATION FUNCTION FCN */
+/* EPS --> MACHINE PRECISION */
+/* METHOD <--> ALGORITHM INDICATOR */
+/* GRDFLG <--> =1 IF ANALYTIC GRADIENT SUPPLIED */
+/* HESFLG <--> =1 IF ANALYTIC HESSIAN SUPPLIED */
+/* STEPMX <--> MAXIMUM STEP SIZE */
+/* MSG <--> MESSAGE AND ERROR CODE */
+/* IPR --> DEVICE TO WHICH TO SEND OUTPUT */
+
+
+/* CHECK DIMENSION OF PROBLEM */
+
+ /* Parameter adjustments */
+ --typx;
+ --x;
+
+ /* Function Body */
+ if (*n <= 0) {
+ goto L805;
+ }
+ if (*nr < *n) {
+ goto L806;
+ }
+
+/* CHECK THAT PARAMETERS ONLY TAKE ON ACCEPTABLE VALUES. */
+/* IF NOT, SET THEM TO DEFAULT VALUES. */
+ if (*method != 0) {
+ *method = 1;
+ }
+ if (*grdflg != 2 && *grdflg != 1) {
+ *grdflg = 0;
+ }
+ if (*hesflg != 2 && *hesflg != 1) {
+ *hesflg = 0;
+ }
+ if (*msg > 3 || (real) (*msg) < 0.f) {
+ *msg = 1;
+ }
+
+/* COMPUTE SCALE MATRIX */
+
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ if (typx[i__] == 0.f) {
+ typx[i__] = 1.;
+ }
+ if (typx[i__] < 0.f) {
+ typx[i__] = -typx[i__];
+ }
+/* L10: */
+ }
+
+/* CHECK MAXIMUM STEP SIZE */
+
+ if (*stepmx > 0.) {
+ goto L20;
+ }
+ stpsiz = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ stpsiz += x[i__] * x[i__] / typx[i__] * typx[i__];
+/* L15: */
+ }
+ stpsiz = sqrt(stpsiz);
+/* Computing MAX */
+ d__1 = stpsiz * 1e3;
+ *stepmx = max(d__1,1e3);
+L20:
+/* CHECK FUNCTION SCALE */
+ if (*fscale == 0.f) {
+ *fscale = 1.;
+ }
+ if (*fscale < 0.f) {
+ *fscale = -(*fscale);
+ }
+/* CHECK GRADIENT TOLERANCE */
+ if (*gradtl < 0.f) {
+ *gradtl = pow_dd(eps, &c_b250);
+ }
+/* CHECK STEP TOLERANCE */
+ if (*steptl < 0.f) {
+ temp = pow_dd(eps, &c_b250);
+ *steptl = temp * temp;
+ }
+
+/* CHECK ITERATION LIMIT */
+ if (*itnlim <= 0) {
+ *itnlim = 100;
+ }
+
+/* CHECK NUMBER OF DIGITS OF ACCURACY IN FUNCTION FCN */
+ if (*ndigit <= 0) {
+ *ndigit = (integer) (-d_lg10(eps));
+ }
+ i__1 = -(*ndigit);
+ if (pow_di(&c_b134, &i__1) <= *eps) {
+ *ndigit = (integer) (-d_lg10(eps));
+ }
+ return 0;
+
+/* ERROR EXITS */
+
+L805:
+ io___110.ciunit = *ipr;
+ s_wsfe(&io___110);
+ do_fio(&c__1, (char *)&(*n), (ftnlen)sizeof(integer));
+ e_wsfe();
+ *msg = -20;
+ return 0;
+L806:
+ io___111.ciunit = *ipr;
+ s_wsfe(&io___111);
+ do_fio(&c__1, (char *)&(*nr), (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&(*n), (ftnlen)sizeof(integer));
+ e_wsfe();
+ *msg = -20;
+ return 0;
+} /* optchk_ */
+
+/* ---------------------- */
+/* | G R D C H K | */
+/* ---------------------- */
+/* Subroutine */ int grdchk_(integer *n, doublereal *x, S_fp fcn, doublereal *
+ f, doublereal *g, doublereal *typsiz, doublereal *typx, doublereal *
+ fscale, doublereal *rnf, doublereal *analtl, doublereal *wrk1,
+ integer *msg, integer *ipr, integer *ifn)
+{
+ /* Format strings */
+ static char fmt_901[] = "(\0020GRDCHK PROBABLE ERROR IN CODING OF ANA"
+ "LYTIC\002,\002 GRADIENT FUNCTION.\002/\002 GRDCHK COMP\002,1"
+ "2x,\002ANALYTIC\002,12x,\002ESTIMATE\002)";
+ static char fmt_902[] = "(\002 GRDCHK \002,i5,3x,e20.13,3x,e20.13)";
+
+ /* System generated locals */
+ integer i__1;
+ doublereal d__1, d__2, d__3, d__4;
+
+ /* Builtin functions */
+ integer s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen);
+
+ /* Local variables */
+ integer i__;
+ doublereal gs;
+ integer ker;
+ doublereal wrk;
+ extern /* Subroutine */ int fstofd_(integer *, integer *, integer *,
+ doublereal *, S_fp, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *, integer *);
+
+ /* Fortran I/O blocks */
+ static cilist io___116 = { 0, 0, 0, fmt_901, 0 };
+ static cilist io___117 = { 0, 0, 0, fmt_902, 0 };
+
+
+
+/* PURPOSE */
+/* ------- */
+/* CHECK ANALYTIC GRADIENT AGAINST ESTIMATED GRADIENT */
+
+/* PARAMETERS */
+/* ---------- */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> ESTIMATE TO A ROOT OF FCN */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE OPTIMIZATION FUNCTION */
+/* MUST BE DECLARED EXTERNAL IN CALLING ROUTINE */
+/* FCN: R(N) --> R(1) */
+/* F --> FUNCTION VALUE: FCN(X) */
+/* G(N) --> GRADIENT: G(X) */
+/* TYPSIZ(N) --> TYPICAL SIZE FOR EACH COMPONENT OF X */
+/* FSCALE --> ESTIMATE OF SCALE OF OBJECTIVE FUNCTION FCN */
+/* RNF --> RELATIVE NOISE IN OPTIMIZATION FUNCTION FCN */
+/* ANALTL --> TOLERANCE FOR COMPARISON OF ESTIMATED AND */
+/* ANALYTICAL GRADIENTS */
+/* WRK1(N) --> WORKSPACE */
+/* MSG <-- MESSAGE OR ERROR CODE */
+/* ON OUTPUT: =-21, PROBABLE CODING ERROR OF GRADIENT */
+/* IPR --> DEVICE TO WHICH TO SEND OUTPUT */
+/* IFN <--> NUMBER OF FUNCTION EVALUATIONS */
+
+/* COMPUTE FIRST ORDER FINITE DIFFERENCE GRADIENT AND COMPARE TO */
+/* ANALYTIC GRADIENT. */
+
+ /* Parameter adjustments */
+ --wrk1;
+ --typx;
+ --typsiz;
+ --g;
+ --x;
+
+ /* Function Body */
+ fstofd_(&c__1, &c__1, n, &x[1], (S_fp)fcn, f, &wrk1[1], &typx[1], rnf, &
+ wrk, &c__1, ifn);
+ ker = 0;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+/* Computing MAX */
+ d__2 = abs(*f);
+/* Computing MAX */
+ d__3 = (d__1 = x[i__], abs(d__1)), d__4 = typsiz[i__];
+ gs = max(d__2,*fscale) / max(d__3,d__4);
+/* Computing MAX */
+ d__3 = (d__1 = g[i__], abs(d__1));
+ if ((d__2 = g[i__] - wrk1[i__], abs(d__2)) > max(d__3,gs) * *analtl) {
+ ker = 1;
+ }
+/* L5: */
+ }
+ if (ker == 0) {
+ goto L20;
+ }
+ io___116.ciunit = *ipr;
+ s_wsfe(&io___116);
+ e_wsfe();
+ io___117.ciunit = *ipr;
+ s_wsfe(&io___117);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ do_fio(&c__1, (char *)&i__, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&g[i__], (ftnlen)sizeof(doublereal));
+ do_fio(&c__1, (char *)&wrk1[i__], (ftnlen)sizeof(doublereal));
+ }
+ e_wsfe();
+ *msg = -21;
+L20:
+ return 0;
+} /* grdchk_ */
+
+/* ---------------------- */
+/* | H E S C H K | */
+/* ---------------------- */
+/* Subroutine */ int heschk_(integer *nr, integer *n, doublereal *x, S_fp fcn,
+ S_fp grd, S_fp hsn, doublereal *f, doublereal *g, doublereal *a,
+ doublereal *typsiz, doublereal *typx, doublereal *rnf, doublereal *
+ analtl, integer *iagflg, doublereal *udiag, doublereal *wrk1,
+ doublereal *wrk2, integer *msg, integer *ipr, integer *ifn)
+{
+ /* Format strings */
+ static char fmt_901[] = "(\002 HESCHK PROBABLE ERROR IN CODING OF ANA"
+ "LYTIC\002,\002 HESSIAN FUNCTION.\002/\002 HESCHK ROW CO"
+ "L\002,14x,\002ANALYTIC\002,14x,\002(ESTIMATE)\002)";
+ static char fmt_902[] = "(\002 HESCHK \002,2i5,2x,e20.13,2x,\002(\002"
+ ",e20.13,\002)\002)";
+
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+ doublereal d__1, d__2, d__3, d__4, d__5;
+
+ /* Builtin functions */
+ integer s_wsfe(cilist *), e_wsfe(void), do_fio(integer *, char *, ftnlen);
+
+ /* Local variables */
+ integer i__, j;
+ doublereal hs;
+ integer im1, jp1, ker;
+ extern /* Subroutine */ int sndofd_(integer *, integer *, doublereal *,
+ S_fp, doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, integer *), fstofd_(integer *,
+ integer *, integer *, doublereal *, S_fp, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *, integer *,
+ integer *);
+
+ /* Fortran I/O blocks */
+ static cilist io___123 = { 0, 0, 0, fmt_901, 0 };
+ static cilist io___125 = { 0, 0, 0, fmt_902, 0 };
+ static cilist io___126 = { 0, 0, 0, fmt_902, 0 };
+
+
+
+/* PURPOSE */
+/* ------- */
+/* CHECK ANALYTIC HESSIAN AGAINST ESTIMATED HESSIAN */
+/* (THIS MAY BE DONE ONLY IF THE USER SUPPLIED ANALYTIC HESSIAN */
+/* HSN FILLS ONLY THE LOWER TRIANGULAR PART AND DIAGONAL OF A) */
+
+/* PARAMETERS */
+/* ---------- */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> ESTIMATE TO A ROOT OF FCN */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE OPTIMIZATION FUNCTION */
+/* MUST BE DECLARED EXTERNAL IN CALLING ROUTINE */
+/* FCN: R(N) --> R(1) */
+/* GRD --> NAME OF SUBROUTINE TO EVALUATE GRADIENT OF FCN. */
+/* MUST BE DECLARED EXTERNAL IN CALLING ROUTINE */
+/* HSN --> NAME OF SUBROUTINE TO EVALUATE HESSIAN OF FCN. */
+/* MUST BE DECLARED EXTERNAL IN CALLING ROUTINE */
+/* HSN SHOULD FILL ONLY THE LOWER TRIANGULAR PART */
+/* AND DIAGONAL OF A */
+/* F --> FUNCTION VALUE: FCN(X) */
+/* G(N) <-- GRADIENT: G(X) */
+/* A(N,N) <-- ON EXIT: HESSIAN IN LOWER TRIANGULAR PART AND DIAG */
+/* TYPSIZ(N) --> TYPICAL SIZE FOR EACH COMPONENT OF X */
+/* RNF --> RELATIVE NOISE IN OPTIMIZATION FUNCTION FCN */
+/* ANALTL --> TOLERANCE FOR COMPARISON OF ESTIMATED AND */
+/* ANALYTICAL GRADIENTS */
+/* IAGFLG --> =1 IF ANALYTIC GRADIENT SUPPLIED */
+/* UDIAG(N) --> WORKSPACE */
+/* WRK1(N) --> WORKSPACE */
+/* WRK2(N) --> WORKSPACE */
+/* MSG <--> MESSAGE OR ERROR CODE */
+/* ON INPUT : IF =1XX DO NOT COMPARE ANAL + EST HESS */
+/* ON OUTPUT: =-22, PROBABLE CODING ERROR OF HESSIAN */
+/* IPR --> DEVICE TO WHICH TO SEND OUTPUT */
+/* IFN <--> NUMBER OF FUNCTION EVALUTATIONS */
+
+/* COMPUTE FINITE DIFFERENCE APPROXIMATION A TO THE HESSIAN. */
+
+ /* Parameter adjustments */
+ a_dim1 = *nr;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+ --wrk2;
+ --wrk1;
+ --udiag;
+ --typx;
+ --typsiz;
+ --g;
+ --x;
+
+ /* Function Body */
+ if (*iagflg == 1) {
+ fstofd_(nr, n, n, &x[1], (S_fp)grd, &g[1], &a[a_offset], &typx[1],
+ rnf, &wrk1[1], &c__3, ifn);
+ }
+ if (*iagflg != 1) {
+ sndofd_(nr, n, &x[1], (S_fp)fcn, f, &a[a_offset], &typx[1], rnf, &
+ wrk1[1], &wrk2[1], ifn);
+ }
+
+ ker = 0;
+
+/* COPY LOWER TRIANGULAR PART OF "A" TO UPPER TRIANGULAR PART */
+/* AND DIAGONAL OF "A" TO UDIAG */
+
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ udiag[j] = a[j + j * a_dim1];
+ if (j == *n) {
+ goto L30;
+ }
+ jp1 = j + 1;
+ i__2 = *n;
+ for (i__ = jp1; i__ <= i__2; ++i__) {
+ a[j + i__ * a_dim1] = a[i__ + j * a_dim1];
+/* L25: */
+ }
+L30:
+ ;
+ }
+
+/* COMPUTE ANALYTIC HESSIAN AND COMPARE TO FINITE DIFFERENCE */
+/* APPROXIMATION. */
+
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ i__2 = *n;
+ for (j = i__; j <= i__2; ++j) {
+ a[j + i__ * a_dim1] = 0.;
+/* L32: */
+ }
+ }
+
+ (*hsn)(nr, n, &x[1], &a[a_offset]);
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+/* Computing MAX */
+ d__3 = (d__1 = g[j], abs(d__1));
+/* Computing MAX */
+ d__4 = (d__2 = x[j], abs(d__2)), d__5 = typsiz[j];
+ hs = max(d__3,1.) / max(d__4,d__5);
+/* Computing MAX */
+ d__3 = (d__1 = udiag[j], abs(d__1));
+ if ((d__2 = a[j + j * a_dim1] - udiag[j], abs(d__2)) > max(d__3,hs) *
+ *analtl) {
+ ker = 1;
+ }
+ if (j == *n) {
+ goto L40;
+ }
+ jp1 = j + 1;
+ i__1 = *n;
+ for (i__ = jp1; i__ <= i__1; ++i__) {
+/* Computing MAX */
+ d__3 = (d__1 = a[i__ + j * a_dim1], abs(d__1));
+ if ((d__2 = a[i__ + j * a_dim1] - a[j + i__ * a_dim1], abs(d__2))
+ > max(d__3,hs) * *analtl) {
+ ker = 1;
+ }
+/* L35: */
+ }
+L40:
+ ;
+ }
+
+ if (ker == 0) {
+ goto L90;
+ }
+ io___123.ciunit = *ipr;
+ s_wsfe(&io___123);
+ e_wsfe();
+ i__2 = *n;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ if (i__ == 1) {
+ goto L45;
+ }
+ im1 = i__ - 1;
+ i__1 = im1;
+ for (j = 1; j <= i__1; ++j) {
+ io___125.ciunit = *ipr;
+ s_wsfe(&io___125);
+ do_fio(&c__1, (char *)&i__, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&j, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&a[i__ + j * a_dim1], (ftnlen)sizeof(
+ doublereal));
+ do_fio(&c__1, (char *)&a[j + i__ * a_dim1], (ftnlen)sizeof(
+ doublereal));
+ e_wsfe();
+/* L43: */
+ }
+L45:
+ io___126.ciunit = *ipr;
+ s_wsfe(&io___126);
+ do_fio(&c__1, (char *)&i__, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&i__, (ftnlen)sizeof(integer));
+ do_fio(&c__1, (char *)&a[i__ + i__ * a_dim1], (ftnlen)sizeof(
+ doublereal));
+ do_fio(&c__1, (char *)&udiag[i__], (ftnlen)sizeof(doublereal));
+ e_wsfe();
+/* L50: */
+ }
+ *msg = -22;
+/* ENDIF */
+L90:
+ return 0;
+} /* heschk_ */
+
+/* ----------------------- */
+/* | M C H E P S | */
+/* ----------------------- */
+/* Subroutine */ int mcheps_(doublereal *eps)
+{
+ doublereal temp, temp1;
+
+
+/* PURPOSE: */
+/* COMPUTE MACHINE PRECISION */
+
+/* ------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* EPS <-- MACHINE PRECISION */
+
+ temp = 1.;
+L20:
+ temp /= 2.;
+ temp1 = temp + 1.;
+ if (temp1 != 1.) {
+ goto L20;
+ }
+ *eps = temp * 2.;
+ return 0;
+} /* mcheps_ */
+
+
+doublereal twonrm_(integer *n, doublereal *v)
+{
+ /* System generated locals */
+ doublereal ret_val;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ doublereal temp;
+
+
+/* PURPOSE: */
+/* COMPUTER L-2 NORM */
+
+/* -------------------------------------------------------------------------- */
+
+/* PARAMETER: */
+
+/* N --> DIMENSION OF PROBLEM */
+/* V(N) --> VECTOR WHICH L-2 NORM IS EVALUATED */
+
+ /* Parameter adjustments */
+ --v;
+
+ /* Function Body */
+ temp = ddot_(n, &v[1], &c__1, &v[1], &c__1);
+ ret_val = sqrt(temp);
+ return ret_val;
+} /* twonrm_ */
+
+/* ---------------------- */
+/* | L N S R C H | */
+/* ---------------------- */
+/* Subroutine */ int lnsrch_(integer *nr, integer *n, doublereal *x,
+ doublereal *f, doublereal *g, doublereal *p, doublereal *xpls,
+ doublereal *fpls, logical *mxtake, integer *iretcd, doublereal *
+ stepmx, doublereal *steptl, doublereal *typx, S_fp fcn, doublereal *
+ w2, integer *nfcnt)
+{
+ /* System generated locals */
+ integer i__1;
+ doublereal d__1, d__2;
+
+ /* Builtin functions */
+ double sqrt(doublereal), d_sign(doublereal *, doublereal *);
+
+ /* Local variables */
+ doublereal a, b;
+ integer i__, k;
+ doublereal t1, t2, t3, scl, rln, sln, slp, tmp, disc;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ doublereal temp, temp1, temp2, alpha;
+ extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *,
+ integer *);
+ doublereal pfpls, almbda, plmbda, tlmbda, almbmn;
+
+
+/* THE ALPHA CONDITION ONLY LINE SEARCH */
+
+/* PURPOSE */
+/* ------- */
+/* FIND A NEXT NEWTON ITERATE BY LINE SEARCH. */
+
+/* PARAMETERS */
+/* ---------- */
+/* N --> DIMENSION OF PROBLEM */
+/* X(N) --> OLD ITERATE: X[K-1] */
+/* F --> FUNCTION VALUE AT OLD ITERATE, F(X) */
+/* G(N) --> GRADIENT AT OLD ITERATE, G(X), OR APPROXIMATE */
+/* P(N) --> NON-ZERO NEWTON STEP */
+/* XPLS(N) <-- NEW ITERATE X[K] */
+/* FPLS <-- FUNCTION VALUE AT NEW ITERATE, F(XPLS) */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION */
+/* IRETCD <-- RETURN CODE */
+/* MXTAKE <-- BOOLEAN FLAG INDICATING STEP OF MAXIMUM LENGTH USED */
+/* STEPMX --> MAXIMUM ALLOWABLE STEP SIZE */
+/* STEPTL --> RELATIVE STEP SIZE AT WHICH SUCCESSIVE ITERATES */
+/* CONSIDERED CLOSE ENOUGH TO TERMINATE ALGORITHM */
+/* TYPX(N) --> DIAGONAL SCALING MATRIX FOR X (NOT IN UNCMIN) */
+/* IPR --> DEVICE TO WHICH TO SEND OUTPUT */
+/* W2 --> WORKING SPACE */
+/* NFCNT <--> NUMBER OF FUNCTION EVALUTIONS */
+
+/* INTERNAL VARIABLES */
+/* ------------------ */
+/* SLN NEWTON LENGTH */
+/* RLN RELATIVE LENGTH OF NEWTON STEP */
+
+
+ /* Parameter adjustments */
+ --w2;
+ --typx;
+ --xpls;
+ --p;
+ --g;
+ --x;
+
+ /* Function Body */
+ *mxtake = FALSE_;
+ *iretcd = 2;
+ alpha = 1e-4;
+/* $ WRITE(IPR,954) */
+/* $ WRITE(IPR,955) (P(I),I=1,N) */
+ tmp = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ tmp += p[i__] * p[i__];
+/* L5: */
+ }
+ sln = sqrt(tmp);
+ if (sln <= *stepmx) {
+ goto L10;
+ }
+
+/* NEWTON STEP LONGER THAN MAXIMUM ALLOWED */
+ scl = *stepmx / sln;
+ dscal_(n, &scl, &p[1], &c__1);
+ sln = *stepmx;
+/* $ WRITE(IPR,954) */
+/* $ WRITE(IPR,955) (P(I),I=1,N) */
+L10:
+ slp = ddot_(n, &g[1], &c__1, &p[1], &c__1);
+ rln = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ temp = 1.;
+ temp1 = (d__1 = x[i__], abs(d__1));
+ temp2 = max(temp1,temp);
+ temp1 = (d__1 = p[i__], abs(d__1));
+/* Computing MAX */
+ d__1 = rln, d__2 = temp1 / temp2;
+ rln = max(d__1,d__2);
+/* L15: */
+ }
+ almbmn = *steptl / rln;
+ almbda = 1.;
+/* $ WRITE(IPR,952) SLN,SLP,RMNLMB,STEPMX,STEPTL */
+
+/* LOOP */
+/* CHECK IF NEW ITERATE SATISFACTORY. GENERATE NEW LAMBDA IF NECESSARY. */
+
+L100:
+ if (*iretcd < 2) {
+ return 0;
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ xpls[i__] = x[i__] + almbda * p[i__];
+/* L105: */
+ }
+ i__1 = *n;
+ for (k = 1; k <= i__1; ++k) {
+ w2[k] = xpls[k] * typx[k];
+/* L101: */
+ }
+ (*fcn)(n, &w2[1], fpls);
+ ++(*nfcnt);
+/* $ WRITE(IPR,956) ALMBDA */
+/* $ WRITE(IPR,951) */
+/* $ WRITE(IPR,955) (XPLS(I),I=1,N) */
+/* $ WRITE(IPR,953) FPLS */
+ if (*fpls > *f + slp * alpha * almbda) {
+ goto L130;
+ }
+/* IF(FPLS.LE. F+SLP*1.E-4*ALMBDA) */
+/* THEN */
+
+/* SOLUTION FOUND */
+
+ *iretcd = 0;
+ if (almbda == 1. && sln > *stepmx * .99) {
+ *mxtake = TRUE_;
+ }
+ goto L100;
+
+/* SOLUTION NOT (YET) FOUND */
+
+/* ELSE */
+L130:
+ if (almbda >= almbmn) {
+ goto L140;
+ }
+/* IF(ALMBDA .LT. ALMBMN) */
+/* THEN */
+
+/* NO SATISFACTORY XPLS FOUND SUFFICIENTLY DISTINCT FROM X */
+
+ *iretcd = 1;
+ goto L100;
+/* ELSE */
+
+/* CALCULATE NEW LAMBDA */
+
+L140:
+ if (almbda != 1.) {
+ goto L150;
+ }
+/* IF(ALMBDA.EQ.1.0) */
+/* THEN */
+
+/* FIRST BACKTRACK: QUADRATIC FIT */
+
+ tlmbda = -slp / ((*fpls - *f - slp) * 2.);
+ goto L170;
+/* ELSE */
+
+/* ALL SUBSEQUENT BACKTRACKS: CUBIC FIT */
+
+L150:
+ t1 = *fpls - *f - almbda * slp;
+ t2 = pfpls - *f - plmbda * slp;
+ t3 = 1. / (almbda - plmbda);
+ a = t3 * (t1 / (almbda * almbda) - t2 / (plmbda * plmbda));
+ b = t3 * (t2 * almbda / (plmbda * plmbda) - t1 * plmbda / (almbda *
+ almbda));
+ disc = b * b - a * 3.f * slp;
+ if (disc <= b * b) {
+ goto L160;
+ }
+/* IF(DISC.GT. B*B) */
+/* THEN */
+
+/* ONLY ONE POSITIVE CRITICAL POINT, MUST BE MINIMUM */
+
+ tlmbda = (-b + d_sign(&c_b324, &a) * sqrt(disc)) / (a * 3.f);
+ goto L165;
+/* ELSE */
+
+/* BOTH CRITICAL POINTS POSITIVE, FIRST IS MINIMUM */
+
+L160:
+ tlmbda = (-b - d_sign(&c_b324, &a) * sqrt(disc)) / (a * 3.f);
+/* ENDIF */
+L165:
+ if (tlmbda > almbda * .5) {
+ tlmbda = almbda * .5;
+ }
+/* ENDIF */
+L170:
+ plmbda = almbda;
+ pfpls = *fpls;
+ if (tlmbda >= almbda * .1) {
+ goto L180;
+ }
+/* IF(TLMBDA.LT.ALMBDA/10.) */
+/* THEN */
+ almbda *= .1f;
+ goto L190;
+/* ELSE */
+L180:
+ almbda = tlmbda;
+/* ENDIF */
+/* ENDIF */
+/* ENDIF */
+L190:
+ goto L100;
+/* L956: */
+/* L951: */
+/* L952: */
+/* L953: */
+/* L954: */
+/* L955: */
+} /* lnsrch_ */
+
+/* ---------------------- */
+/* | Z H Z | */
+/* ---------------------- */
+/* Subroutine */ int zhz_(integer *nr, integer *n, doublereal *y, doublereal *
+ h__, doublereal *u, doublereal *t)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, i__1, i__2;
+ doublereal d__1;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ doublereal d__;
+ integer i__, j;
+ doublereal s, sgn;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ doublereal temp1, temp2;
+ extern /* Subroutine */ int dcopy_(integer *, doublereal *, integer *,
+ doublereal *, integer *);
+ doublereal ynorm;
+
+
+/* PURPOSE: */
+/* COMPUTE QTHQ(N,N) AND ZTHZ(N-1,N-1) = FIRST N-1 ROWS AND */
+/* FIRST N-1 COLUMNS OF QTHQ */
+
+/* --------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* Y(N) --> FIRST BASIS IN Q */
+/* H(N,N) <--> ON INPUT : HESSIAN */
+/* ON OUTPUT: QTHQ (ZTHZ) */
+/* U(N) <-- VECTOR TO FORM Q AND Z */
+/* T(N) --> WORKSPACE */
+
+
+/* U=Y+SGN(Y(N))||Y||E(N) */
+ /* Parameter adjustments */
+ --t;
+ --u;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+ --y;
+
+ /* Function Body */
+ if (y[*n] != 0.) {
+ sgn = y[*n] / (d__1 = y[*n], abs(d__1));
+ } else {
+ sgn = 1.;
+ }
+ ynorm = ddot_(n, &y[1], &c__1, &y[1], &c__1);
+ ynorm = sqrt(ynorm);
+ u[*n] = y[*n] + sgn * ynorm;
+ i__1 = *n - 1;
+ dcopy_(&i__1, &y[1], &c__1, &u[1], &c__1);
+
+/* D=UTU/2 */
+ d__ = ddot_(n, &u[1], &c__1, &u[1], &c__1);
+ d__ /= 2.;
+
+/* T=2HU/UTU */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ t[i__] = 0.;
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ t[i__] = h__[i__ + j * h_dim1] * u[j] + t[i__];
+/* L30: */
+ }
+ t[i__] /= d__;
+/* L40: */
+ }
+
+/* S=4UHU/(UTU)**2 */
+ s = ddot_(n, &u[1], &c__1, &t[1], &c__1);
+ s /= d__;
+
+/* COMPUTE QTHQ (ZTHZ) */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ temp1 = u[i__];
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ temp2 = u[j];
+ h__[i__ + j * h_dim1] = h__[i__ + j * h_dim1] - u[i__] * t[j] - t[
+ i__] * u[j] + u[i__] * u[j] * s;
+/* L60: */
+ }
+/* L70: */
+ }
+ return 0;
+} /* zhz_ */
+
+/* ---------------------- */
+/* | S O L V E W | */
+/* ---------------------- */
+/* Subroutine */ int solvew_(integer *nr, integer *n, doublereal *al,
+ doublereal *u, doublereal *w, doublereal *b)
+{
+ /* System generated locals */
+ integer al_dim1, al_offset, i__1, i__2;
+
+ /* Local variables */
+ doublereal d__;
+ integer i__, j;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ extern /* Subroutine */ int forslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *);
+
+
+/* PURPOSE: */
+/* SOLVE L*W=ZT*V */
+
+/* ---------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* AL(N-1,N-1) --> LOWER TRIAGULAR MATRIX */
+/* U(N) --> VECTOR TO FORM Z */
+/* W(N) --> ON INPUT : VECTOR V IN SYSTEM OF LINEAR EQUATIONS */
+/* ON OUTPUT: SOLUTION OF SYSTEM OF LINEAR EQUATIONS */
+/* B(N) --> WORKSPACE TO STORE ZT*V */
+
+/* FORM ZT*V (STORED IN B) */
+ /* Parameter adjustments */
+ al_dim1 = *nr;
+ al_offset = 1 + al_dim1;
+ al -= al_offset;
+ --b;
+ --w;
+ --u;
+
+ /* Function Body */
+ d__ = ddot_(n, &u[1], &c__1, &u[1], &c__1);
+ d__ /= 2.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ b[i__] = 0.;
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ b[i__] += u[j] * u[i__] * w[j] / d__;
+/* L15: */
+ }
+ b[i__] = w[i__] - b[i__];
+/* L20: */
+ }
+
+/* SOLVE LW=ZT*V */
+ i__1 = *n - 1;
+ forslv_(nr, &i__1, &al[al_offset], &w[1], &b[1]);
+ return 0;
+} /* solvew_ */
+
+/* ---------------------- */
+/* | D S T A R | */
+/* ---------------------- */
+/* Subroutine */ int dstar_(integer *nr, integer *n, doublereal *u,
+ doublereal *s, doublereal *w1, doublereal *w2, doublereal *w3,
+ doublereal *sigma, doublereal *al, doublereal *d__)
+{
+ /* System generated locals */
+ integer al_dim1, al_offset, i__1;
+
+ /* Local variables */
+ integer i__;
+ doublereal utt, utu;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+ doublereal temp;
+ extern /* Subroutine */ int bakslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *);
+
+
+/* PURPOSE: */
+/* COMPUTE TENSOR STEP D=SIGMA*S+ZT*T(SIGMA) */
+
+/* ------------------------------------------------------------------------ */
+
+/* PARAMETERS: */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* U(N) --> VECTOR TO FORM Z */
+/* S(N) --> PREVIOUS STEP */
+/* W1(N) --> L**-1*ZT*A, WHERE A IS DESCRIBED IN SUBROUTINE SLVMDL */
+/* W2(N) --> L**-1*ZT*SH, WHERE H IS CURRENT HESSIAN */
+/* W3(N) --> L**-1*ZT*G, WHERE G IS CURRENT GRADIENT */
+/* SIGMA --> SOLUTION FOR REDUCED ONE VARIABLE MODEL */
+/* AL(N-1,N-1) --> LOWER TRIANGULAR MATRIX L */
+/* D(N) --> TENSOR STEP */
+
+ /* Parameter adjustments */
+ al_dim1 = *nr;
+ al_offset = 1 + al_dim1;
+ al -= al_offset;
+ --d__;
+ --w3;
+ --w2;
+ --w1;
+ --s;
+ --u;
+
+ /* Function Body */
+ if (*n == 1) {
+ d__[1] = *sigma * s[1];
+ } else {
+
+/* COMPUTE T(SIGMA)=-(ZTHZ)*ZT*(G+SIGMA*SH+SIGMA**2*A/2) (STORED IN D) */
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w2[i__] = w3[i__] + *sigma * w2[i__] + w1[i__] * .5 * *sigma * *
+ sigma;
+/* L10: */
+ }
+ i__1 = *n - 1;
+ bakslv_(nr, &i__1, &al[al_offset], &d__[1], &w2[1]);
+ d__[*n] = 0.;
+
+/* COMPUTE TENSOR STEP D=SIGMA*S+ZT*T(SIGMA) */
+ utu = ddot_(n, &u[1], &c__1, &u[1], &c__1);
+ utt = ddot_(n, &u[1], &c__1, &d__[1], &c__1);
+ temp = utt / utu;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ d__[i__] = *sigma * s[i__] - (d__[i__] - u[i__] * 2. * temp);
+/* L50: */
+ }
+ }
+ return 0;
+} /* dstar_ */
+
+/* ---------------------- */
+/* | M K M D L | */
+/* ---------------------- */
+/* Subroutine */ int mkmdl_(integer *nr, integer *n, doublereal *f,
+ doublereal *fp, doublereal *g, doublereal *gp, doublereal *s,
+ doublereal *h__, doublereal *alpha, doublereal *beta, doublereal *sh,
+ doublereal *a)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, i__1, i__2;
+
+ /* Local variables */
+ integer i__, j;
+ doublereal b1, b2, gs, gps, shs, sts;
+ extern doublereal ddot_(integer *, doublereal *, integer *, doublereal *,
+ integer *);
+
+
+/* PURPOSE: */
+/* FORM TENSOR MODEL */
+
+/* ----------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* F --> CURRENT FUNCTION VALUE */
+/* FP --> PREVIOUS FUNCTION VALUE */
+/* G(N) --> CURRENT GRADIENT */
+/* GP(N) --> PREVIOUS GRADIENT */
+/* S(N) --> STEP TO PREVIOUS POINT */
+/* H(N,N) --> HESSIAN */
+/* ALPHA <-- SCALAR TO FORM 3RD ORDER TERM OF TENSOR MODEL */
+/* BETA <-- SCALAR TO FORM 4TH ORDER TERM OF TENSOR MODEL */
+/* SH(N) <-- SH */
+/* A(N) <-- A=2*(GP-G-SH-S*BETA/(6*STS)) */
+
+
+/* COMPUTE SH */
+ /* Parameter adjustments */
+ --a;
+ --sh;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+ --s;
+ --gp;
+ --g;
+
+ /* Function Body */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ sh[i__] = 0.;
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ sh[i__] += s[j] * h__[j + i__ * h_dim1];
+/* L10: */
+ }
+/* L20: */
+ }
+ gs = ddot_(n, &g[1], &c__1, &s[1], &c__1);
+ gps = ddot_(n, &gp[1], &c__1, &s[1], &c__1);
+ shs = ddot_(n, &sh[1], &c__1, &s[1], &c__1);
+ b1 = gps - gs - shs;
+ b2 = *fp - *f - gs - shs * .5;
+ *alpha = b2 * 24. - b1 * 6.;
+ *beta = b1 * 24. - b2 * 72.;
+
+/* COMPUTE A */
+ sts = ddot_(n, &s[1], &c__1, &s[1], &c__1);
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ a[i__] = (gp[i__] - g[i__] - sh[i__] - s[i__] * *beta / (sts * 6.)) *
+ 2.;
+/* L50: */
+ }
+ return 0;
+} /* mkmdl_ */
+
+/* ---------------------- */
+/* | S I G M A | */
+/* ---------------------- */
+/* Subroutine */ int sigma_(doublereal *sgstar, doublereal *a, doublereal *b,
+ doublereal *c__, doublereal *d__)
+{
+ doublereal s1, s2, s3;
+ extern /* Subroutine */ int roots_(doublereal *, doublereal *, doublereal
+ *, doublereal *, doublereal *, doublereal *, doublereal *),
+ sortrt_(doublereal *, doublereal *, doublereal *);
+
+
+/* PURPOSE: */
+/* COMPUTE DESIRABLE ROOT OF REDUCED ONE VARIABLE EQUATION */
+
+/* ------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+/* SGSTAR --> DESIRABLE ROOT */
+/* A --> COEFFICIENT OF 3RD ORDER TERM */
+/* B --> COEFFICIENT OF 2ND ORDER TERM */
+/* C --> COEFFICIENT OF 1ST ORDER TERM */
+/* D --> COEFFICIENT OF CONSTANT TERM */
+
+
+/* COMPUTE ALL THREE ROOTS */
+ roots_(&s1, &s2, &s3, a, b, c__, d__);
+
+/* SORT ROOTS */
+ sortrt_(&s1, &s2, &s3);
+
+/* CHOOSE DESIRABLE ROOT */
+ if (*a > 0.) {
+ *sgstar = s3;
+ if (s2 >= 0.) {
+ *sgstar = s1;
+ }
+ } else {
+/* IF A < 0 THEN */
+ *sgstar = s2;
+ if (s1 > 0. || s3 < 0.) {
+ if (s1 > 0.) {
+ *sgstar = s1;
+ } else {
+ *sgstar = s3;
+ }
+ *a = 0.;
+ }
+ }
+ return 0;
+} /* sigma_ */
+
+/* ---------------------- */
+/* | R O O T S | */
+/* ---------------------- */
+/* Subroutine */ int roots_(doublereal *s1, doublereal *s2, doublereal *s3,
+ doublereal *a, doublereal *b, doublereal *c__, doublereal *d__)
+{
+ /* System generated locals */
+ doublereal d__1;
+
+ /* Builtin functions */
+ double sqrt(doublereal), pow_dd(doublereal *, doublereal *), acos(
+ doublereal), cos(doublereal);
+
+ /* Local variables */
+ doublereal q, r__, s, t, v, a1, a2, a3, pi, temp, theta;
+
+
+/* PURPOSE: */
+/* COMPUTE ROOT(S) OF 3RD ORDER EQUATION */
+
+/* --------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+/* S1 <-- ROOT (IF THREE ROOTS ARE */
+/* S2 <-- ROOT EQUAL, THEN S1=S2=S3) */
+/* S3 <-- ROOT */
+/* A --> COEFFICIENT OF 3RD ORDER TERM */
+/* B --> COEFFICIENT OF 2ND ORDER TERM */
+/* C --> COEFFICIENT OF 1ST ORDER TERM */
+/* D --> COEFFICIENT OF CONSTANT TERM */
+
+/* SET VALUE OF PI */
+ pi = 3.141592653589793;
+ a1 = *b / *a;
+ a2 = *c__ / *a;
+ a3 = *d__ / *a;
+ q = (a2 * 3. - a1 * a1) / 9.;
+ r__ = (a1 * 9. * a2 - a3 * 27. - a1 * 2. * a1 * a1) / 54.;
+ v = q * q * q + r__ * r__;
+ if (v > 0.) {
+ s = r__ + sqrt(v);
+ t = r__ - sqrt(v);
+ if (t < 0.) {
+ d__1 = -t;
+ t = -pow_dd(&d__1, &c_b250);
+ } else {
+ t = pow_dd(&t, &c_b250);
+ }
+ if (s < 0.) {
+ d__1 = -s;
+ s = -pow_dd(&d__1, &c_b250);
+ } else {
+ s = pow_dd(&s, &c_b250);
+ }
+ *s1 = s + t - a1 / 3.;
+ *s3 = *s1;
+ *s2 = *s1;
+ } else {
+ temp = r__ / sqrt(-pow_dd(&q, &c_b384));
+ theta = acos(temp);
+ theta /= 3.;
+ temp = sqrt(-q) * 2.;
+ *s1 = temp * cos(theta) - a1 / 3.;
+ *s2 = temp * cos(theta + pi * 2. / 3.) - a1 / 3.;
+ *s3 = temp * cos(theta + pi * 4. / 3.) - a1 / 3.;
+ }
+ return 0;
+} /* roots_ */
+
+/* ---------------------- */
+/* | S O R T R T | */
+/* ---------------------- */
+/* Subroutine */ int sortrt_(doublereal *s1, doublereal *s2, doublereal *s3)
+{
+ doublereal t;
+
+
+/* PURPOSE: */
+/* SORT ROOTS INTO ASCENDING ORDER */
+
+/* ----------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+/* S1 <--> ROOT */
+/* S2 <--> ROOT */
+/* S3 <--> ROOT */
+
+ if (*s1 > *s2) {
+ t = *s1;
+ *s1 = *s2;
+ *s2 = t;
+ }
+ if (*s2 > *s3) {
+ t = *s2;
+ *s2 = *s3;
+ *s3 = t;
+ }
+ if (*s1 > *s2) {
+ t = *s1;
+ *s1 = *s2;
+ *s2 = t;
+ }
+ return 0;
+} /* sortrt_ */
+
+/* ---------------------- */
+/* | F S T O F D | */
+/* ---------------------- */
+/* Subroutine */ int fstofd_(integer *nr, integer *m, integer *n, doublereal *
+ xpls, S_fp fcn, doublereal *fpls, doublereal *a, doublereal *typx,
+ doublereal *rnoise, doublereal *fhat, integer *icase, integer *nfcnt)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+ doublereal d__1, d__2;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ integer i__, j, jp1, nm1;
+ doublereal xtmpj, stepsz;
+
+/* PURPOSE */
+/* ------- */
+/* FIND FIRST ORDER FORWARD FINITE DIFFERENCE APPROXIMATION "A" TO THE */
+/* FIRST DERIVATIVE OF THE FUNCTION DEFINED BY THE SUBPROGRAM "FNAME" */
+/* EVALUATED AT THE NEW ITERATE "XPLS". */
+
+
+/* FOR OPTIMIZATION USE THIS ROUTINE TO ESTIMATE: */
+/* 1) THE FIRST DERIVATIVE (GRADIENT) OF THE OPTIMIZATION FUNCTION "FCN */
+/* ANALYTIC USER ROUTINE HAS BEEN SUPPLIED; */
+/* 2) THE SECOND DERIVATIVE (HESSIAN) OF THE OPTIMIZATION FUNCTION */
+/* IF NO ANALYTIC USER ROUTINE HAS BEEN SUPPLIED FOR THE HESSIAN BUT */
+/* ONE HAS BEEN SUPPLIED FOR THE GRADIENT ("FCN") AND IF THE */
+/* OPTIMIZATION FUNCTION IS INEXPENSIVE TO EVALUATE */
+
+/* NOTE */
+/* ---- */
+/* _M=1 (OPTIMIZATION) ALGORITHM ESTIMATES THE GRADIENT OF THE FUNCTION */
+/* (FCN). FCN(X) # F: R(N)-->R(1) */
+/* _M=N (SYSTEMS) ALGORITHM ESTIMATES THE JACOBIAN OF THE FUNCTION */
+/* FCN(X) # F: R(N)-->R(N). */
+/* _M=N (OPTIMIZATION) ALGORITHM ESTIMATES THE HESSIAN OF THE OPTIMIZATIO */
+/* FUNCTION, WHERE THE HESSIAN IS THE FIRST DERIVATIVE OF "FCN" */
+
+/* PARAMETERS */
+/* ---------- */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* M --> NUMBER OF ROWS IN A */
+/* N --> NUMBER OF COLUMNS IN A; DIMENSION OF PROBLEM */
+/* XPLS(N) --> NEW ITERATE: X[K] */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION */
+/* FPLS(M) --> _M=1 (OPTIMIZATION) FUNCTION VALUE AT NEW ITERATE: */
+/* FCN(XPLS) */
+/* _M=N (OPTIMIZATION) VALUE OF FIRST DERIVATIVE */
+/* (GRADIENT) GIVEN BY USER FUNCTION FCN */
+/* _M=N (SYSTEMS) FUNCTION VALUE OF ASSOCIATED */
+/* MINIMIZATION FUNCTION */
+/* A(NR,N) <-- FINITE DIFFERENCE APPROXIMATION (SEE NOTE). ONLY */
+/* LOWER TRIANGULAR MATRIX AND DIAGONAL ARE RETURNED */
+/* RNOISE --> RELATIVE NOISE IN FCN [F(X)] */
+/* FHAT(M) --> WORKSPACE */
+/* ICASE --> =1 OPTIMIZATION (GRADIENT) */
+/* =2 SYSTEMS */
+/* =3 OPTIMIZATION (HESSIAN) */
+/* NFCNT <--> NUMBER OF FUNCTION EVALUTIONS */
+
+/* INTERNAL VARIABLES */
+/* ------------------ */
+/* STEPSZ - STEPSIZE IN THE J-TH VARIABLE DIRECTION */
+
+
+/* FIND J-TH COLUMN OF A */
+/* EACH COLUMN IS DERIVATIVE OF F(FCN) WITH RESPECT TO XPLS(J) */
+
+ /* Parameter adjustments */
+ --fhat;
+ --fpls;
+ --typx;
+ a_dim1 = *nr;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+ --xpls;
+
+ /* Function Body */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+ xtmpj = xpls[j];
+/* Computing MAX */
+ d__2 = (d__1 = xpls[j], abs(d__1));
+ stepsz = sqrt(*rnoise) * max(d__2,1.);
+ xpls[j] = xtmpj + stepsz;
+ (*fcn)(n, &xpls[1], &fhat[1]);
+ ++(*nfcnt);
+ xpls[j] = xtmpj;
+ i__2 = *m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ a[i__ + j * a_dim1] = (fhat[i__] - fpls[i__]) / stepsz;
+ a[i__ + j * a_dim1] *= typx[j];
+/* L20: */
+ }
+/* L30: */
+ }
+ if (*icase != 3) {
+ return 0;
+ }
+
+/* IF COMPUTING HESSIAN, A MUST BE SYMMETRIC */
+
+ if (*n == 1) {
+ return 0;
+ }
+ nm1 = *n - 1;
+ i__1 = nm1;
+ for (j = 1; j <= i__1; ++j) {
+ jp1 = j + 1;
+ i__2 = *m;
+ for (i__ = jp1; i__ <= i__2; ++i__) {
+ a[i__ + j * a_dim1] = (a[i__ + j * a_dim1] + a[j + i__ * a_dim1])
+ / 2.f;
+/* L40: */
+ }
+/* L50: */
+ }
+ return 0;
+} /* fstofd_ */
+
+/* ---------------------- */
+/* | S N D O F D | */
+/* ---------------------- */
+/* Subroutine */ int sndofd_(integer *nr, integer *n, doublereal *xpls, S_fp
+ fcn, doublereal *fpls, doublereal *a, doublereal *typx, doublereal *
+ rnoise, doublereal *stepsz, doublereal *anbr, integer *nfcnt)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+ doublereal d__1, d__2;
+
+ /* Builtin functions */
+ double pow_dd(doublereal *, doublereal *);
+
+ /* Local variables */
+ integer i__, j, ip1;
+ doublereal ov3, fhat, xtmpi, xtmpj;
+
+/* PURPOSE */
+/* ------- */
+/* FIND SECOND ORDER FORWARD FINITE DIFFERENCE APPROXIMATION "A" */
+/* TO THE SECOND DERIVATIVE (HESSIAN) OF THE FUNCTION DEFINED BY THE SUBP */
+/* "FCN" EVALUATED AT THE NEW ITERATE "XPLS" */
+
+/* FOR OPTIMIZATION USE THIS ROUTINE TO ESTIMATE */
+/* 1) THE SECOND DERIVATIVE (HESSIAN) OF THE OPTIMIZATION FUNCTION */
+/* IF NO ANALYTICAL USER FUNCTION HAS BEEN SUPPLIED FOR EITHER */
+/* THE GRADIENT OR THE HESSIAN AND IF THE OPTIMIZATION FUNCTION */
+/* "FCN" IS INEXPENSIVE TO EVALUATE. */
+
+/* PARAMETERS */
+/* ---------- */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* XPLS(N) --> NEW ITERATE: X[K] */
+/* FCN --> NAME OF SUBROUTINE TO EVALUATE FUNCTION */
+/* FPLS --> FUNCTION VALUE AT NEW ITERATE, F(XPLS) */
+/* A(N,N) <-- FINITE DIFFERENCE APPROXIMATION TO HESSIAN */
+/* ONLY LOWER TRIANGULAR MATRIX AND DIAGONAL */
+/* ARE RETURNED */
+/* RNOISE --> RELATIVE NOISE IN FNAME [F(X)] */
+/* STEPSZ(N) --> WORKSPACE (STEPSIZE IN I-TH COMPONENT DIRECTION) */
+/* ANBR(N) --> WORKSPACE (NEIGHBOR IN I-TH DIRECTION) */
+/* NFCNT <--> NUMBER OF FUNCTION EVALUATIONS */
+
+
+
+/* FIND I-TH STEPSIZE AND EVALUATE NEIGHBOR IN DIRECTION */
+/* OF I-TH UNIT VECTOR. */
+
+ /* Parameter adjustments */
+ --anbr;
+ --stepsz;
+ --typx;
+ a_dim1 = *nr;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+ --xpls;
+
+ /* Function Body */
+ ov3 = .33333333333333331;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ xtmpi = xpls[i__];
+/* Computing MAX */
+ d__2 = (d__1 = xpls[i__], abs(d__1));
+ stepsz[i__] = pow_dd(rnoise, &ov3) * max(d__2,1.);
+ xpls[i__] = xtmpi + stepsz[i__];
+ (*fcn)(n, &xpls[1], &anbr[i__]);
+ ++(*nfcnt);
+ xpls[i__] = xtmpi;
+/* L10: */
+ }
+
+/* CALCULATE COLUMN I OF A */
+
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ xtmpi = xpls[i__];
+ xpls[i__] = xtmpi + stepsz[i__] * 2.f;
+ (*fcn)(n, &xpls[1], &fhat);
+ ++(*nfcnt);
+ a[i__ + i__ * a_dim1] = (*fpls - anbr[i__] + (fhat - anbr[i__])) / (
+ stepsz[i__] * stepsz[i__]);
+ a[i__ + i__ * a_dim1] *= typx[i__] * typx[i__];
+
+/* CALCULATE SUB-DIAGONAL ELEMENTS OF COLUMN */
+ if (i__ == *n) {
+ goto L25;
+ }
+ xpls[i__] = xtmpi + stepsz[i__];
+ ip1 = i__ + 1;
+ i__2 = *n;
+ for (j = ip1; j <= i__2; ++j) {
+ xtmpj = xpls[j];
+ xpls[j] = xtmpj + stepsz[j];
+ (*fcn)(n, &xpls[1], &fhat);
+ ++(*nfcnt);
+ a[j + i__ * a_dim1] = (*fpls - anbr[i__] + (fhat - anbr[j])) / (
+ stepsz[i__] * stepsz[j]);
+ a[j + i__ * a_dim1] *= typx[i__] * typx[j];
+ xpls[j] = xtmpj;
+/* L20: */
+ }
+L25:
+ xpls[i__] = xtmpi;
+/* L30: */
+ }
+ return 0;
+} /* sndofd_ */
+
+/* ---------------------- */
+/* | B A K S L V | */
+/* ---------------------- */
+/* Subroutine */ int bakslv_(integer *nr, integer *n, doublereal *a,
+ doublereal *x, doublereal *b)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1;
+
+ /* Local variables */
+ integer i__, j, ip1;
+ doublereal sum;
+
+
+/* PURPOSE */
+/* ------- */
+/* SOLVE AX=B WHERE A IS UPPER TRIANGULAR MATRIX. */
+/* NOTE THAT A IS INPUT AS A LOWER TRIANGULAR MATRIX AND */
+/* THAT THIS ROUTINE TAKES ITS TRANSPOSE IMPLICITLY. */
+
+/* PARAMETERS */
+/* ---------- */
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* A(N,N) --> LOWER TRIANGULAR MATRIX (PRESERVED) */
+/* X(N) <-- SOLUTION VECTOR */
+/* B(N) --> RIGHT-HAND SIDE VECTOR */
+
+/* NOTE */
+/* ---- */
+/* IF B IS NO LONGER REQUIRED BY CALLING ROUTINE, */
+/* THEN VECTORS B AND X MAY SHARE THE SAME STORAGE. */
+
+
+/* SOLVE (L-TRANSPOSE)X=B. (BACK SOLVE) */
+
+ /* Parameter adjustments */
+ --b;
+ --x;
+ a_dim1 = *nr;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ i__ = *n;
+ x[i__] = b[i__] / a[i__ + i__ * a_dim1];
+ if (*n == 1) {
+ return 0;
+ }
+L30:
+ ip1 = i__;
+ --i__;
+ sum = 0.f;
+ i__1 = *n;
+ for (j = ip1; j <= i__1; ++j) {
+ sum += a[j + i__ * a_dim1] * x[j];
+/* L40: */
+ }
+ x[i__] = (b[i__] - sum) / a[i__ + i__ * a_dim1];
+ if (i__ > 1) {
+ goto L30;
+ }
+ return 0;
+} /* bakslv_ */
+
+/* ---------------------- */
+/* | F O R S L V | */
+/* ---------------------- */
+/* Subroutine */ int forslv_(integer *nr, integer *n, doublereal *a,
+ doublereal *x, doublereal *b)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+
+ /* Local variables */
+ integer i__, j, im1;
+ doublereal sum;
+
+
+/* PURPOSE */
+/* -------- */
+/* SOLVE AX=B WHERE A IS LOWER TRIANGULAR MATRIX */
+
+/* PARAMETERS */
+/* --------- */
+
+/* NR -----> ROW DIMENSION OF MATRIX */
+/* N -----> DIMENSION OF PROBLEM */
+/* A(N,N) -----> LOWER TRIANGULAR MATRIX (PRESERVED) */
+/* X(N) <---- SOLUTION VECTOR */
+/* B(N) ----> RIGHT-HAND SIDE VECTOR */
+
+/* NOTE */
+/* ----- */
+/* THEN VECTORS B AND X MAY SHARE THE SAME STORAGE */
+
+
+/* SOLVE LX=B. (FOREWARD SOLVE) */
+
+ /* Parameter adjustments */
+ --b;
+ --x;
+ a_dim1 = *nr;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ x[1] = b[1] / a[a_dim1 + 1];
+ if (*n == 1) {
+ return 0;
+ }
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ sum = 0.f;
+ im1 = i__ - 1;
+ i__2 = im1;
+ for (j = 1; j <= i__2; ++j) {
+ sum += a[i__ + j * a_dim1] * x[j];
+/* L10: */
+ }
+ x[i__] = (b[i__] - sum) / a[i__ + i__ * a_dim1];
+/* L20: */
+ }
+ return 0;
+} /* forslv_ */
+
+/* ---------------------- */
+/* | C H O L D R | */
+/* ---------------------- */
+/* Subroutine */ int choldr_(integer *nr, integer *n, doublereal *h__,
+ doublereal *g, doublereal *eps, integer *pivot, doublereal *e,
+ doublereal *diag, doublereal *addmax)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, i__1, i__2, i__3;
+
+ /* Builtin functions */
+ double pow_dd(doublereal *, doublereal *), sqrt(doublereal);
+
+ /* Local variables */
+ integer i__, j, k;
+ doublereal tau1, tau2;
+ logical redo;
+ doublereal temp;
+ extern /* Subroutine */ int modchl_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *, integer *,
+ doublereal *);
+
+
+/* PURPOSE: */
+/* DRIVER FOR CHOLESKY DECOMPOSITION */
+
+/* ---------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION */
+/* N --> DIMENSION OF PROBLEM */
+/* H(N,N) --> MATRIX */
+/* G(N) --> WORK SPACE */
+/* EPS --> MACHINE EPSILON */
+/* PIVOT(N) --> PIVOTING VECTOR */
+/* E(N) --> DIAGONAL MATRIX ADDED TO H FOR MAKING H P.D. */
+/* DIAG(N) --> DIAGONAL OF H */
+/* ADDMAX --> ADDMAX * I IS ADDED TO H */
+ /* Parameter adjustments */
+ --diag;
+ --e;
+ --pivot;
+ --g;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+
+ /* Function Body */
+ redo = FALSE_;
+
+/* SAVE DIAGONAL OF H */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ diag[i__] = h__[i__ + i__ * h_dim1];
+/* L10: */
+ }
+ tau1 = pow_dd(eps, &c_b250);
+ tau2 = tau1;
+ modchl_(nr, n, &h__[h_offset], &g[1], eps, &tau1, &tau2, &pivot[1], &e[1])
+ ;
+ *addmax = e[*n];
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ if (pivot[i__] != i__) {
+ redo = TRUE_;
+ }
+/* L22: */
+ }
+ if (*addmax > 0. || redo) {
+/* ******************************** */
+/* * */
+/* H IS NOT P.D. * */
+/* * */
+/* ******************************** */
+
+/* H=H+UI */
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ i__2 = i__ - 1;
+ for (j = 1; j <= i__2; ++j) {
+ h__[i__ + j * h_dim1] = h__[j + i__ * h_dim1];
+/* L32: */
+ }
+/* L30: */
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ pivot[i__] = i__;
+ h__[i__ + i__ * h_dim1] = diag[i__] + *addmax;
+/* L34: */
+ }
+/* ******************************** */
+/* * */
+/* COMPUTE L * */
+/* * */
+/* ******************************** */
+ i__1 = *n;
+ for (j = 1; j <= i__1; ++j) {
+
+/* COMPUTE L(J,J) */
+ temp = 0.;
+ if (j > 1) {
+ i__2 = j - 1;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp += h__[j + i__ * h_dim1] * h__[j + i__ * h_dim1];
+/* L41: */
+ }
+ }
+ h__[j + j * h_dim1] -= temp;
+ h__[j + j * h_dim1] = sqrt(h__[j + j * h_dim1]);
+
+/* COMPUTE L(I,J) */
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ temp = 0.;
+ if (j > 1) {
+ i__3 = j - 1;
+ for (k = 1; k <= i__3; ++k) {
+ temp += h__[i__ + k * h_dim1] * h__[j + k * h_dim1];
+/* L45: */
+ }
+ }
+ h__[i__ + j * h_dim1] = h__[j + i__ * h_dim1] - temp;
+ h__[i__ + j * h_dim1] /= h__[j + j * h_dim1];
+/* L43: */
+ }
+/* L40: */
+ }
+ }
+ return 0;
+} /* choldr_ */
+
+/* ---------------------- */
+/* | M O D C H L | */
+/* ---------------------- */
+/* ********************************************************************* */
+
+/* SUBROUTINE NAME: MODCHL */
+
+/* AUTHORS : ELIZABETH ESKOW AND ROBERT B. SCHNABEL */
+
+/* DATE : DECEMBER, 1988 */
+
+/* PURPOSE : PERFORM A MODIFIED CHOLESKY FACTORIZATION */
+/* OF THE FORM (PTRANSPOSE)AP + E = L(LTRANSPOSE), */
+/* WHERE L IS STORED IN THE LOWER TRIANGLE OF THE */
+/* ORIGINAL MATRIX A. */
+/* THE FACTORIZATION HAS 2 PHASES: */
+/* PHASE 1: PIVOT ON THE MAXIMUM DIAGONAL ELEMENT. */
+/* CHECK THAT THE NORMAL CHOLESKY UPDATE */
+/* WOULD RESULT IN A POSITIVE DIAGONAL */
+/* AT THE CURRENT ITERATION, AND */
+/* IF SO, DO THE NORMAL CHOLESKY UPDATE, */
+/* OTHERWISE SWITCH TO PHASE 2. */
+/* PHASE 2: PIVOT ON THE MINIMUM OF THE NEGATIVES */
+/* OF THE LOWER GERSCHGORIN BOUND */
+/* ESTIMATES. */
+/* COMPUTE THE AMOUNT TO ADD TO THE */
+/* PIVOT ELEMENT AND ADD THIS */
+/* TO THE PIVOT ELEMENT. */
+/* DO THE CHOLESKY UPDATE. */
+/* UPDATE THE ESTIMATES OF THE */
+/* GERSCHGORIN BOUNDS. */
+
+/* INPUT : NDIM - LARGEST DIMENSION OF MATRIX THAT */
+/* WILL BE USED */
+
+/* N - DIMENSION OF MATRIX A */
+
+/* A - N*N SYMMETRIC MATRIX (ONLY LOWER TRIANGULAR */
+/* PORTION OF A, INCLUDING THE MAIN DIAGONAL, IS USED) */
+
+/* G - N*1 WORK ARRAY */
+
+/* MCHEPS - MACHINE PRECISION */
+
+/* TAU1 - TOLERANCE USED FOR DETERMINING WHEN TO SWITCH TO */
+/* PHASE 2 */
+
+/* TAU2 - TOLERANCE USED FOR DETERMINING THE MAXIMUM */
+/* CONDITION NUMBER OF THE FINAL 2X2 SUBMATRIX. */
+
+
+/* OUTPUT : L - STORED IN THE MATRIX A (IN LOWER TRIANGULAR */
+/* PORTION OF A, INCLUDING THE MAIN DIAGONAL) */
+
+/* P - A RECORD OF HOW THE ROWS AND COLUMNS */
+/* OF THE MATRIX WERE PERMUTED WHILE */
+/* PERFORMING THE DECOMPOSITION */
+
+/* E - N*1 ARRAY, THE ITH ELEMENT IS THE */
+/* AMOUNT ADDED TO THE DIAGONAL OF A */
+/* AT THE ITH ITERATION */
+
+
+/* ************************************************************************ */
+/* Subroutine */ int modchl_(integer *ndim, integer *n, doublereal *a,
+ doublereal *g, doublereal *mcheps, doublereal *tau1, doublereal *tau2,
+ integer *p, doublereal *e)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2, i__3;
+ doublereal d__1;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ integer i__, j, k, jp1;
+ doublereal maxd, ming;
+ extern /* Subroutine */ int init_(integer *, integer *, doublereal *,
+ logical *, doublereal *, integer *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *);
+ doublereal temp, gamma, delta, jdmin;
+ integer imaxd, iming;
+ extern /* Subroutine */ int fin2x2_(integer *, integer *, doublereal *,
+ doublereal *, integer *, doublereal *, doublereal *, doublereal *)
+ ;
+ doublereal tdmin;
+ integer itemp;
+ doublereal normj, delta1;
+ logical phase1;
+ extern /* Subroutine */ int gersch_(integer *, integer *, doublereal *,
+ integer *, doublereal *);
+ doublereal taugam, tempjj;
+
+
+/* J - CURRENT ITERATION NUMBER */
+/* IMING - INDEX OF THE ROW WITH THE MIN. OF THE */
+/* NEG. LOWER GERSCH. BOUNDS */
+/* IMAXD - INDEX OF THE ROW WITH THE MAXIMUM DIAG. */
+/* ELEMENT */
+/* I,ITEMP,JPL,K - TEMPORARY INTEGER VARIABLES */
+/* DELTA - AMOUNT TO ADD TO AJJ AT THE JTH ITERATION */
+/* GAMMA - THE MAXIMUM DIAGONAL ELEMENT OF THE ORIGINAL */
+/* MATRIX A. */
+/* NORMJ - THE 1 NORM OF A(COLJ), ROWS J+1 --> N. */
+/* MING - THE MINIMUM OF THE NEG. LOWER GERSCH. BOUNDS */
+/* MAXD - THE MAXIMUM DIAGONAL ELEMENT */
+/* TAUGAM - TAU1 * GAMMA */
+/* PHASE1 - LOGICAL, TRUE IF IN PHASE1, OTHERWISE FALSE */
+/* DELTA1,TEMP,JDMIN,TDMIN,TEMPJJ - TEMPORARY DOUBLE PRECISION VARS. */
+
+ /* Parameter adjustments */
+ --e;
+ --p;
+ --g;
+ a_dim1 = *ndim;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ init_(n, ndim, &a[a_offset], &phase1, &delta, &p[1], &g[1], &e[1], &ming,
+ tau1, &gamma, &taugam);
+/* CHECK FOR N=1 */
+ if (*n == 1) {
+ delta = *tau2 * (d__1 = a[a_dim1 + 1], abs(d__1)) - a[a_dim1 + 1];
+ if (delta > 0.) {
+ e[1] = delta;
+ }
+ if (a[a_dim1 + 1] == 0.) {
+ e[1] = *tau2;
+ }
+ a[a_dim1 + 1] = sqrt(a[a_dim1 + 1] + e[1]);
+ }
+
+
+ i__1 = *n - 1;
+ for (j = 1; j <= i__1; ++j) {
+
+/* PHASE 1 */
+
+ if (phase1) {
+
+/* FIND INDEX OF MAXIMUM DIAGONAL ELEMENT A(I,I) WHERE I>=J */
+
+ maxd = a[j + j * a_dim1];
+ imaxd = j;
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ if (maxd < a[i__ + i__ * a_dim1]) {
+ maxd = a[i__ + i__ * a_dim1];
+ imaxd = i__;
+ }
+/* L20: */
+ }
+
+/* PIVOT TO THE TOP THE ROW AND COLUMN WITH THE MAX DIAG */
+
+ if (imaxd != j) {
+
+/* SWAP ROW J WITH ROW OF MAX DIAG */
+
+ i__2 = j - 1;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp = a[j + i__ * a_dim1];
+ a[j + i__ * a_dim1] = a[imaxd + i__ * a_dim1];
+ a[imaxd + i__ * a_dim1] = temp;
+/* L30: */
+ }
+
+/* SWAP COLJ AND ROW MAXDIAG BETWEEN J AND MAXDIAG */
+
+ i__2 = imaxd - 1;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ a[i__ + j * a_dim1] = a[imaxd + i__ * a_dim1];
+ a[imaxd + i__ * a_dim1] = temp;
+/* L35: */
+ }
+
+/* SWAP COLUMN J WITH COLUMN OF MAX DIAG */
+
+ i__2 = *n;
+ for (i__ = imaxd + 1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ a[i__ + j * a_dim1] = a[i__ + imaxd * a_dim1];
+ a[i__ + imaxd * a_dim1] = temp;
+/* L40: */
+ }
+
+/* SWAP DIAG ELEMENTS */
+
+ temp = a[j + j * a_dim1];
+ a[j + j * a_dim1] = a[imaxd + imaxd * a_dim1];
+ a[imaxd + imaxd * a_dim1] = temp;
+
+/* SWAP ELEMENTS OF THE PERMUTATION VECTOR */
+
+ itemp = p[j];
+ p[j] = p[imaxd];
+ p[imaxd] = itemp;
+ }
+/* CHECK TO SEE WHETHER THE NORMAL CHOLESKY UPDATE FOR THIS */
+/* ITERATION WOULD RESULT IN A POSITIVE DIAGONAL, */
+/* AND IF NOT THEN SWITCH TO PHASE 2. */
+ jp1 = j + 1;
+ tempjj = a[j + j * a_dim1];
+ if (tempjj > 0.) {
+ jdmin = a[jp1 + jp1 * a_dim1];
+ i__2 = *n;
+ for (i__ = jp1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1] * a[i__ + j * a_dim1] / tempjj;
+ tdmin = a[i__ + i__ * a_dim1] - temp;
+ jdmin = min(jdmin,tdmin);
+/* L60: */
+ }
+ if (jdmin < taugam) {
+ phase1 = FALSE_;
+ }
+ } else {
+ phase1 = FALSE_;
+ }
+ if (phase1) {
+
+/* DO THE NORMAL CHOLESKY UPDATE IF STILL IN PHASE 1 */
+
+ a[j + j * a_dim1] = sqrt(a[j + j * a_dim1]);
+ tempjj = a[j + j * a_dim1];
+ i__2 = *n;
+ for (i__ = jp1; i__ <= i__2; ++i__) {
+ a[i__ + j * a_dim1] /= tempjj;
+/* L70: */
+ }
+ i__2 = *n;
+ for (i__ = jp1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ i__3 = i__;
+ for (k = jp1; k <= i__3; ++k) {
+ a[i__ + k * a_dim1] -= temp * a[k + j * a_dim1];
+/* L75: */
+ }
+/* L80: */
+ }
+ if (j == *n - 1) {
+ a[*n + *n * a_dim1] = sqrt(a[*n + *n * a_dim1]);
+ }
+ } else {
+
+/* CALCULATE THE NEGATIVES OF THE LOWER GERSCHGORIN BOUNDS */
+
+ gersch_(ndim, n, &a[a_offset], &j, &g[1]);
+ }
+ }
+
+/* PHASE 2 */
+
+ if (! phase1) {
+ if (j != *n - 1) {
+
+/* FIND THE MINIMUM NEGATIVE GERSHGORIN BOUND */
+
+ iming = j;
+ ming = g[j];
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ if (ming > g[i__]) {
+ ming = g[i__];
+ iming = i__;
+ }
+/* L90: */
+ }
+
+/* PIVOT TO THE TOP THE ROW AND COLUMN WITH THE */
+/* MINIMUM NEGATIVE GERSCHGORIN BOUND */
+
+ if (iming != j) {
+
+/* SWAP ROW J WITH ROW OF MIN GERSCH BOUND */
+
+ i__2 = j - 1;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ temp = a[j + i__ * a_dim1];
+ a[j + i__ * a_dim1] = a[iming + i__ * a_dim1];
+ a[iming + i__ * a_dim1] = temp;
+/* L100: */
+ }
+
+/* SWAP COLJ WITH ROW IMING FROM J TO IMING */
+
+ i__2 = iming - 1;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ a[i__ + j * a_dim1] = a[iming + i__ * a_dim1];
+ a[iming + i__ * a_dim1] = temp;
+/* L105: */
+ }
+
+/* SWAP COLUMN J WITH COLUMN OF MIN GERSCH BOUND */
+
+ i__2 = *n;
+ for (i__ = iming + 1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ a[i__ + j * a_dim1] = a[i__ + iming * a_dim1];
+ a[i__ + iming * a_dim1] = temp;
+/* L110: */
+ }
+
+/* SWAP DIAGONAL ELEMENTS */
+
+ temp = a[j + j * a_dim1];
+ a[j + j * a_dim1] = a[iming + iming * a_dim1];
+ a[iming + iming * a_dim1] = temp;
+
+/* SWAP ELEMENTS OF THE PERMUTATION VECTOR */
+
+ itemp = p[j];
+ p[j] = p[iming];
+ p[iming] = itemp;
+
+/* SWAP ELEMENTS OF THE NEGATIVE GERSCHGORIN BOUNDS VECTOR */
+
+ temp = g[j];
+ g[j] = g[iming];
+ g[iming] = temp;
+ }
+
+/* CALCULATE DELTA AND ADD TO THE DIAGONAL. */
+/* DELTA=MAX{0,-A(J,J) + MAX{NORMJ,TAUGAM},DELTA_PREVIOUS} */
+/* WHERE NORMJ=SUM OF |A(I,J)|,FOR I=1,N, */
+/* DELTA_PREVIOUS IS THE DELTA COMPUTED AT THE PREVIOUS ITERATION, */
+/* AND TAUGAM IS TAU1*GAMMA. */
+
+ normj = 0.f;
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ normj += (d__1 = a[i__ + j * a_dim1], abs(d__1));
+/* L140: */
+ }
+ temp = max(normj,taugam);
+ delta1 = temp - a[j + j * a_dim1];
+ temp = 0.f;
+ delta1 = max(temp,delta1);
+ delta = max(delta1,delta);
+ e[j] = delta;
+ a[j + j * a_dim1] += e[j];
+
+/* UPDATE THE GERSCHGORIN BOUND ESTIMATES */
+/* (NOTE: G(I) IS THE NEGATIVE OF THE */
+/* GERSCHGORIN LOWER BOUND.) */
+
+ if (a[j + j * a_dim1] != normj) {
+ temp = normj / a[j + j * a_dim1] - 1.f;
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ g[i__] += (d__1 = a[i__ + j * a_dim1], abs(d__1)) *
+ temp;
+/* L150: */
+ }
+ }
+
+/* DO THE CHOLESKY UPDATE */
+
+ a[j + j * a_dim1] = sqrt(a[j + j * a_dim1]);
+ tempjj = a[j + j * a_dim1];
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ a[i__ + j * a_dim1] /= tempjj;
+/* L160: */
+ }
+ i__2 = *n;
+ for (i__ = j + 1; i__ <= i__2; ++i__) {
+ temp = a[i__ + j * a_dim1];
+ i__3 = i__;
+ for (k = j + 1; k <= i__3; ++k) {
+ a[i__ + k * a_dim1] -= temp * a[k + j * a_dim1];
+/* L170: */
+ }
+/* L180: */
+ }
+ } else {
+ fin2x2_(ndim, n, &a[a_offset], &e[1], &j, tau2, &delta, &
+ gamma);
+ }
+ }
+/* L200: */
+ }
+ return 0;
+} /* modchl_ */
+
+/* ************************************************************************ */
+/* SUBROUTINE NAME : INIT */
+
+/* PURPOSE : SET UP FOR START OF CHOLESKY FACTORIZATION */
+
+/* INPUT : N, NDIM, A, TAU1 */
+
+/* OUTPUT : PHASE1 - BOOLEAN VALUE SET TO TRUE IF IN PHASE ONE, */
+/* OTHERWISE FALSE. */
+/* DELTA - AMOUNT TO ADD TO AJJ AT ITERATION J */
+/* P,G,E - DESCRIBED ABOVE IN MODCHL */
+/* MING - THE MINIMUM NEGATIVE GERSCHGORIN BOUND */
+/* GAMMA - THE MAXIMUM DIAGONAL ELEMENT OF A */
+/* TAUGAM - TAU1 * GAMMA */
+
+/* ************************************************************************ */
+/* Subroutine */ int init_(integer *n, integer *ndim, doublereal *a, logical *
+ phase1, doublereal *delta, integer *p, doublereal *g, doublereal *e,
+ doublereal *ming, doublereal *tau1, doublereal *gamma, doublereal *
+ taugam)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1;
+ doublereal d__1, d__2, d__3;
+
+ /* Local variables */
+ integer i__;
+ extern /* Subroutine */ int gersch_(integer *, integer *, doublereal *,
+ integer *, doublereal *);
+
+ /* Parameter adjustments */
+ --e;
+ --g;
+ --p;
+ a_dim1 = *ndim;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ *phase1 = TRUE_;
+ *delta = 0.f;
+ *ming = 0.f;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ p[i__] = i__;
+ g[i__] = 0.f;
+ e[i__] = 0.f;
+/* L10: */
+ }
+
+/* FIND THE MAXIMUM MAGNITUDE OF THE DIAGONAL ELEMENTS. */
+/* IF ANY DIAGONAL ELEMENT IS NEGATIVE, THEN PHASE1 IS FALSE. */
+
+ *gamma = 0.f;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+/* Computing MAX */
+ d__2 = *gamma, d__3 = (d__1 = a[i__ + i__ * a_dim1], abs(d__1));
+ *gamma = max(d__2,d__3);
+ if (a[i__ + i__ * a_dim1] < 0.f) {
+ *phase1 = FALSE_;
+ }
+/* L20: */
+ }
+ *taugam = *tau1 * *gamma;
+
+/* IF NOT IN PHASE1, THEN CALCULATE THE INITIAL GERSCHGORIN BOUNDS */
+/* NEEDED FOR THE START OF PHASE2. */
+
+ if (! (*phase1)) {
+ gersch_(ndim, n, &a[a_offset], &c__1, &g[1]);
+ }
+ return 0;
+} /* init_ */
+
+/* ************************************************************************ */
+
+/* SUBROUTINE NAME : GERSCH */
+
+/* PURPOSE : CALCULATE THE NEGATIVE OF THE GERSCHGORIN BOUNDS */
+/* CALLED ONCE AT THE START OF PHASE II. */
+
+/* INPUT : NDIM, N, A, J */
+
+/* OUTPUT : G - AN N VECTOR CONTAINING THE NEGATIVES OF THE */
+/* GERSCHGORIN BOUNDS. */
+
+/* ************************************************************************ */
+/* Subroutine */ int gersch_(integer *ndim, integer *n, doublereal *a,
+ integer *j, doublereal *g)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset, i__1, i__2;
+ doublereal d__1;
+
+ /* Local variables */
+ integer i__, k;
+ doublereal offrow;
+
+ /* Parameter adjustments */
+ --g;
+ a_dim1 = *ndim;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ i__1 = *n;
+ for (i__ = *j; i__ <= i__1; ++i__) {
+ offrow = 0.f;
+ i__2 = i__ - 1;
+ for (k = *j; k <= i__2; ++k) {
+ offrow += (d__1 = a[i__ + k * a_dim1], abs(d__1));
+/* L10: */
+ }
+ i__2 = *n;
+ for (k = i__ + 1; k <= i__2; ++k) {
+ offrow += (d__1 = a[k + i__ * a_dim1], abs(d__1));
+/* L20: */
+ }
+ g[i__] = offrow - a[i__ + i__ * a_dim1];
+/* L30: */
+ }
+ return 0;
+} /* gersch_ */
+
+/* ************************************************************************ */
+
+/* SUBROUTINE NAME : FIN2X2 */
+
+/* PURPOSE : HANDLES FINAL 2X2 SUBMATRIX IN PHASE II. */
+/* FINDS EIGENVALUES OF FINAL 2 BY 2 SUBMATRIX, */
+/* CALCULATES THE AMOUNT TO ADD TO THE DIAGONAL, */
+/* ADDS TO THE FINAL 2 DIAGONAL ELEMENTS, */
+/* AND DOES THE FINAL UPDATE. */
+
+/* INPUT : NDIM, N, A, E, J, TAU2, */
+/* DELTA - AMOUNT ADDED TO THE DIAGONAL IN THE */
+/* PREVIOUS ITERATION */
+
+/* OUTPUT : A - MATRIX WITH COMPLETE L FACTOR IN THE LOWER TRIANGLE, */
+/* E - N*1 VECTOR CONTAINING THE AMOUNT ADDED TO THE DIAGONAL */
+/* AT EACH ITERATION, */
+/* DELTA - AMOUNT ADDED TO DIAGONAL ELEMENTS N-1 AND N. */
+
+/* ************************************************************************ */
+/* Subroutine */ int fin2x2_(integer *ndim, integer *n, doublereal *a,
+ doublereal *e, integer *j, doublereal *tau2, doublereal *delta,
+ doublereal *gamma)
+{
+ /* System generated locals */
+ integer a_dim1, a_offset;
+ doublereal d__1;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ doublereal t1, t2, t3, t1a, t2a, temp, lmbd1, lmbd2, delta1, lmbdhi,
+ lmbdlo;
+
+
+/* FIND EIGENVALUES OF FINAL 2 BY 2 SUBMATRIX */
+
+ /* Parameter adjustments */
+ --e;
+ a_dim1 = *ndim;
+ a_offset = 1 + a_dim1;
+ a -= a_offset;
+
+ /* Function Body */
+ t1 = a[*n - 1 + (*n - 1) * a_dim1] + a[*n + *n * a_dim1];
+ t2 = a[*n - 1 + (*n - 1) * a_dim1] - a[*n + *n * a_dim1];
+ t1a = abs(t2);
+ t2a = (d__1 = a[*n + (*n - 1) * a_dim1], abs(d__1)) * 2.;
+ if (t1a >= t2a) {
+ if (t1a > 0.) {
+ t2a /= t1a;
+ }
+/* Computing 2nd power */
+ d__1 = t2a;
+ t3 = t1a * sqrt(d__1 * d__1 + 1.);
+ } else {
+ t1a /= t2a;
+/* Computing 2nd power */
+ d__1 = t1a;
+ t3 = t2a * sqrt(d__1 * d__1 + 1.);
+ }
+ lmbd1 = (t1 - t3) / 2.f;
+ lmbd2 = (t1 + t3) / 2.f;
+ lmbdhi = max(lmbd1,lmbd2);
+ lmbdlo = min(lmbd1,lmbd2);
+
+/* FIND DELTA SUCH THAT: */
+/* 1. THE L2 CONDITION NUMBER OF THE FINAL */
+/* 2X2 SUBMATRIX + DELTA*I <= TAU2 */
+/* 2. DELTA >= PREVIOUS DELTA, */
+/* 3. LMBDLO + DELTA >= TAU2 * GAMMA, */
+/* WHERE LMBDLO IS THE SMALLEST EIGENVALUE OF THE FINAL */
+/* 2X2 SUBMATRIX */
+
+ delta1 = (lmbdhi - lmbdlo) / (1.f - *tau2);
+ delta1 = max(delta1,*gamma);
+ delta1 = *tau2 * delta1 - lmbdlo;
+ temp = 0.f;
+ *delta = max(*delta,temp);
+ *delta = max(*delta,delta1);
+ if (*delta > 0.f) {
+ a[*n - 1 + (*n - 1) * a_dim1] += *delta;
+ a[*n + *n * a_dim1] += *delta;
+ e[*n - 1] = *delta;
+ e[*n] = *delta;
+ }
+
+/* FINAL UPDATE */
+
+ a[*n - 1 + (*n - 1) * a_dim1] = sqrt(a[*n - 1 + (*n - 1) * a_dim1]);
+ a[*n + (*n - 1) * a_dim1] /= a[*n - 1 + (*n - 1) * a_dim1];
+/* Computing 2nd power */
+ d__1 = a[*n + (*n - 1) * a_dim1];
+ a[*n + *n * a_dim1] -= d__1 * d__1;
+ a[*n + *n * a_dim1] = sqrt(a[*n + *n * a_dim1]);
+ return 0;
+} /* fin2x2_ */
+
+/* ---------------------- */
+/* | S L V M D L | */
+/* ---------------------- */
+/* Subroutine */ int slvmdl_(integer *nr, integer *n, doublereal *h__,
+ doublereal *u, doublereal *t, doublereal *e, doublereal *diag,
+ doublereal *s, doublereal *g, integer *pivot, doublereal *w1,
+ doublereal *w2, doublereal *w3, doublereal *alpha, doublereal *beta,
+ logical *nomin, doublereal *eps)
+{
+ /* System generated locals */
+ integer h_dim1, h_offset, i__1, i__2;
+
+ /* Builtin functions */
+ double sqrt(doublereal);
+
+ /* Local variables */
+ integer i__, j;
+ doublereal r__, r1, r2, ca, cb, cc, cd, w11, sg, w22, w12, w33, w13, w23,
+ ss, uu, shs;
+ extern /* Subroutine */ int zhz_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, doublereal *);
+ doublereal temp;
+ extern /* Subroutine */ int sigma_(doublereal *, doublereal *, doublereal
+ *, doublereal *, doublereal *), dstar_(integer *, integer *,
+ doublereal *, doublereal *, doublereal *, doublereal *,
+ doublereal *, doublereal *, doublereal *, doublereal *);
+ doublereal addmax;
+ extern /* Subroutine */ int choldr_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *, integer *, doublereal *, doublereal *,
+ doublereal *), bakslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *);
+ doublereal sgstar;
+ extern /* Subroutine */ int forslv_(integer *, integer *, doublereal *,
+ doublereal *, doublereal *), solvew_(integer *, integer *,
+ doublereal *, doublereal *, doublereal *, doublereal *);
+
+
+/* PURPOSE: */
+/* COMPUTE TENSOR AND NEWTON STEPS */
+
+/* ---------------------------------------------------------------------------- */
+
+/* PARAMETERS: */
+
+/* NR --> ROW DIMENSION OF MATRIX */
+/* N --> DIMENSION OF PROBLEM */
+/* H(N,N) --> HESSIAN */
+/* U(N) --> VECTOR TO FORM Q IN QR */
+/* T(N) --> WORKSPACE */
+/* E(N) --> DIAGONAL ADDED TO HESSIAN IN CHOLESKY DECOMPOSITION */
+/* DIAG(N) --> DIAGONAL OF HESSIAN */
+/* S(N) --> STEP TO PREVIOUS POINT (FOR TENSOR MODEL) */
+/* G(N) --> CURRENT GRADIENT */
+/* PIVOT(N) --> PIVOT VECTOR FOR CHOLESKY DECOMPOSITION */
+/* W1(N) <--> ON INPUT: A=2*(GP-G-HS-S*BETA/(6*STS)) */
+/* ON OUTPUT: TENSOR STEP */
+/* W2(N) --> SH */
+/* W3(N) <-- NEWTON STEP */
+/* ALPHA --> SCALAR FOR 3RD ORDER TERM OF TENSOR MODEL */
+/* BETA --> SCALAR FOR 4TH ORDER TERM OF TENSOR MODEL */
+/* NOMIN <-- =.TRUE. IF TENSOR MODEL HAS NO MINIMIZER */
+/* EPS --> MACHINE EPSILON */
+
+
+/* S O L V E M O D E L */
+
+ /* Parameter adjustments */
+ --w3;
+ --w2;
+ --w1;
+ --pivot;
+ --g;
+ --s;
+ --diag;
+ --e;
+ --t;
+ --u;
+ h_dim1 = *nr;
+ h_offset = 1 + h_dim1;
+ h__ -= h_offset;
+
+ /* Function Body */
+ *nomin = FALSE_;
+
+/* COMPUTE QTHQ(N,N), ZTHZ(N-1,N-1) = FIRST N-1 ROWS AND N-1 */
+/* COLUMNS OF QTHQ */
+ if (*n > 1) {
+ zhz_(nr, n, &s[1], &h__[h_offset], &u[1], &t[1]);
+
+/* IN CHOLESKY DECOMPOSITION WILL STORE H(1,1) ... H(N-1,N-1) */
+/* IN DIAG(1) ... DIAG(N-1), STORE H(N,N) IN DIAG(N) FIRST */
+ diag[*n] = h__[*n + *n * h_dim1];
+
+/* COLESKY DECOMPOSITION FOR FIRST N-1 ROWS AND N-1 COLUMNS OF ZTHZ */
+/* ZTHZ(N-1,N-1)=LLT */
+ i__1 = *n - 1;
+ choldr_(nr, &i__1, &h__[h_offset], &t[1], eps, &pivot[1], &e[1], &
+ diag[1], &addmax);
+ }
+
+/* ON INPUT: SH IS STORED IN W2 */
+ shs = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ shs += w2[i__] * s[i__];
+ w3[i__] = g[i__];
+/* L100: */
+ }
+
+/* COMPUTE W1,W2,W3 */
+/* W1=L**-1*ZT*A */
+/* W2=L**-1*ZT*SH */
+/* W3=L**-1*ZT*G */
+
+ if (*n > 1) {
+ solvew_(nr, n, &h__[h_offset], &u[1], &w1[1], &t[1]);
+ solvew_(nr, n, &h__[h_offset], &u[1], &w2[1], &t[1]);
+ solvew_(nr, n, &h__[h_offset], &u[1], &w3[1], &t[1]);
+ }
+
+/* COMPUTE COEFFICIENTS CA,CB,CC AND CD FOR REDUCED ONE VARIABLE */
+/* 3RD ORDER EQUATION */
+ w11 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w11 += w1[i__] * w1[i__];
+/* L110: */
+ }
+ ca = *beta / 6. - w11 / 2.;
+ w12 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w12 += w1[i__] * w2[i__];
+/* L120: */
+ }
+ cb = *alpha / 2. - w12 * 3. / 2.;
+ w13 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w13 += w1[i__] * w3[i__];
+/* L130: */
+ }
+ w22 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w22 += w2[i__] * w2[i__];
+/* L133: */
+ }
+ cc = shs - w22 - w13;
+ sg = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ sg += s[i__] * g[i__];
+/* L140: */
+ }
+ w23 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w23 += w2[i__] * w3[i__];
+/* L145: */
+ }
+ cd = sg - w23;
+ w33 = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w33 += w3[i__] * w3[i__];
+/* L147: */
+ }
+
+/* COMPUTE DESIRABLE ROOT, SGSTAR, OF 3RD ORDER EQUATION */
+ if (ca != 0.) {
+ sigma_(&sgstar, &ca, &cb, &cc, &cd);
+ if (ca == 0.) {
+ *nomin = TRUE_;
+ goto L200;
+ }
+ } else {
+/* 2ND ORDER ( CA=0 ) */
+ if (cb != 0.) {
+ r__ = cc * cc - cb * 4. * cd;
+ if (r__ < 0.) {
+ *nomin = TRUE_;
+ goto L200;
+ } else {
+ r1 = (-cc + sqrt(r__)) / (cb * 2.);
+ r2 = (-cc - sqrt(r__)) / (cb * 2.);
+ if (r2 < r1) {
+ temp = r1;
+ r1 = r2;
+ r2 = temp;
+ }
+ if (cb > 0.) {
+ sgstar = r2;
+ } else {
+ sgstar = r1;
+ }
+ if (r1 > 0. && sgstar == r2 || r2 < 0. && sgstar == r1) {
+ *nomin = TRUE_;
+ goto L200;
+ }
+ }
+ } else {
+/* 1ST ORDER (CA=0,CB=0) */
+ if (cc > 0.) {
+ sgstar = -cd / cc;
+ } else {
+ *nomin = TRUE_;
+ goto L200;
+ }
+ }
+ }
+
+/* FIND TENSOR STEP, W1 (FUNCTION OF SGSTAR) */
+ dstar_(nr, n, &u[1], &s[1], &w1[1], &w2[1], &w3[1], &sgstar, &h__[
+ h_offset], &w1[1]);
+
+/* COMPUTE DN */
+L200:
+ uu = 0.;
+ ss = 0.;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ uu += u[i__] * u[i__];
+ ss += s[i__] * s[i__];
+/* L202: */
+ }
+ uu /= 2.;
+ ss = sqrt(ss);
+ if (*n == 1) {
+ choldr_(nr, n, &h__[h_offset], &t[1], eps, &pivot[1], &e[1], &diag[1],
+ &addmax);
+ } else {
+
+/* COMPUTE LAST ROW OF L(N,N) */
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ temp = 0.;
+ if (i__ > 1) {
+ i__2 = i__ - 1;
+ for (j = 1; j <= i__2; ++j) {
+ temp += h__[*n + j * h_dim1] * h__[i__ + j * h_dim1];
+/* L210: */
+ }
+ }
+ h__[*n + i__ * h_dim1] = (h__[i__ + *n * h_dim1] - temp) / h__[
+ i__ + i__ * h_dim1];
+/* L220: */
+ }
+ temp = 0.;
+ i__1 = *n - 1;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ temp += h__[*n + i__ * h_dim1] * h__[*n + i__ * h_dim1];
+/* L224: */
+ }
+ h__[*n + *n * h_dim1] = diag[*n] - temp + addmax;
+ if (h__[*n + *n * h_dim1] > 0.) {
+ h__[*n + *n * h_dim1] = sqrt(h__[*n + *n * h_dim1]);
+ } else {
+/* AFTER ADDING THE LAST COLUMN AND ROW */
+/* QTHQ IS NOT P.D., NEED TO REDO CHOLESKY DECOMPOSITION */
+ i__1 = *n;
+ for (i__ = 2; i__ <= i__1; ++i__) {
+ i__2 = i__ - 1;
+ for (j = 1; j <= i__2; ++j) {
+ h__[i__ + j * h_dim1] = h__[j + i__ * h_dim1];
+/* L230: */
+ }
+ h__[i__ + i__ * h_dim1] = diag[i__];
+/* L232: */
+ }
+ h__[h_dim1 + 1] = diag[1];
+ choldr_(nr, n, &h__[h_offset], &t[1], eps, &pivot[1], &e[1], &
+ diag[1], &addmax);
+ }
+ }
+
+/* SOLVE QTHQ*QT*W3=-QT*G, WHERE W3 IS NEWTON STEP */
+/* W2=-QT*G */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w2[i__] = 0.;
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ w2[i__] += u[j] * u[i__] * g[j] / uu;
+/* L300: */
+ }
+ w2[i__] -= g[i__];
+/* L302: */
+ }
+ forslv_(nr, n, &h__[h_offset], &w3[1], &w2[1]);
+ bakslv_(nr, n, &h__[h_offset], &w2[1], &w3[1]);
+/* W2=QT*W3 => W3=Q*W2 --- NEWTON STEP */
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ w3[i__] = 0.;
+ i__2 = *n;
+ for (j = 1; j <= i__2; ++j) {
+ w3[i__] += u[i__] * u[j] * w2[j] / uu;
+/* L310: */
+ }
+ w3[i__] = w2[i__] - w3[i__];
+/* L312: */
+ }
+ return 0;
+} /* slvmdl_ */
+
+/* ---------------------- */
+/* | O P T S T P | */
+/* ---------------------- */
+/* Subroutine */ int optstp_(integer *n, doublereal *xpls, doublereal *fpls,
+ doublereal *gpls, doublereal *x, integer *itncnt, integer *icscmx,
+ integer *itrmcd, doublereal *gradtl, doublereal *steptl, doublereal *
+ fscale, integer *itnlim, integer *iretcd, logical *mxtake, integer *
+ ipr, integer *msg, doublereal *rgx, doublereal *rsx)
+{
+ /* Format strings */
+ static char fmt_900[] = "(\002 OPTSTP STEP OF MAXIMUM LENGTH (STEPMX)"
+ " TAKEN\002)";
+ static char fmt_901[] = "(\002 OPTSTP RELATIVE GRADIENT CLOSE TO ZE"
+ "RO.\002/\002 OPTSTP CURRENT ITERATE IS PROBABLY SOLUTION.\002)"
+ ;
+ static char fmt_902[] = "(\002 OPTSTP SUCCESSIVE ITERATES WITHIN TOLE"
+ "RANCE.\002/\002 OPTSTP CURRENT ITERATE IS PROBABLY SOLUTION"
+ ".\002)";
+ static char fmt_903[] = "(\002 OPTSTP LAST GLOBAL STEP FAILED TO LOCA"
+ "TE A POINT\002,\002 LOWER THAN X.\002/\002 OPTSTP EITHER X IS"
+ " AN APPROXIMATE LOCAL MINIMUM\002,\002 OF THE FUNCTION,\002/\002"
+ " OPTSTP THE FUNCTION IS TOO NON-LINEAR FOR THIS\002,\002 ALGO"
+ "RITHM,\002/\002 OPTSTP OR STEPTL IS TOO LARGE.\002)";
+ static char fmt_904[] = "(\002 OPTSTP ITERATION LIMIT EXCEEDED.\002"
+ "/\002 OPTSTP ALGORITHM FAILED.\002)";
+ static char fmt_905[] = "(\002 OPTSTP MAXIMUM STEP SIZE EXCEEDED 5"
+ "\002,\002 CONSECUTIVE TIMES.\002/\002 OPTSTP EITHER THE FUNCT"
+ "ION IS UNBOUNDED BELOW,\002/\002 OPTSTP BECOMES ASYMPTOTIC TO"
+ " A FINITE VALUE\002,\002 FROM ABOVE IN SOME DIRECTION,\002/\002 "
+ "OPTSTP OR STEPMX IS TOO SMALL\002)";
+
+ /* System generated locals */
+ integer i__1;
+ doublereal d__1, d__2, d__3;
+
+ /* Builtin functions */
+ integer s_wsfe(cilist *), e_wsfe(void);
+
+ /* Local variables */
+ doublereal d__;
+ integer i__, imsg;
+ doublereal relgrd;
+ integer jtrmcd;
+ doublereal relstp;
+
+ /* Fortran I/O blocks */
+ static cilist io___280 = { 0, 0, 0, fmt_900, 0 };
+ static cilist io___281 = { 0, 0, 0, fmt_901, 0 };
+ static cilist io___282 = { 0, 0, 0, fmt_902, 0 };
+ static cilist io___283 = { 0, 0, 0, fmt_903, 0 };
+ static cilist io___284 = { 0, 0, 0, fmt_904, 0 };
+ static cilist io___285 = { 0, 0, 0, fmt_905, 0 };
+
+
+
+/* UNCONSTRAINED MINIMIZATION STOPPING CRITERIA */
+/* -------------------------------------------- */
+/* FIND WHETHER THE ALGORITHM SHOULD TERMINATE, DUE TO ANY */
+/* OF THE FOLLOWING: */
+/* 1) PROBLEM SOLVED WITHIN USER TOLERANCE */
+/* 2) CONVERGENCE WITHIN USER TOLERANCE */
+/* 3) ITERATION LIMIT REACHED */
+/* 4) DIVERGENCE OR TOO RESTRICTIVE MAXIMUM STEP (STEPMX) SUSPECTED */
+
+
+/* PARAMETERS */
+/* ---------- */
+/* N --> DIMENSION OF PROBLEM */
+/* XPLS(N) --> NEW ITERATE X[K] */
+/* FPLS --> FUNCTION VALUE AT NEW ITERATE F(XPLS) */
+/* GPLS(N) --> GRADIENT AT NEW ITERATE, G(XPLS), OR APPROXIMATE */
+/* X(N) --> OLD ITERATE X[K-1] */
+/* ITNCNT --> CURRENT ITERATION K */
+/* ICSCMX <--> NUMBER CONSECUTIVE STEPS .GE. STEPMX */
+/* [RETAIN VALUE BETWEEN SUCCESSIVE CALLS] */
+/* ITRMCD <-- TERMINATION CODE */
+/* GRADTL --> TOLERANCE AT WHICH RELATIVE GRADIENT CONSIDERED CLOSE */
+/* ENOUGH TO ZERO TO TERMINATE ALGORITHM */
+/* STEPTL --> RELATIVE STEP SIZE AT WHICH SUCCESSIVE ITERATES */
+/* CONSIDERED CLOSE ENOUGH TO TERMINATE ALGORITHM */
+/* FSCALE --> ESTIMATE OF SCALE OF OBJECTIVE FUNCTION */
+/* ITNLIM --> MAXIMUM NUMBER OF ALLOWABLE ITERATIONS */
+/* IRETCD --> RETURN CODE */
+/* MXTAKE --> BOOLEAN FLAG INDICATING STEP OF MAXIMUM LENGTH USED */
+/* IPR --> DEVICE TO WHICH TO SEND OUTPUT */
+/* MSG <--> CONTROL OUTPUT ON INPUT AND CONTAIN STOPPING */
+/* CONDITION ON OUTPUT */
+
+
+
+ /* Parameter adjustments */
+ --x;
+ --gpls;
+ --xpls;
+
+ /* Function Body */
+ *itrmcd = 0;
+ imsg = *msg;
+ *rgx = 0.;
+ *rsx = 0.;
+
+/* LAST GLOBAL STEP FAILED TO LOCATE A POINT LOWER THAN X */
+ if (*iretcd != 1) {
+ goto L50;
+ }
+/* IF(IRETCD.EQ.1) */
+/* THEN */
+ jtrmcd = 3;
+ goto L600;
+/* ENDIF */
+L50:
+
+/* FIND DIRECTION IN WHICH RELATIVE GRADIENT MAXIMUM. */
+/* CHECK WHETHER WITHIN TOLERANCE */
+
+/* Computing MAX */
+ d__1 = abs(*fpls);
+ d__ = max(d__1,*fscale);
+/* D=1D0 */
+ *rgx = 0.f;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+/* Computing MAX */
+ d__3 = (d__2 = xpls[i__], abs(d__2));
+ relgrd = (d__1 = gpls[i__], abs(d__1)) * max(d__3,1.) / d__;
+ *rgx = max(*rgx,relgrd);
+/* L100: */
+ }
+ jtrmcd = 1;
+ if (*rgx <= *gradtl) {
+ goto L600;
+ }
+
+ if (*itncnt == 0) {
+ return 0;
+ }
+
+/* FIND DIRECTION IN WHICH RELATIVE STEPSIZE MAXIMUM */
+/* CHECK WHETHER WITHIN TOLERANCE. */
+
+ *rsx = 0.f;
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+/* Computing MAX */
+ d__3 = (d__2 = xpls[i__], abs(d__2));
+ relstp = (d__1 = xpls[i__] - x[i__], abs(d__1)) / max(d__3,1.);
+ *rsx = max(*rsx,relstp);
+/* L120: */
+ }
+ jtrmcd = 2;
+ if (*rsx <= *steptl) {
+ goto L600;
+ }
+
+/* CHECK ITERATION LIMIT */
+
+ jtrmcd = 4;
+ if (*itncnt >= *itnlim) {
+ goto L600;
+ }
+
+/* CHECK NUMBER OF CONSECUTIVE STEPS \ STEPMX */
+
+ if (*mxtake) {
+ goto L140;
+ }
+/* IF(.NOT.MXTAKE) */
+/* THEN */
+ *icscmx = 0;
+ return 0;
+/* ELSE */
+L140:
+/* IF (MOD(MSG/8,2) .EQ. 0) WRITE(IPR,900) */
+ if (imsg >= 1) {
+ io___280.ciunit = *ipr;
+ s_wsfe(&io___280);
+ e_wsfe();
+ }
+ ++(*icscmx);
+ if (*icscmx < 5) {
+ return 0;
+ }
+ jtrmcd = 5;
+/* ENDIF */
+
+
+/* PRINT TERMINATION CODE */
+
+L600:
+ *itrmcd = jtrmcd;
+/* IF (MOD(MSG/8,2) .EQ. 0) GO TO(601,602,603,604,605), ITRMCD */
+ if (imsg >= 1) {
+ switch (*itrmcd) {
+ case 1: goto L601;
+ case 2: goto L602;
+ case 3: goto L603;
+ case 4: goto L604;
+ case 5: goto L605;
+ }
+ }
+ goto L700;
+L601:
+ io___281.ciunit = *ipr;
+ s_wsfe(&io___281);
+ e_wsfe();
+ goto L700;
+L602:
+ io___282.ciunit = *ipr;
+ s_wsfe(&io___282);
+ e_wsfe();
+ goto L700;
+L603:
+ io___283.ciunit = *ipr;
+ s_wsfe(&io___283);
+ e_wsfe();
+ goto L700;
+L604:
+ io___284.ciunit = *ipr;
+ s_wsfe(&io___284);
+ e_wsfe();
+ goto L700;
+L605:
+ io___285.ciunit = *ipr;
+ s_wsfe(&io___285);
+ e_wsfe();
+
+L700:
+ *msg = -(*itrmcd);
+ return 0;
+
+} /* optstp_ */
+
+
+/* Subroutine */ int dcopy_(integer *n, doublereal *dx, integer *incx,
+ doublereal *dy, integer *incy)
+{
+ /* System generated locals */
+ integer i__1;
+
+ /* Local variables */
+ integer i__, m, ix, iy, mp1;
+
+
+/* COPIES A VECTOR, X, TO A VECTOR, Y. */
+/* USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE. */
+/* JACK DONGARRA, LINPACK, 3/11/78. */
+
+
+ /* Parameter adjustments */
+ --dy;
+ --dx;
+
+ /* Function Body */
+ if (*n <= 0) {
+ return 0;
+ }
+ if (*incx == 1 && *incy == 1) {
+ goto L20;
+ }
+
+/* CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS */
+/* NOT EQUAL TO 1 */
+
+ ix = 1;
+ iy = 1;
+ if (*incx < 0) {
+ ix = (-(*n) + 1) * *incx + 1;
+ }
+ if (*incy < 0) {
+ iy = (-(*n) + 1) * *incy + 1;
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dy[iy] = dx[ix];
+ ix += *incx;
+ iy += *incy;
+/* L10: */
+ }
+ return 0;
+
+/* CODE FOR BOTH INCREMENTS EQUAL TO 1 */
+
+
+/* CLEAN-UP LOOP */
+
+L20:
+ m = *n % 7;
+ if (m == 0) {
+ goto L40;
+ }
+ i__1 = m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dy[i__] = dx[i__];
+/* L30: */
+ }
+ if (*n < 7) {
+ return 0;
+ }
+L40:
+ mp1 = m + 1;
+ i__1 = *n;
+ for (i__ = mp1; i__ <= i__1; i__ += 7) {
+ dy[i__] = dx[i__];
+ dy[i__ + 1] = dx[i__ + 1];
+ dy[i__ + 2] = dx[i__ + 2];
+ dy[i__ + 3] = dx[i__ + 3];
+ dy[i__ + 4] = dx[i__ + 4];
+ dy[i__ + 5] = dx[i__ + 5];
+ dy[i__ + 6] = dx[i__ + 6];
+/* L50: */
+ }
+ return 0;
+} /* dcopy_ */
+
+
+doublereal ddot_(integer *n, doublereal *dx, integer *incx, doublereal *dy,
+ integer *incy)
+{
+ /* System generated locals */
+ integer i__1;
+ doublereal ret_val;
+
+ /* Local variables */
+ integer i__, m, ix, iy, mp1;
+ doublereal dtemp;
+
+
+/* FORMS THE DOT PRODUCT OF TWO VECTORS. */
+/* USES UNROLLED LOOPS FOR INCREMENTS EQUAL TO ONE. */
+/* JACK DONGARRA, LINPACK, 3/11/78. */
+
+
+ /* Parameter adjustments */
+ --dy;
+ --dx;
+
+ /* Function Body */
+ ret_val = 0.;
+ dtemp = 0.;
+ if (*n <= 0) {
+ return ret_val;
+ }
+ if (*incx == 1 && *incy == 1) {
+ goto L20;
+ }
+
+/* CODE FOR UNEQUAL INCREMENTS OR EQUAL INCREMENTS */
+/* NOT EQUAL TO 1 */
+
+ ix = 1;
+ iy = 1;
+ if (*incx < 0) {
+ ix = (-(*n) + 1) * *incx + 1;
+ }
+ if (*incy < 0) {
+ iy = (-(*n) + 1) * *incy + 1;
+ }
+ i__1 = *n;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dtemp += dx[ix] * dy[iy];
+ ix += *incx;
+ iy += *incy;
+/* L10: */
+ }
+ ret_val = dtemp;
+ return ret_val;
+
+/* CODE FOR BOTH INCREMENTS EQUAL TO 1 */
+
+
+/* CLEAN-UP LOOP */
+
+L20:
+ m = *n % 5;
+ if (m == 0) {
+ goto L40;
+ }
+ i__1 = m;
+ for (i__ = 1; i__ <= i__1; ++i__) {
+ dtemp += dx[i__] * dy[i__];
+/* L30: */
+ }
+ if (*n < 5) {
+ goto L60;
+ }
+L40:
+ mp1 = m + 1;
+ i__1 = *n;
+ for (i__ = mp1; i__ <= i__1; i__ += 5) {
+ dtemp = dtemp + dx[i__] * dy[i__] + dx[i__ + 1] * dy[i__ + 1] + dx[
+ i__ + 2] * dy[i__ + 2] + dx[i__ + 3] * dy[i__ + 3] + dx[i__ +
+ 4] * dy[i__ + 4];
+/* L50: */
+ }
+L60:
+ ret_val = dtemp;
+ return ret_val;
+} /* ddot_ */
+
+
+/* Subroutine */ int dscal_(integer *n, doublereal *da, doublereal *dx,
+ integer *incx)
+{
+ /* System generated locals */
+ integer i__1, i__2;
+
+ /* Local variables */
+ integer i__, m, mp1, nincx;
+
+
+/* SCALES A VECTOR BY A CONSTANT. */
+/* USES UNROLLED LOOPS FOR INCREMENT EQUAL TO ONE. */
+/* JACK DONGARRA, LINPACK, 3/11/78. */
+
+
+ /* Parameter adjustments */
+ --dx;
+
+ /* Function Body */
+ if (*n <= 0) {
+ return 0;
+ }
+ if (*incx == 1) {
+ goto L20;
+ }
+
+/* CODE FOR INCREMENT NOT EQUAL TO 1 */
+
+ nincx = *n * *incx;
+ i__1 = nincx;
+ i__2 = *incx;
+ for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+ dx[i__] = *da * dx[i__];
+/* L10: */
+ }
+ return 0;
+
+/* CODE FOR INCREMENT EQUAL TO 1 */
+
+
+/* CLEAN-UP LOOP */
+
+L20:
+ m = *n % 5;
+ if (m == 0) {
+ goto L40;
+ }
+ i__2 = m;
+ for (i__ = 1; i__ <= i__2; ++i__) {
+ dx[i__] = *da * dx[i__];
+/* L30: */
+ }
+ if (*n < 5) {
+ return 0;
+ }
+L40:
+ mp1 = m + 1;
+ i__2 = *n;
+ for (i__ = mp1; i__ <= i__2; i__ += 5) {
+ dx[i__] = *da * dx[i__];
+ dx[i__ + 1] = *da * dx[i__ + 1];
+ dx[i__ + 2] = *da * dx[i__ + 2];
+ dx[i__ + 3] = *da * dx[i__ + 3];
+ dx[i__ + 4] = *da * dx[i__ + 4];
+/* L50: */
+ }
+ return 0;
+} /* dscal_ */
+
+/* Main program alias */ int driver_ () { MAIN__ (); return 0; }