      SUBROUTINE   SNLAGB(N, P, X, B, SCALCR, SCALCJ, IV, LIV, LV, V)
c Copyright (c) 1996 California Institute of Technology, Pasadena, CA.
c ALL RIGHTS RESERVED.
c Based on Government Sponsored Research NAS7-03001.
c>> 1996-04-27 SNLAGB Krogh  Changes to get desired C prototypes.
c>> 1994-10-20 SNLAGB Krogh  Changes to use M77CON
c>> 1990-07-02 SNLAGB CLL @ JPL
c>> 1990-06-12 CLL @ JPL
c>> 1990-02-16 CLL @ JPL
*** from netlib, Wed Feb  7 13:51:26 EST 1990 ***
C
C  ***  VERSION OF NL2SOL THAT HANDLES SIMPLE BOUNDS ON X  ***
C
C  ***  PARAMETERS  ***
C
      EXTERNAL SCALCR, SCALCJ
      INTEGER N, P, LIV, LV
      INTEGER IV(LIV)
      REAL             X(P), B(2,P), V(LV)
C
C  ***  DISCUSSION  ***
C
C        NOTE... NL2SOL (MENTIONED BELOW) IS A CODE FOR SOLVING
C     NONLINEAR LEAST-SQUARES PROBLEMS.  IT IS DESCRIBED IN
C     ACM TRANS. MATH. SOFTWARE, VOL. 9, PP. 369-383 (AN ADAPTIVE
C     NONLINEAR LEAST-SQUARES ALGORITHM, BY <NAME>, <NAME>,
C     AND R.E. WELSCH).
C
C        LIV GIVES THE LENGTH OF IV.  IT MUST BE AT LEAST 82 + 4*P.
C     IF NOT, THEN SNLAGB RETURNS WITH IV(1) = 15.  When SNLAGB returns,
c     the minimum acceptable value of LIV is stored in
c     IV(LASTIV) = IV(44), (provided that LIV .ge. 44).
C
C        LV GIVES THE LENGTH OF V.  THE MINIMUM VALUE FOR LV IS
C     LV0 = 105 + P*(N + 2*P + 21) + 2*N.  IF LV IS SMALLER THAN THIS,
C     THEN SNLAGB RETURNS WITH IV(1) = 16.  WHEN SNLAGB RETURNS, THE
C     MINIMUM ACCEPTABLE VALUE OF LV IS STORED IN IV(LASTV) = IV(45)
C     (PROVIDED LIV .GE. 45).
C
C        RETURN CODES AND CONVERGENCE TOLERANCES ARE THE SAME AS FOR
C     NL2SOL, WITH SOME SMALL EXTENSIONS... IV(1) = 15 MEANS LIV WAS
C     TOO SMALL.   IV(1) = 16 MEANS LV WAS TOO SMALL.
C
C        THERE ARE TWO NEW V INPUT COMPONENTS...  V(LMAXS) = V(36) AND
C     V(SCTOL) = V(37) SERVE WHERE V(LMAX0) AND V(RFCTOL) FORMERLY DID
C     IN THE SINGULAR CONVERGENCE TEST -- SEE THE NL2SOL DOCUMENTATION.
C
C  ***  BOUNDS  ***
C
C     THE BOUNDS  B(1,I) .LE. X(I) .LE. B(2,I), I = 1(1)P, ARE ENFORCED.
C
C  ***  DEFAULT VALUES  ***
C
C        DEFAULT VALUES ARE PROVIDED BY SUBROUTINE SIVSET, RATHER THAN
C     DFAULT.  THE CALLING SEQUENCE IS...
C             CALL SIVSET(1, IV, LIV, LV, V)
C     THE FIRST PARAMETER IS AN INTEGER 1.  IF LIV AND LV ARE LARGE
C     ENOUGH FOR SIVSET, THEN SIVSET SETS IV(1) TO 12.  OTHERWISE IT
C     SETS IV(1) TO 15 OR 16.  CALLING SNLAGB WITH IV(1) = 0 CAUSES ALL
C     DEFAULT VALUES TO BE USED FOR THE INPUT COMPONENTS OF IV AND V.
C        IF YOU FIRST CALL SIVSET, THEN SET IV(1) TO 13 AND CALL SNLAGB,
C     THEN STORAGE ALLOCATION ONLY WILL BE PERFORMED.  IN PARTICULAR,
C     IV(D) = IV(27), IV(J) = IV(70), AND IV(R) = IV(61) WILL BE SET
C     TO THE FIRST SUBSCRIPT IN V OF THE SCALE VECTOR, THE JACOBIAN
C     MATRIX, AND THE RESIDUAL VECTOR RESPECTIVELY, PROVIDED LIV AND LV
C     ARE LARGE ENOUGH.  IF SO, THEN SNLAGB RETURNS WITH IV(1) = 14.
C     WHEN CALLED WITH IV(1) = 14, SNLAGB ASSUMES THAT STORAGE HAS
C     BEEN ALLOCATED, AND IT BEGINS THE MINIMIZATION ALGORITHM.
C
C  ***  SCALE VECTOR  ***
C
C        ONE DIFFERENCE WITH NL2SOL IS THAT THE SCALE VECTOR D IS
C     STORED IN V, STARTING AT A DIFFERENT SUBSCRIPT.  THE STARTING
C     SUBSCRIPT VALUE IS STILL STORED IN IV(D) = IV(27).  THE
C     DISCUSSION OF DEFAULT VALUES ABOVE TELLS HOW TO HAVE IV(D) SET
C     BEFORE THE ALGORITHM IS STARTED.
C
C  ***  GENERAL  ***
C
C     CODED BY <NAME>.
C
C  ***  EXTERNAL SUBROUTINES  ***
C
      EXTERNAL SIVSET, SRN2GB
c--S replaces "?": ?NLAGB, ?IVSET, ?RN2GB, ?CALCR, ?CALCJ
C SIVSET.... PROVIDES DEFAULT IV AND V INPUT COMPONENTS.
C  SRN2GB... CARRIES OUT OPTIMIZATION ITERATIONS.
C
C  ***  LOCAL VARIABLES  ***
C
      INTEGER D1, DR1, IV1, N1, N2, NF, R1, RD1
C
C  ***  IV COMPONENTS  ***
C
      INTEGER D, J, NEXTV, NFCALL, NFGCAL, R, REGD0, TOOBIG, VNEED
C/6
C     DATA D/27/, J/70/, NEXTV/47/, NFCALL/6/, NFGCAL/7/, R/61/,
C    1     REGD0/82/, TOOBIG/2/, VNEED/4/
C/7
      PARAMETER (D=27, J=70, NEXTV=47, NFCALL=6, NFGCAL=7, R=61,
     1           REGD0=82, TOOBIG=2, VNEED=4)
C/
c --------------------------------  BODY  ------------------------------
C
      IF (IV(1) .EQ. 0) CALL SIVSET(1, IV, LIV, LV, V)
      IV1 = IV(1)
      IF (IV1 .EQ. 14) GO TO 10
      IF (IV1 .GT. 2 .AND. IV1 .LT. 12) GO TO 10
      IF (IV1 .EQ. 12) IV(1) = 13
      IF (IV(1) .EQ. 13) IV(VNEED) = IV(VNEED) + P + N*(P+2)
      CALL SRN2GB(B, X, V, IV, LIV, LV, N, N, N1, N2, P, V, V, V, X)
      IF (IV(1) .NE. 14) GO TO 999
C
C  ***  STORAGE ALLOCATION  ***
C
      IV(D) = IV(NEXTV)
      IV(R) = IV(D) + P
      IV(REGD0) = IV(R) + N
      IV(J) = IV(REGD0) + N
      IV(NEXTV) = IV(J) + N*P
      IF (IV1 .EQ. 13) GO TO 999
C
 10   D1 = IV(D)
      DR1 = IV(J)
      R1 = IV(R)
      RD1 = IV(REGD0)
C
 20   CALL SRN2GB(B, V(D1), V(DR1), IV, LIV, LV, N, N, N1, N2, P, V(R1),
     1            V(RD1), V, X)
      IF (IV(1)-2) 30, 50, 999
C
C  ***  NEW FUNCTION VALUE (R VALUE) NEEDED  ***
C
 30   NF = IV(NFCALL)
C%%    (*scalcr)( n, p, x, &nf, &V[r1] );
      CALL SCALCR(N, P, X, NF, V(R1))
      IF (NF .GT. 0) GO TO 40
         IV(TOOBIG) = 1
         GO TO 20
 40   IF (IV(1) .GT. 0) GO TO 20
C
C  ***  COMPUTE DR = GRADIENT OF R COMPONENTS  ***
C
 50   CONTINUE
C%%    (*scalcj)( n, p, x, &Iv[NFGCAL], &V[dr1] );
      CALL SCALCJ(N, P, X, IV(NFGCAL), V(DR1))
      IF (IV(NFGCAL) .EQ. 0) IV(TOOBIG) = 1
      GO TO 20
C
 999  RETURN
C
C  ***  LAST CARD OF   SNLAGB FOLLOWS  ***
      END
