Code covered by the BSD License  

Highlights from
slatec

from slatec by Ben Barrowes
The slatec library converted into matlab functions.

[fcn,iopt,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,maxfev,epsfcn,diag,mode,factor,nprint,info,nfev,njev,ipvt,qtf,wa1,wa2,wa3,wa4]=snls1(fcn,iopt,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,maxfev,epsfcn,diag,mode,factor,nprint,info,nfev,njev,ipvt,qtf,wa1,wa2,wa3,w
function [fcn,iopt,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,maxfev,epsfcn,diag,mode,factor,nprint,info,nfev,njev,ipvt,qtf,wa1,wa2,wa3,wa4]=snls1(fcn,iopt,m,n,x,fvec,fjac,ldfjac,ftol,xtol,gtol,maxfev,epsfcn,diag,mode,factor,nprint,info,nfev,njev,ipvt,qtf,wa1,wa2,wa3,wa4);
%***BEGIN PROLOGUE  SNLS1
%***PURPOSE  Minimize the sum of the squares of M nonlinear functions
%            in N variables by a modification of the Levenberg-Marquardt
%            algorithm.
%***LIBRARY   SLATEC
%***CATEGORY  K1B1A1, K1B1A2
%***TYPE      SINGLE PRECISION (SNLS1-S, DNLS1-D)
%***KEYWORDS  LEVENBERG-MARQUARDT, NONLINEAR DATA FITTING,
%             NONLINEAR LEAST SQUARES
%***AUTHOR  Hiebert, K. L., (SNLA)
%***DESCRIPTION
%
% 1. Purpose.
%
%       The purpose of SNLS1 is to minimize the sum of the squares of M
%       nonlinear functions in N variables by a modification of the
%       Levenberg-Marquardt algorithm.  The user must provide a subrou-
%       tine which calculates the functions.  The user has the option
%       of how the Jacobian will be supplied.  The user can supply the
%       full Jacobian, or the rows of the Jacobian (to avoid storing
%       the full Jacobian), or let the code approximate the Jacobian by
%       forward-differencing.   This code is the combination of the
%       MINPACK codes (Argonne) LMDER, LMDIF, and LMSTR.
%
%
% 2. subroutine and Type Statements.
%
%       subroutine SNLS1(FCN,IOPT,M,N,X,FVEC,FJAC,LDFJAC,FTOL,XTOL,
%      *                 GTOL,MAXFEV,EPSFCN,DIAG,MODE,FACTOR,NPRINT,INFO
%      *                 ,NFEV,NJEV,IPVT,QTF,WA1,WA2,WA3,WA4)
%       INTEGER IOPT,M,N,LDFJAC,MAXFEV,MODE,NPRINT,INFO,NFEV,NJEV
%       INTEGER IPVT(N)
%       REAL FTOL,XTOL,GTOL,EPSFCN,FACTOR
%       REAL X(N),FVEC(M),FJAC(LDFJAC,N),DIAG(N),QTF(N),
%      *     WA1(N),WA2(N),WA3(N),WA4(M)
%
%
% 3. Parameters.
%
%       Parameters designated as input parameters must be specified on
%       entry to SNLS1 and are not changed on exit, while parameters
%       designated as output parameters need not be specified on entry
%       and are set to appropriate values on exit from SNLS1.
%
%       FCN is the name of the user-supplied subroutine which calculates
%         the functions.  If the user wants to supply the Jacobian
%         (IOPT=2 or 3), then FCN must be written to calculate the
%         Jacobian, as well as the functions.  See the explanation
%         of the IOPT argument below.
%         If the user wants the iterates printed (NPRINT positive), then
%         FCN must do the printing.  See the explanation of NPRINT
%         below.  FCN must be declared in an EXTERNAL statement in the
%         calling program and should be written as follows.
%
%
%         subroutine FCN(IFLAG,M,N,X,FVEC,FJAC,LDFJAC)
%         INTEGER IFLAG,LDFJAC,M,N
%         REAL X(N),FVEC(M)
%         ----------
%         FJAC and LDFJAC may be ignored     , if IOPT=1.
%         REAL FJAC(LDFJAC,N)                , if IOPT=2.
%         REAL FJAC(N)                       , if IOPT=3.
%         ----------
%           If IFLAG=0, the values in X and FVEC are available
%           for printing.  See the explanation of NPRINT below.
%           IFLAG will never be zero unless NPRINT is positive.
%           The values of X and FVEC must not be changed.
%         RETURN
%         ----------
%           If IFLAG=1, calculate the functions at X and return
%           this vector in FVEC.
%         RETURN
%         ----------
%           If IFLAG=2, calculate the full Jacobian at X and return
%           this matrix in FJAC.  Note that IFLAG will never be 2 unless
%           IOPT=2.  FVEC contains the function values at X and must
%           not be altered.  FJAC(I,J) must be set to the derivative
%           of FVEC(I) with respect to X(J).
%         RETURN
%         ----------
%           If IFLAG=3, calculate the LDFJAC-th row of the Jacobian
%           and return this vector in FJAC.  Note that IFLAG will
%           never be 3 unless IOPT=3.  FVEC contains the function
%           values at X and must not be altered.  FJAC(J) must be
%           set to the derivative of FVEC(LDFJAC) with respect to X(J).
%         RETURN
%         ----------
%         end
%
%
%         The value of IFLAG should not be changed by FCN unless the
%         user wants to terminate execution of SNLS1.  In this case, set
%         IFLAG to a negative integer.
%
%
%       IOPT is an input variable which specifies how the Jacobian will
%         be calculated.  If IOPT=2 or 3, then the user must supply the
%         Jacobian, as well as the function values, through the
%         subroutine FCN.  If IOPT=2, the user supplies the full
%         Jacobian with one call to FCN.  If IOPT=3, the user supplies
%         one row of the Jacobian with each call.  (In this manner,
%         storage can be saved because the full Jacobian is not stored.)
%         If IOPT=1, the code will approximate the Jacobian by forward
%         differencing.
%
%       M is a positive integer input variable set to the number of
%         functions.
%
%       N is a positive integer input variable set to the number of
%         variables.  N must not exceed M.
%
%       X is an array of length N.  On input, X must contain an initial
%         estimate of the solution vector.  On output, X contains the
%         final estimate of the solution vector.
%
%       FVEC is an output array of length M which contains the functions
%         evaluated at the output X.
%
%       FJAC is an output array.  For IOPT=1 and 2, FJAC is an M by N
%         array.  For IOPT=3, FJAC is an N by N array.  The upper N by N
%         submatrix of FJAC contains an upper triangular matrix R with
%         diagonal elements of nonincreasing magnitude such that
%
%                T     T           T
%               P *(JAC *JAC)*P = R *R,
%
%         where P is a permutation matrix and JAC is the final calcu-
%         lated Jacobian.  Column J of P is column IPVT(J) (see below)
%         of the identity matrix.  The lower part of FJAC contains
%         information generated during the computation of R.
%
%       LDFJAC is a positive integer input variable which specifies
%         the leading dimension of the array FJAC.  For IOPT=1 and 2,
%         LDFJAC must not be less than M.  For IOPT=3, LDFJAC must not
%         be less than N.
%
%       FTOL is a non-negative input variable.  Termination occurs when
%         both the actual and predicted relative reductions in the sum
%         of squares are at most FTOL.  Therefore, FTOL measures the
%         relative error desired in the sum of squares.  Section 4 con-
%         tains more details about FTOL.
%
%       XTOL is a non-negative input variable.  Termination occurs when
%         the relative error between two consecutive iterates is at most
%         XTOL.  Therefore, XTOL measures the relative error desired in
%         the approximate solution.  Section 4 contains more details
%         about XTOL.
%
%       GTOL is a non-negative input variable.  Termination occurs when
%         the cosine of the angle between FVEC and any column of the
%         Jacobian is at most GTOL in absolute value.  Therefore, GTOL
%         measures the orthogonality desired between the function vector
%         and the columns of the Jacobian.  Section 4 contains more
%         details about GTOL.
%
%       MAXFEV is a positive integer input variable.  Termination occurs
%         when the number of calls to FCN to evaluate the functions
%         has reached MAXFEV.
%
%       EPSFCN is an input variable used in determining a suitable step
%         for the forward-difference approximation.  This approximation
%         assumes that the relative errors in the functions are of the
%         order of EPSFCN.  If EPSFCN is less than the machine preci-
%         sion, it is assumed that the relative errors in the functions
%         are of the order of the machine precision.  If IOPT=2 or 3,
%         then EPSFCN can be ignored (treat it as a dummy argument).
%
%       DIAG is an array of length N.  If MODE = 1 (see below), DIAG is
%         internally set.  If MODE = 2, DIAG must contain positive
%         entries that serve as implicit (multiplicative) scale factors
%         for the variables.
%
%       MODE is an integer input variable.  If MODE = 1, the variables
%         will be scaled internally.  If MODE = 2, the scaling is speci-
%         fied by the input DIAG.  Other values of MODE are equivalent
%         to MODE = 1.
%
%       FACTOR is a positive input variable used in determining the ini-
%         tial step bound.  This bound is set to the product of FACTOR
%         and the Euclidean norm of DIAG*X if nonzero, or else to FACTOR
%         itself.  In most cases FACTOR should lie in the interval
%         (.1,100.).  100. is a generally recommended value.
%
%       NPRINT is an integer input variable that enables controlled
%         printing of iterates if it is positive.  In this case, FCN is
%         called with IFLAG = 0 at the beginning of the first iteration
%         and every NPRINT iterations thereafter and immediately prior
%         to return, with X and FVEC available for printing. Appropriate
%         print statements must be added to FCN (see example) and
%         FVEC should not be altered.  If NPRINT is not positive, no
%         special calls to FCN with IFLAG = 0 are made.
%
%       INFO is an integer output variable.  If the user has terminated
%         execution, INFO is set to the (negative) value of IFLAG.  See
%         description of FCN and JAC. Otherwise, INFO is set as follows.
%
%         INFO = 0  improper input parameters.
%
%         INFO = 1  both actual and predicted relative reductions in the
%                   sum of squares are at most FTOL.
%
%         INFO = 2  relative error between two consecutive iterates is
%                   at most XTOL.
%
%         INFO = 3  conditions for INFO = 1 and INFO = 2 both hold.
%
%         INFO = 4  the cosine of the angle between FVEC and any column
%                   of the Jacobian is at most GTOL in absolute value.
%
%         INFO = 5  number of calls to FCN for function evaluation
%                   has reached MAXFEV.
%
%         INFO = 6  FTOL is too small.  No further reduction in the sum
%                   of squares is possible.
%
%         INFO = 7  XTOL is too small.  No further improvement in the
%                   approximate solution X is possible.
%
%         INFO = 8  GTOL is too small.  FVEC is orthogonal to the
%                   columns of the Jacobian to machine precision.
%
%         Sections 4 and 5 contain more details about INFO.
%
%       NFEV is an integer output variable set to the number of calls to
%         FCN for function evaluation.
%
%       NJEV is an integer output variable set to the number of
%         evaluations of the full Jacobian.  If IOPT=2, only one call to
%         FCN is required for each evaluation of the full Jacobian.
%         If IOPT=3, the M calls to FCN are required.
%         If IOPT=1, then NJEV is set to zero.
%
%       IPVT is an integer output array of length N.  IPVT defines a
%         permutation matrix P such that JAC*P = Q*R, where JAC is the
%         final calculated Jacobian, Q is orthogonal (not stored), and R
%         is upper triangular with diagonal elements of nonincreasing
%         magnitude.  Column J of P is column IPVT(J) of the identity
%         matrix.
%
%       QTF is an output array of length N which contains the first N
%         elements of the vector (Q transpose)*FVEC.
%
%       WA1, WA2, and WA3 are work arrays of length N.
%
%       WA4 is a work array of length M.
%
%
% 4. Successful Completion.
%
%       The accuracy of SNLS1 is controlled by the convergence parame-
%       ters FTOL, XTOL, and GTOL.  These parameters are used in tests
%       which make three types of comparisons between the approximation
%       X and a solution XSOL.  SNLS1 terminates when any of the tests
%       is satisfied.  If any of the convergence parameters is less than
%       the machine precision (as defined by the function R1MACH(4)),
%       then SNLS1 only attempts to satisfy the test defined by the
%       machine precision.  Further progress is not usually possible.
%
%       The tests assume that the functions are reasonably well behaved,
%       and, if the Jacobian is supplied by the user, that the functions
%       and the Jacobian are coded consistently.  If these conditions
%       are not satisfied, then SNLS1 may incorrectly indicate conver-
%       gence.  If the Jacobian is coded correctly or IOPT=1,
%       then the validity of the answer can be checked, for example, by
%       rerunning SNLS1 with tighter tolerances.
%
%       First Convergence Test.  If ENORM(Z) denotes the Euclidean norm
%         of a vector Z, then this test attempts to guarantee that
%
%               ENORM(FVEC) .LE. (1+FTOL)*ENORM(FVECS),
%
%         where FVECS denotes the functions evaluated at XSOL.  If this
%         condition is satisfied with FTOL = 10**(-K), then the final
%         residual norm ENORM(FVEC) has K significant decimal digits and
%         INFO is set to 1 (or to 3 if the second test is also satis-
%         fied).  Unless high precision solutions are required, the
%         recommended value for FTOL is the square root of the machine
%         precision.
%
%       Second Convergence Test.  If D is the diagonal matrix whose
%         entries are defined by the array DIAG, then this test attempts
%         to guarantee that
%
%               ENORM(D*(X-XSOL)) .LE. XTOL*ENORM(D*XSOL).
%
%         If this condition is satisfied with XTOL = 10**(-K), then the
%         larger components of D*X have K significant decimal digits and
%         INFO is set to 2 (or to 3 if the first test is also satis-
%         fied).  There is a danger that the smaller components of D*X
%         may have large relative errors, but if MODE = 1, then the
%         accuracy of the components of X is usually related to their
%         sensitivity.  Unless high precision solutions are required,
%         the recommended value for XTOL is the square root of the
%         machine precision.
%
%       Third Convergence Test.  This test is satisfied when the cosine
%         of the angle between FVEC and any column of the Jacobian at X
%         is at most GTOL in absolute value.  There is no clear rela-
%         tionship between this test and the accuracy of SNLS1, and
%         furthermore, the test is equally well satisfied at other crit-
%         ical points, namely maximizers and saddle points.  Therefore,
%         termination caused by this test (INFO = 4) should be examined
%         carefully.  The recommended value for GTOL is zero.
%
%
% 5. Unsuccessful Completion.
%
%       Unsuccessful termination of SNLS1 can be due to improper input
%       parameters, arithmetic interrupts, or an excessive number of
%       function evaluations.
%
%       Improper Input Parameters.  INFO is set to 0 if IOPT .LT. 1
%         or IOPT .GT. 3, or N .LE. 0, or M .LT. N, or for IOPT=1 or 2
%         LDFJAC .LT. M, or for IOPT=3 LDFJAC .LT. N, or FTOL .LT. 0.0E0,
%         or XTOL .LT. 0.0E0, or GTOL .LT. 0.0E0, or MAXFEV .LE. 0, or
%         FACTOR .LE. 0.0E0.
%
%       Arithmetic Interrupts.  If these interrupts occur in the FCN
%         subroutine during an early stage of the computation, they may
%         be caused by an unacceptable choice of X by SNLS1.  In this
%         case, it may be possible to remedy the situation by rerunning
%         SNLS1 with a smaller value of FACTOR.
%
%       Excessive Number of Function Evaluations.  A reasonable value
%         for MAXFEV is 100*(N+1) for IOPT=2 or 3 and 200*(N+1) for
%         IOPT=1.  If the number of calls to FCN reaches MAXFEV, then
%         this indicates that the routine is converging very slowly
%         as measured by the progress of FVEC, and INFO is set to 5.
%         In this case, it may be helpful to restart SNLS1 with MODE
%         set to 1.
%
%
% 6. Characteristics of the Algorithm.
%
%       SNLS1 is a modification of the Levenberg-Marquardt algorithm.
%       Two of its main characteristics involve the proper use of
%       implicitly scaled variables (if MODE = 1) and an optimal choice
%       for the correction.  The use of implicitly scaled variables
%       achieves scale invariance of SNLS1 and limits the size of the
%       correction in any direction where the functions are changing
%       rapidly.  The optimal choice of the correction guarantees (under
%       reasonable conditions) global convergence from starting points
%       far from the solution and a fast rate of convergence for
%       problems with small residuals.
%
%       Timing.  The time required by SNLS1 to solve a given problem
%         depends on M and N, the behavior of the functions, the accu-
%         racy requested, and the starting point.  The number of arith-
%         metic operations needed by SNLS1 is about N**3 to process each
%         evaluation of the functions (call to FCN) and to process each
%         evaluation of the Jacobian it takes M*N**2 for IOPT=2 (one
%         call to FCN), M*N**2 for IOPT=1 (N calls to FCN) and
%         1.5*M*N**2 for IOPT=3 (M calls to FCN).  Unless FCN
%         can be evaluated quickly, the timing of SNLS1 will be
%         strongly influenced by the time spent in FCN.
%
%       Storage.  SNLS1 requires (M*N + 2*M + 6*N) for IOPT=1 or 2 and
%         (N**2 + 2*M + 6*N) for IOPT=3 single precision storage
%         locations and N integer storage locations, in addition to
%         the storage required by the program.  There are no internally
%         declared storage arrays.
%
% *Long Description:
%
% 7. Example.
%
%       The problem is to determine the values of X(1), X(2), and X(3)
%       which provide the best fit (in the least squares sense) of
%
%             X(1) + U(I)/(V(I)*X(2) + W(I)*X(3)),  I = 1, 15
%
%       to the data
%
%             Y = (0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,
%                  0.37,0.58,0.73,0.96,1.34,2.10,4.39),
%
%       where U(I) = I, V(I) = 16 - I, and W(I) = MIN(U(I),V(I)).  The
%       I-th component of FVEC is thus defined by
%
%             Y(I) - (X(1) + U(I)/(V(I)*X(2) + W(I)*X(3))).
%
%       **********
%
%       program TEST
% C
% C     Driver for SNLS1 example.
% C
%       INTEGER J,IOPT,M,N,LDFJAC,MAXFEV,MODE,NPRINT,INFO,NFEV,NJEV,
%      *        NWRITE
%       INTEGER IPVT(3)
%       REAL FTOL,XTOL,GTOL,FACTOR,FNORM,EPSFCN
%       REAL X(3),FVEC(15),FJAC(15,3),DIAG(3),QTF(3),
%      *     WA1(3),WA2(3),WA3(3),WA4(15)
%       REAL ENORM,R1MACH
%       EXTERNAL FCN
%       DATA NWRITE /6/
% C
%       IOPT = 1
%       M = 15
%       N = 3
% C
% C     The following starting values provide a rough fit.
% C
%       X(1) = 1.0E0
%       X(2) = 1.0E0
%       X(3) = 1.0E0
% C
%       LDFJAC = 15
% C
% C     Set FTOL and XTOL to the square root of the machine precision
% C     and GTOL to zero.  Unless high precision solutions are
% C     required, these are the recommended settings.
% C
%       FTOL = SQRT(R1MACH(4))
%       XTOL = SQRT(R1MACH(4))
%       GTOL = 0.0E0
% C
%       MAXFEV = 400
%       EPSFCN = 0.0
%       MODE = 1
%       FACTOR = 1.0E2
%       NPRINT = 0
% C
%       CALL SNLS1(FCN,IOPT,M,N,X,FVEC,FJAC,LDFJAC,FTOL,XTOL,
%      *           GTOL,MAXFEV,EPSFCN,DIAG,MODE,FACTOR,NPRINT,
%      *           INFO,NFEV,NJEV,IPVT,QTF,WA1,WA2,WA3,WA4)
%       FNORM = ENORM(M,FVEC)
%       WRITE (NWRITE,1000) FNORM,NFEV,NJEV,INFO,(X(J),J=1,N)
%       STOP
%  1000 FORMAT (5X,' FINAL L2 NORM OF THE RESIDUALS',E15.7 //
%      *        5X,' NUMBER OF FUNCTION EVALUATIONS',I10 //
%      *        5X,' NUMBER OF JACOBIAN EVALUATIONS',I10 //
%      *        5X,' EXIT PARAMETER',16X,I10 //
%      *        5X,' FINAL APPROXIMATE SOLUTION' // 5X,3E15.7)
%       end
%       subroutine FCN(IFLAG,M,N,X,FVEC,DUM,IDUM)
% C     This is the form of the FCN routine if IOPT=1,
% C     that is, if the user does not calculate the Jacobian.
%       INTEGER M,N,IFLAG
%       REAL X(N),FVEC(M)
%       INTEGER I
%       REAL TMP1,TMP2,TMP3,TMP4
%       REAL Y(15)
%       DATA Y(1),Y(2),Y(3),Y(4),Y(5),Y(6),Y(7),Y(8),
%      *     Y(9),Y(10),Y(11),Y(12),Y(13),Y(14),Y(15)
%      *     /1.4E-1,1.8E-1,2.2E-1,2.5E-1,2.9E-1,3.2E-1,3.5E-1,3.9E-1,
%      *      3.7E-1,5.8E-1,7.3E-1,9.6E-1,1.34E0,2.1E0,4.39E0/
% C
%       IF (IFLAG .NE. 0) GO TO 5
% C
% C     Insert print statements here when NPRINT is positive.
% C
%       RETURN
%     5 CONTINUE
%       DO 10 I = 1, M
%          TMP1 = I
%          TMP2 = 16 - I
%          TMP3 = TMP1
%          IF (I .GT. 8) TMP3 = TMP2
%          FVEC(I) = Y(I) - (X(1) + TMP1/(X(2)*TMP2 + X(3)*TMP3))
%    10    CONTINUE
%       RETURN
%       end
%
%
%       Results obtained with different compilers or machines
%       may be slightly different.
%
%       FINAL L2 NORM OF THE RESIDUALS  0.9063596E-01
%
%       NUMBER OF FUNCTION EVALUATIONS        25
%
%       NUMBER OF JACOBIAN EVALUATIONS         0
%
%       EXIT PARAMETER                         1
%
%       FINAL APPROXIMATE SOLUTION
%
%        0.8241058E-01  0.1133037E+01  0.2343695E+01
%
%
%       For IOPT=2, FCN would be modified as follows to also
%       calculate the full Jacobian when IFLAG=2.
%
%       subroutine FCN(IFLAG,M,N,X,FVEC,FJAC,LDFJAC)
% C
% C     This is the form of the FCN routine if IOPT=2,
% C     that is, if the user calculates the full Jacobian.
% C
%       INTEGER LDFJAC,M,N,IFLAG
%       REAL X(N),FVEC(M)
%       REAL FJAC(LDFJAC,N)
%       INTEGER I
%       REAL TMP1,TMP2,TMP3,TMP4
%       REAL Y(15)
%       DATA Y(1),Y(2),Y(3),Y(4),Y(5),Y(6),Y(7),Y(8),
%      *     Y(9),Y(10),Y(11),Y(12),Y(13),Y(14),Y(15)
%      *     /1.4E-1,1.8E-1,2.2E-1,2.5E-1,2.9E-1,3.2E-1,3.5E-1,3.9E-1,
%      *      3.7E-1,5.8E-1,7.3E-1,9.6E-1,1.34E0,2.1E0,4.39E0/
% C
%       IF (IFLAG .NE. 0) GO TO 5
% C
% C     Insert print statements here when NPRINT is positive.
% C
%       RETURN
%     5 CONTINUE
%       IF(IFLAG.NE.1) GO TO 20
%       DO 10 I = 1, M
%          TMP1 = I
%          TMP2 = 16 - I
%          TMP3 = TMP1
%          IF (I .GT. 8) TMP3 = TMP2
%          FVEC(I) = Y(I) - (X(1) + TMP1/(X(2)*TMP2 + X(3)*TMP3))
%    10    CONTINUE
%       RETURN
% C
% C     Below, calculate the full Jacobian.
% C
%    20    CONTINUE
% C
%       DO 30 I = 1, M
%          TMP1 = I
%          TMP2 = 16 - I
%          TMP3 = TMP1
%          IF (I .GT. 8) TMP3 = TMP2
%          TMP4 = (X(2)*TMP2 + X(3)*TMP3)**2
%          FJAC(I,1) = -1.0E0
%          FJAC(I,2) = TMP1*TMP2/TMP4
%          FJAC(I,3) = TMP1*TMP3/TMP4
%    30    CONTINUE
%       RETURN
%       end
%
%
%       For IOPT = 3, FJAC would be dimensioned as FJAC(3,3),
%         LDFJAC would be set to 3, and FCN would be written as
%         follows to calculate a row of the Jacobian when IFLAG=3.
%
%       subroutine FCN(IFLAG,M,N,X,FVEC,FJAC,LDFJAC)
% C     This is the form of the FCN routine if IOPT=3,
% C     that is, if the user calculates the Jacobian row by row.
%       INTEGER M,N,IFLAG
%       REAL X(N),FVEC(M)
%       REAL FJAC(N)
%       INTEGER I
%       REAL TMP1,TMP2,TMP3,TMP4
%       REAL Y(15)
%       DATA Y(1),Y(2),Y(3),Y(4),Y(5),Y(6),Y(7),Y(8),
%      *     Y(9),Y(10),Y(11),Y(12),Y(13),Y(14),Y(15)
%      *     /1.4E-1,1.8E-1,2.2E-1,2.5E-1,2.9E-1,3.2E-1,3.5E-1,3.9E-1,
%      *      3.7E-1,5.8E-1,7.3E-1,9.6E-1,1.34E0,2.1E0,4.39E0/
% C
%       IF (IFLAG .NE. 0) GO TO 5
% C
% C     Insert print statements here when NPRINT is positive.
% C
%       RETURN
%     5 CONTINUE
%       IF( IFLAG.NE.1) GO TO 20
%       DO 10 I = 1, M
%          TMP1 = I
%          TMP2 = 16 - I
%          TMP3 = TMP1
%          IF (I .GT. 8) TMP3 = TMP2
%          FVEC(I) = Y(I) - (X(1) + TMP1/(X(2)*TMP2 + X(3)*TMP3))
%    10    CONTINUE
%       RETURN
% C
% C     Below, calculate the LDFJAC-th row of the Jacobian.
% C
%    20 CONTINUE
%
%       I = LDFJAC
%          TMP1 = I
%          TMP2 = 16 - I
%          TMP3 = TMP1
%          IF (I .GT. 8) TMP3 = TMP2
%          TMP4 = (X(2)*TMP2 + X(3)*TMP3)**2
%          FJAC(1) = -1.0E0
%          FJAC(2) = TMP1*TMP2/TMP4
%          FJAC(3) = TMP1*TMP3/TMP4
%       RETURN
%       end
%
%***REFERENCES  Jorge J. More, The Levenberg-Marquardt algorithm:
%                 implementation and theory.  In Numerical Analysis
%                 Proceedings (Dundee, June 28 - July 1, 1977, G. A.
%                 Watson, Editor), Lecture Notes in Mathematics 630,
%                 Springer-Verlag, 1978.
%***ROUTINES CALLED  CHKDER, ENORM, FDJAC3, LMPAR, QRFAC, R1MACH,
%                    RWUPDT, XERMSG
%***REVISION HISTORY  (YYMMDD)
%   800301  DATE WRITTEN
%   890531  Changed all specific intrinsics to generic.  (WRB)
%   890531  REVISION DATE from Version 3.2
%   891214  Prologue converted to Version 4.0 format.  (BAB)
%   900315  CALLs to XERROR changed to CALLs to XERMSG.  (THJ)
%   900510  Convert XERRWV calls to XERMSG calls.  (RWC)
%   920501  Reformatted the REFERENCES section.  (WRB)
%***end PROLOGUE  SNLS1
persistent actred chklim delta dirder epsmch err firstCall fnorm fnorm1 gnorm gt100 i iflag ijunk iter j l modech nrow one p0001 p1 p25 p5 p75 par pnorm prered ratio sing summlv temp temp1 temp2 xern1 xern3 xnorm zero ; if isempty(firstCall),firstCall=1;end; 

if isempty(gt100), gt100=0; end;
if isempty(ijunk), ijunk=0; end;
if isempty(nrow), nrow=0; end;
ipvt_shape=size(ipvt);ipvt=reshape(ipvt,1,[]);
x_shape=size(x);x=reshape(x,1,[]);
fvec_shape=size(fvec);fvec=reshape(fvec,1,[]);
fjac_shape=size(fjac);fjac=reshape([fjac(:).',zeros(1,ceil(numel(fjac)./prod([ldfjac])).*prod([ldfjac])-numel(fjac))],ldfjac,[]);
diag_shape=size(diag);diag=reshape(diag,1,[]);
qtf_shape=size(qtf);qtf=reshape(qtf,1,[]);
wa1_shape=size(wa1);wa1=reshape(wa1,1,[]);
wa2_shape=size(wa2);wa2=reshape(wa2,1,[]);
wa3_shape=size(wa3);wa3=reshape(wa3,1,[]);
wa4_shape=size(wa4);wa4=reshape(wa4,1,[]);
if isempty(sing), sing=false; end;
if isempty(i), i=0; end;
if isempty(iflag), iflag=0; end;
if isempty(iter), iter=0; end;
if isempty(j), j=0; end;
if isempty(l), l=0; end;
if isempty(modech), modech=0; end;
if isempty(actred), actred=0; end;
if isempty(delta), delta=0; end;
if isempty(dirder), dirder=0; end;
if isempty(epsmch), epsmch=0; end;
if isempty(fnorm), fnorm=0; end;
if isempty(fnorm1), fnorm1=0; end;
if isempty(gnorm), gnorm=0; end;
if isempty(one), one=0; end;
if isempty(par), par=0; end;
if isempty(pnorm), pnorm=0; end;
if isempty(prered), prered=0; end;
if isempty(p1), p1=0; end;
if isempty(p5), p5=0; end;
if isempty(p25), p25=0; end;
if isempty(p75), p75=0; end;
if isempty(p0001), p0001=0; end;
if isempty(ratio), ratio=0; end;
if isempty(summlv), summlv=0; end;
if isempty(temp), temp=0; end;
if isempty(temp1), temp1=0; end;
if isempty(temp2), temp2=0; end;
if isempty(xnorm), xnorm=0; end;
if isempty(zero), zero=0; end;
if isempty(err), err=0; end;
if isempty(chklim), chklim=0; end;
if isempty(xern1), xern1=repmat(' ',1,8); end;
if isempty(xern3), xern3=repmat(' ',1,16); end;
%
if firstCall,   chklim=[.1e0];  end;
if firstCall,   one =[1.0e0];  end;
if firstCall,  p1 =[1.0e-1];  end;
if firstCall,  p5 =[5.0e-1];  end;
if firstCall,  p25 =[2.5e-1];  end;
if firstCall,  p75 =[7.5e-1];  end;
if firstCall,  p0001 =[1.0e-4];  end;
if firstCall,  zero=[0.0e0];  end;
firstCall=0;
%
%***FIRST EXECUTABLE STATEMENT  SNLS1
[epsmch ]=r1mach(4);
%
info = 0;
iflag = 0;
nfev = 0;
njev = 0;
%
%     CHECK THE INPUT PARAMETERS FOR ERRORS.
%
gt100=0;
while (1);
if( iopt>=1 && iopt<=3 && n>0 && m>=n &&ldfjac>=n && ftol>=zero && xtol>=zero &&gtol>=zero && maxfev>0 && factor>zero )
if( iopt>=3 || ldfjac>=m )
if( mode==2 )
for j = 1 : n;
if( diag(j)<=zero )
gt100=1;
break;
end;
end;
if(gt100==1)
break;
end;
end;
%
%     EVALUATE THE FUNCTION AT THE STARTING POINT
%     AND CALCULATE ITS NORM.
%
iflag = 1;
ijunk = 1;
[iflag,m,n,x,fvec,fjac,ijunk]=fcn(iflag,m,n,x,fvec,fjac,ijunk);
nfev = 1;
if( iflag>=0 )
[fnorm ,m,fvec]=enorm(m,fvec);
%
%     INITIALIZE LEVENBERG-MARQUARDT PARAMETER AND ITERATION COUNTER.
%
par = zero;
iter = 1;
%
%     BEGINNING OF THE OUTER LOOP.
%
%
%        IF REQUESTED, CALL FCN TO ENABLE PRINTING OF ITERATES.
%
while( true );
if( nprint>0 )
iflag = 0;
if( rem(iter-1,nprint)==0 )
[iflag,m,n,x,fvec,fjac,ijunk]=fcn(iflag,m,n,x,fvec,fjac,ijunk);
end;
if( iflag<0 )
break;
end;
end;
%
%        CALCULATE THE JACOBIAN MATRIX.
%
if( iopt==3 )
%
%        ACCUMULATE THE JACOBIAN BY ROWS IN ORDER TO SAVE STORAGE.
%        COMPUTE THE QR FACTORIZATION OF THE JACOBIAN MATRIX
%        CALCULATED ONE ROW AT A TIME, WHILE SIMULTANEOUSLY
%        FORMING (Q TRANSPOSE)*FVEC AND STORING THE FIRST
%        N COMPONENTS IN QTF.
%
for j = 1 : n;
qtf(j) = zero;
for i = 1 : n;
fjac(i,j) = zero;
end; i = fix(n+1);
end; j = fix(n+1);
for i = 1 : m;
nrow = fix(i);
iflag = 3;
[iflag,m,n,x,fvec,wa3,nrow]=fcn(iflag,m,n,x,fvec,wa3,nrow);
if( iflag<0 )
gt100=1;
break;
end;
%
%            ON THE FIRST ITERATION, CHECK THE USER SUPPLIED JACOBIAN.
%
if( iter<=1 )
%
%            GET THE INCREMENTED X-VALUES INTO WA1(*).
%
modech = 1;
[m,n,x,fvec,fjac,ldfjac,wa1,wa4,modech,err]=chkder(m,n,x,fvec,fjac,ldfjac,wa1,wa4,modech,err);
%
%            EVALUATE AT INCREMENTED VALUES, IF NOT ALREADY EVALUATED.
%
if( i==1 )
%
%            EVALUATE FUNCTION AT INCREMENTED VALUE AND PUT INTO WA4(*).
%
iflag = 1;
[iflag,m,n,wa1,wa4,fjac,nrow]=fcn(iflag,m,n,wa1,wa4,fjac,nrow);
nfev = fix(nfev + 1);
if( iflag<0 )
gt100=1;
break;
end;
end;
modech = 2;
[dumvar1,n,x,fvec(sub2ind(size(fvec),max(i,1)):end),wa3,dumvar6,wa1,wa4(sub2ind(size(wa4),max(i,1)):end),modech,err]=chkder(1,n,x,fvec(sub2ind(size(fvec),max(i,1)):end),wa3,1,wa1,wa4(sub2ind(size(wa4),max(i,1)):end),modech,err);
if( err<chklim )
xern1=sprintf(['%8i'], i);
xern3=sprintf([repmat('%15.6f',1,1)], err);
xermsg('SLATEC','SNLS1',['DERIVATIVE OF FUNCTION ',[xern1,[' MAY BE WRONG, ERR = ',[xern3,' TOO CLOSE TO 0.']]]],7,0);
end;
end;
%
temp = fvec(i);
[n,fjac,ldfjac,wa3,qtf,temp,wa1,wa2]=rwupdt(n,fjac,ldfjac,wa3,qtf,temp,wa1,wa2);
end;
njev = fix(njev + 1);
%
%        IF THE JACOBIAN IS RANK DEFICIENT, CALL QRFAC TO
%        REORDER ITS COLUMNS AND UPDATE THE COMPONENTS OF QTF.
%
sing = false;
for j = 1 : n;
if( fjac(j,j)==zero )
sing = true;
end;
ipvt(j) = fix(j);
[wa2(j) ,j,fjac(sub2ind(size(fjac),1,j):end)]=enorm(j,fjac(sub2ind(size(fjac),1,j):end));
end; j = fix(n+1);
if( sing )
n_orig=n; n_orig=n;    [n,dumvar2,fjac,ldfjac,dumvar5,ipvt,dumvar7,wa1,wa2,wa3]=qrfac(n,n,fjac,ldfjac,true,ipvt,n,wa1,wa2,wa3);    n(dumvar7~=n_orig)=dumvar7(dumvar7~=n_orig); n(dumvar2~=n_orig)=dumvar2(dumvar2~=n_orig);
for j = 1 : n;
if( fjac(j,j)~=zero )
summlv = zero;
for i = j : n;
summlv = summlv + fjac(i,j).*qtf(i);
end; i = fix(n+1);
temp = -summlv./fjac(j,j);
for i = j : n;
qtf(i) = qtf(i) + fjac(i,j).*temp;
end; i = fix(n+1);
end;
fjac(j,j) = wa1(j);
end; j = fix(n+1);
end;
else;
%
%     STORE THE FULL JACOBIAN USING M*N STORAGE
%
if( iopt==1 )
%
%     THE CODE APPROXIMATES THE JACOBIAN
%
iflag = 1;
[fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa4]=fdjac3(fcn,m,n,x,fvec,fjac,ldfjac,iflag,epsfcn,wa4);
nfev = fix(nfev + n);
else;
%
%     THE USER SUPPLIES THE JACOBIAN
%
iflag = 2;
[iflag,m,n,x,fvec,fjac,ldfjac]=fcn(iflag,m,n,x,fvec,fjac,ldfjac);
njev = fix(njev + 1);
%
%             ON THE FIRST ITERATION, CHECK THE USER SUPPLIED JACOBIAN
%
if( iter<=1 )
if( iflag<0 )
break;
end;
%
%           GET THE INCREMENTED X-VALUES INTO WA1(*).
%
modech = 1;
[m,n,x,fvec,fjac,ldfjac,wa1,wa4,modech,err]=chkder(m,n,x,fvec,fjac,ldfjac,wa1,wa4,modech,err);
%
%           EVALUATE FUNCTION AT INCREMENTED VALUE AND PUT IN WA4(*).
%
iflag = 1;
[iflag,m,n,wa1,wa4,fjac,ldfjac]=fcn(iflag,m,n,wa1,wa4,fjac,ldfjac);
nfev = fix(nfev + 1);
if( iflag<0 )
break;
end;
for i = 1 : m;
%
modech = 2;
[dumvar1,n,x,fvec(sub2ind(size(fvec),max(i,1)):end),fjac(sub2ind(size(fjac),i,1):end),ldfjac,wa1,wa4(sub2ind(size(wa4),max(i,1)):end),modech,err]=chkder(1,n,x,fvec(sub2ind(size(fvec),max(i,1)):end),fjac(sub2ind(size(fjac),i,1):end),ldfjac,wa1,wa4(sub2ind(size(wa4),max(i,1)):end),modech,err);
if( err<chklim )
xern1=sprintf(['%8i'], i);
xern3=sprintf([repmat('%15.6f',1,1)], err);
xermsg('SLATEC','SNLS1',['DERIVATIVE OF ',['FUNCTION ',[xern1,[' MAY BE WRONG, ERR = ',[xern3,' TOO CLOSE TO 0.']]]]],7,0);
end;
end; i = fix(m+1);
end;
end;
if( iflag<0 )
break;
end;
%
%        COMPUTE THE QR FACTORIZATION OF THE JACOBIAN.
%
n_orig=n;    [m,n,fjac,ldfjac,dumvar5,ipvt,dumvar7,wa1,wa2,wa3]=qrfac(m,n,fjac,ldfjac,true,ipvt,n,wa1,wa2,wa3);    n(dumvar7~=n_orig)=dumvar7(dumvar7~=n_orig);
%
%        FORM (Q TRANSPOSE)*FVEC AND STORE THE FIRST N COMPONENTS IN
%        QTF.
%
for i = 1 : m;
wa4(i) = fvec(i);
end; i = fix(m+1);
for j = 1 : n;
if( fjac(j,j)~=zero )
summlv = zero;
for i = j : m;
summlv = summlv + fjac(i,j).*wa4(i);
end; i = fix(m+1);
temp = -summlv./fjac(j,j);
for i = j : m;
wa4(i) = wa4(i) + fjac(i,j).*temp;
end; i = fix(m+1);
end;
fjac(j,j) = wa1(j);
qtf(j) = wa4(j);
end; j = fix(n+1);
end;
%
%        ON THE FIRST ITERATION AND IF MODE IS 1, SCALE ACCORDING
%        TO THE NORMS OF THE COLUMNS OF THE INITIAL JACOBIAN.
%
if( iter==1 )
if( mode~=2 )
for j = 1 : n;
diag(j) = wa2(j);
if( wa2(j)==zero )
diag(j) = one;
end;
end; j = fix(n+1);
end;
%
%        ON THE FIRST ITERATION, CALCULATE THE NORM OF THE SCALED X
%        AND INITIALIZE THE STEP BOUND DELTA.
%
for j = 1 : n;
wa3(j) = diag(j).*x(j);
end; j = fix(n+1);
[xnorm ,n,wa3]=enorm(n,wa3);
delta = factor.*xnorm;
if( delta==zero )
delta = factor;
end;
end;
%
%        COMPUTE THE NORM OF THE SCALED GRADIENT.
%
gnorm = zero;
if( fnorm~=zero )
for j = 1 : n;
l = fix(ipvt(j));
if( wa2(l)~=zero )
summlv = zero;
for i = 1 : j;
summlv = summlv + fjac(i,j).*(qtf(i)./fnorm);
end; i = fix(j+1);
gnorm = max(gnorm,abs(summlv./wa2(l)));
end;
end; j = fix(n+1);
end;
%
%        TEST FOR CONVERGENCE OF THE GRADIENT NORM.
%
if( gnorm<=gtol )
info = 4;
end;
if( info~=0 )
break;
end;
%
%        RESCALE IF NECESSARY.
%
if( mode~=2 )
for j = 1 : n;
diag(j) = max(diag(j),wa2(j));
end; j = fix(n+1);
end;
%
%        BEGINNING OF THE INNER LOOP.
%
%
%           DETERMINE THE LEVENBERG-MARQUARDT PARAMETER.
%
while( true );
[n,fjac,ldfjac,ipvt,diag,qtf,delta,par,wa1,wa2,wa3,wa4]=lmpar(n,fjac,ldfjac,ipvt,diag,qtf,delta,par,wa1,wa2,wa3,wa4);
%
%           STORE THE DIRECTION P AND X + P. CALCULATE THE NORM OF P.
%
for j = 1 : n;
wa1(j) = -wa1(j);
wa2(j) = x(j) + wa1(j);
wa3(j) = diag(j).*wa1(j);
end; j = fix(n+1);
[pnorm ,n,wa3]=enorm(n,wa3);
%
%           ON THE FIRST ITERATION, ADJUST THE INITIAL STEP BOUND.
%
if( iter==1 )
delta = min(delta,pnorm);
end;
%
%           EVALUATE THE FUNCTION AT X + P AND CALCULATE ITS NORM.
%
iflag = 1;
[iflag,m,n,wa2,wa4,fjac,ijunk]=fcn(iflag,m,n,wa2,wa4,fjac,ijunk);
nfev = fix(nfev + 1);
if( iflag<0 )
gt100=1;
break;
end;
[fnorm1 ,m,wa4]=enorm(m,wa4);
%
%           COMPUTE THE SCALED ACTUAL REDUCTION.
%
actred = -one;
if( p1.*fnorm1<fnorm )
actred = one -(fnorm1./fnorm).^2;
end;
%
%           COMPUTE THE SCALED PREDICTED REDUCTION AND
%           THE SCALED DIRECTIONAL DERIVATIVE.
%
for j = 1 : n;
wa3(j) = zero;
l = fix(ipvt(j));
temp = wa1(l);
for i = 1 : j;
wa3(i) = wa3(i) + fjac(i,j).*temp;
end; i = fix(j+1);
end; j = fix(n+1);
temp1 = enorm(n,wa3)./fnorm;
temp2 =(sqrt(par).*pnorm)./fnorm;
prered = temp1.^2 + temp2.^2./p5;
dirder = -(temp1.^2+temp2.^2);
%
%           COMPUTE THE RATIO OF THE ACTUAL TO THE PREDICTED
%           REDUCTION.
%
ratio = zero;
if( prered~=zero )
ratio = actred./prered;
end;
%
%           UPDATE THE STEP BOUND.
%
if( ratio<=p25 )
if( actred>=zero )
temp = p5;
end;
if( actred<zero )
temp = p5.*dirder./(dirder+p5.*actred);
end;
if( p1.*fnorm1>=fnorm || temp<p1 )
temp = p1;
end;
delta = temp.*min(delta,pnorm./p1);
par = par./temp;
elseif( par==zero || ratio>=p75 ) ;
delta = pnorm./p5;
par = p5.*par;
end;
%
%           TEST FOR SUCCESSFUL ITERATION.
%
if( ratio>=p0001 )
%
%           SUCCESSFUL ITERATION. UPDATE X, FVEC, AND THEIR NORMS.
%
for j = 1 : n;
x(j) = wa2(j);
wa2(j) = diag(j).*x(j);
end; j = fix(n+1);
for i = 1 : m;
fvec(i) = wa4(i);
end; i = fix(m+1);
[xnorm ,n,wa2]=enorm(n,wa2);
fnorm = fnorm1;
iter = fix(iter + 1);
end;
%
%           TESTS FOR CONVERGENCE.
%
if( abs(actred)<=ftol && prered<=ftol &&p5.*ratio<=one )
info = 1;
end;
if( delta<=xtol.*xnorm )
info = 2;
end;
if( abs(actred)<=ftol && prered<=ftol &&p5.*ratio<=one && info==2 )
info = 3;
end;
if( info~=0 )
gt100=1;
break;
end;
%
%           TESTS FOR TERMINATION AND STRINGENT TOLERANCES.
%
if( nfev>=maxfev )
info = 5;
end;
if( abs(actred)<=epsmch && prered<=epsmch &&p5.*ratio<=one )
info = 6;
end;
if( delta<=epsmch.*xnorm )
info = 7;
end;
if( gnorm<=epsmch )
info = 8;
end;
if( info~=0 )
gt100=1;
break;
end;
%
%           end OF THE INNER LOOP. REPEAT IF ITERATION UNSUCCESSFUL.
%
%
%        end OF THE OUTER LOOP.
%
if( ratio>=p0001 )
break;
end;
end;
if(gt100==1)
break;
end;
end;
if(gt100==1)
break;
end;
end;
end;
end;
break;
end;
%
%     TERMINATION, EITHER NORMAL OR USER IMPOSED.
%
if( iflag<0 )
info = fix(iflag);
end;
iflag = 0;
if( nprint>0 )
[iflag,m,n,x,fvec,fjac,ijunk]=fcn(iflag,m,n,x,fvec,fjac,ijunk);
end;
if( info<0 )
xermsg('SLATEC','SNLS1','EXECUTION TERMINATED BECAUSE USER SET IFLAG NEGATIVE.',1,1);
end;
if( info==0 )
xermsg('SLATEC','SNLS1','INVALID INPUT PARAMETER.',2,1);
end;
if( info==4 )
xermsg('SLATEC','SNLS1','THIRD CONVERGENCE CONDITION, CHECK RESULTS BEFORE ACCEPTING.',1,1);
end;
if( info==5 )
xermsg('SLATEC','SNLS1','TOO MANY FUNCTION EVALUATIONS.',9,1);
end;
if( info>=6 )
xermsg('SLATEC','SNLS1','TOLERANCES TOO SMALL, NO FURTHER IMPROVEMENT POSSIBLE.',3,1);
end;
%
%     LAST CARD OF SUBROUTINE SNLS1.
%
ipvt_shape=zeros(ipvt_shape);ipvt_shape(:)=ipvt(1:numel(ipvt_shape));ipvt=ipvt_shape;
x_shape=zeros(x_shape);x_shape(:)=x(1:numel(x_shape));x=x_shape;
fvec_shape=zeros(fvec_shape);fvec_shape(:)=fvec(1:numel(fvec_shape));fvec=fvec_shape;
fjac_shape=zeros(fjac_shape);fjac_shape(:)=fjac(1:numel(fjac_shape));fjac=fjac_shape;
diag_shape=zeros(diag_shape);diag_shape(:)=diag(1:numel(diag_shape));diag=diag_shape;
qtf_shape=zeros(qtf_shape);qtf_shape(:)=qtf(1:numel(qtf_shape));qtf=qtf_shape;
wa1_shape=zeros(wa1_shape);wa1_shape(:)=wa1(1:numel(wa1_shape));wa1=wa1_shape;
wa2_shape=zeros(wa2_shape);wa2_shape(:)=wa2(1:numel(wa2_shape));wa2=wa2_shape;
wa3_shape=zeros(wa3_shape);wa3_shape(:)=wa3(1:numel(wa3_shape));wa3=wa3_shape;
wa4_shape=zeros(wa4_shape);wa4_shape(:)=wa4(1:numel(wa4_shape));wa4=wa4_shape;
end %subroutine snls1
%DECK SNRM2

Contact us at files@mathworks.com