XLPack 6.1
Excel VBA Numerical Library Reference Manual
Loading...
Searching...
No Matches

◆ Lmdif_r()

Sub Lmdif_r ( M As  Long,
N As  Long,
X() As  Double,
Fvec() As  Double,
Fjac() As  Double,
FTol As  Double,
XTol As  Double,
GTol As  Double,
Diag() As  Double,
Mode As  Long,
Ipvt() As  Long,
Info As  Long,
XX() As  Double,
YY() As  Double,
IRev As  Long,
Optional Info2 As  Long,
Optional Maxfev As  Long = 0,
Optional Epsfcn As  Double = 0,
Optional Factor As  Double = 100,
Optional Nprint As  Long = 0,
Optional Nfev As  Long 
)

Nonlinear least squares approximation by Levenberg-Marquardt method (Jacobian not required) (reverse communication version)

Purpose
This routine minimizes the sum of the squares of M nonlinear functions in N variables by a modification of the Levenberg-Marquardt algorithm.
minimize the sum of fi(x1, x2, ..., xN)^2 (sum for i = 1 to M)
The user must provide the calculated function values according to IRev. Since the Jacobian is calculated by a forward-difference approximation within the routine, the user is not required to provide the Jacobian.
Parameters
[in]MNumber of functions. (M > 0)
[in]NNumber of variables. (0 < N <= M)
[in,out]X()Array X(LX - 1) (LX >= N)
[in] An initial estimate of the solution vector. [out] IRev = 0: The obtained solution vector.
  IRev = 3: Recent approximation of the solution vector.
[out]Fvec()Array Fvec(LFvec - 1) (LFvec >= M)
IRev = 0: The function values evaluated at the solution vector X().
IRev = 3: The function values evaluated at the recent approximation of the solution vector.
[out]Fjac()Array Fjac(LFjac1 - 1, LFjac2 - 1) (LFjac1 >= M, LFjac2 >= N)
The upper N x N submatrix contains an upper triangular matrix R with diagonal elements of nonincreasing magnitude such that
  P^T * (J^T * J)*P = R^T * R
where P is a permutation matrix and J is the final calculated Jacobian.
[in]FTolRelative error desired in the sum of squares. Termination occurs when both the actual and predicted relative reductions in the sum of squares are at most FTol. (FTol >= 0)
[in]XTolRelative error desired in the approximate solution. Termination occurs when the relative error between two consecutive iterates is at most XTol. (XTol >= 0)
[in]GTolOrthogonality desired between the function vector and the columns of the Jacobian. Termination occurs when the cosine of the angle between Fvec() and any column of the jacobian is at most GTol in absolute value. (GTol >= 0)
[in,out]Diag()Array Diag(LD - 1) (LD >= N)
[in] If mode = 2, Diag must contain positive entries that serve as multiplicative scale factors for the variables. (Diag(i) > 0)
[out] If Mode = 1, Diag() is set by the subroutine.
[in]Mode= 1: The variables will be automatically scaled by the subroutine.
= 2: The scaling is specified by the input Diag().
(For other values, Mode = 1 is assumed.)
[out]Ipvt()Array Ipvt(LIpvt - 1) (LIpvt >= N)
The pivot indices that define the permutation matrix P.
[out]Info= 0: Successful exit. (Sub-code is set to Info2)
= -1: The argument M had an illegal value. (M < N)
= -2: The argument N had an illegal value. (N <= 0)
= -3: The argument X() is invalid. (Array X() is not big enough)
= -4: The argument Fvec() is invalid. (Array Fvec() is not big enough)
= -5: The argument Fjac() is invalid. (Array Fjac() is not big enough)
= -6: The argument FTol had an illegal value. (FTol < 0)
= -7: The argument XTol had an illegal value. (XTol < 0)
= -8: The argument GTol had an illegal value. (GTol < 0)
= -9: The argument Diag() is invalid. (Array Diag() is not big enough) or had an illegal value (Diag(i) < 0 when Mode = 2)
= -11: The argument Ipiv() is invalid. (Array Ipiv() is not big enough)
= -13: The argument XX() is invalid. (Array XX() is not big enough)
= -14: The argument YY() is invalid. (Array YY() is not big enough)
= 1: Number of function evaluations with IRev = 1 has reached Maxfev.
= 2: FTol is too small. No further reduction in the sum of squares is possible.
= 3: XTol is too small. No further improvement in the approximate solution X is possible.
= 4: GTol is too small. Fvec is orthogonal to the columns of the Jacobian to machine precision.
[out]XX()Array XX(LXX - 1) (LXX >= N)
When returned with IRev = 1, XX() contains the abscissa where the function value should be evaluated and given in the next call.
[in]YY()Array YY(LYY - 1) (LYY >= M)
When returned with IRev = 1, the function value fi(XX())(i = 1 to M) should be given in YY() in the next call.
[in,out]IRevControl variable for reverse communication.
[in] Before first call, IRev should be initialized to zero. On succeeding calls, IRev should not be altered.
[out] If IRev is not zero, set the required values to the specified variables or display the intermediate result as follows and call the routine again.
= 0: Computation finished. See return code in Info.
= 1 or 2: User should set the function values at XX() in YY(). Do not alter any variables other than YY().
= 3: Display the intermediate result (X(), Fvec(), etc.) (in the case of Nprint > 0). Do not alter any variables.
[out]Info2(Optional)
Sub-code on return with Info = 0.
= 1: Both actual and predicted relative reductions in the sum of squares are at most FTol.
= 2: Relative error between two consecutive iterates is at most XTol.
= 3: Both of above are satisfied.
= 4: The cosine of the angle between Fvec and any column of the Jacobian is at most GTol in absolute value.
[in]Maxfev(Optional)
Termination occurs when the number of function evaluations (IRev = 1) has reached this value. (default = 200*(N + 1))
(if Maxfev <= 0, the default value will be used.)
[in]Epsfcn(Optional)
Used in determining a suitable step length 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 precision, it is assumed that the relative errors in the functions are of the order of the machine precision. (default = 0)
[in]Factor(Optional)
Used in determining the initial 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 (0.1, 100). 100 is a generally recommended value. (default = 100)
(if Factor <= 0, the default value will be used)
[in]Nprint(Optional)
> 0: Returns with IRev = 3 at the beginning of the first iteration and every Nprint iterations thereafter and at the end of last iteration for printing intermediate result.
<= 0: Does not return for printing intermediate result.
(default = 0)
[out]Nfev(Optional)
Number of function evaluations with IRev = 1.
Reference
netlib/minpack
Example Program
Approximate the following data with model function f(x) = c1*(1 - exp(-c2*x)). Two parameters c1 and c2 are determined by the nonlinear least squares method.
f(x) x
10.07 77.6
29.61 239.9
50.76 434.8
81.78 760.0
The initial estimates of the solution are c1 = 500 and c2 = 0.0001.
Sub FLmdif(M As Long, N As Long, X() As Double, Fvec() As Double, IFlag As Long)
Dim Xdata(3) As Double, Ydata(3) As Double, I As Long
Ydata(0) = 10.07: Xdata(0) = 77.6
Ydata(1) = 29.61: Xdata(1) = 239.9
Ydata(2) = 50.76: Xdata(2) = 434.8
Ydata(3) = 81.78: Xdata(3) = 760
If IFlag = 1 Or IFlag = 2 Then
For I = 0 To M - 1
Fvec(I) = Ydata(I) - X(0) * (1 - Exp(-Xdata(I) * X(1)))
Next
End If
End Sub
Sub Ex_Lmdif_r()
Const M = 4, N = 2
Dim X(N - 1) As Double, Fvec(M - 1) As Double, Fjac(M - 1, N - 1) As Double
Dim FTol As Double, XTol As Double, GTol As Double, Diag(N - 1) As Double
Dim Mode As Long, Ipvt(N - 1) As Long, Info As Long
Dim XX(N - 1) As Double, YY(M - 1) As Double, IRev As Long, IFlag As Long
FTol = 0.00000001: XTol = 0.00000001: GTol = 0.00000001 '1.0e-8
X(0) = 500: X(1) = 0.0001
IRev = 0
Do
Call Lmdif_r(M, N, X(), Fvec(), Fjac(), FTol, XTol, GTol, Diag(), Mode, Ipvt(), Info, XX(), YY(), IRev)
If IRev = 1 Or IRev = 2 Then
IFlag = IRev
Call FLmdif(M, N, XX(), YY(), IFlag)
End If
Loop While IRev <> 0
Debug.Print "C1, C2 =", X(0), X(1)
Debug.Print "Info =", Info
End Sub
Example Results
C1, C2 = 241.084897132837 5.44942231312974E-04
Info = 0