IshmaelLocator
Class LM

java.lang.Object
  extended by IshmaelLocator.LM
Direct Known Subclasses:
IshLocHyperbProcess.TimeDiff_LM

public abstract class LM
extends java.lang.Object

LM: The Levenberg-Marquardt algorithm for least-squares minimization

The purpose of LM is to minimize the sum of the squares of m nonlinear functions (dependent variables) in n independent variables by a modification of the Levenberg-Marquardt algorithm. The user must provide a function which calculates the functions and, optionally, a function (jacFcn) to calculate the Jacobian. If useJac is false, the Jacobian is calculated by a forward-difference approximation; this is significantly slower, so define jacFcn if possible.

To use LM, make a subclass of it that defines fcn and, if desired, jacFcn. You can also declare other class variables to be used in calculating fcn and jacFcn. Create an instance of it (initializing your class vars as needed), then call calc(). Alternatively, you can call calc_simple(), which makes reasonable guesses for many of the inputs to calc. The first argument to these, useJac, indicates whether you've defined a jacFcn. After it returns, examine the output variables LM.info, LM.x, and any other output variables you like.

The calling statement is

calc(useJac, m,n,x,fvec,ftol,xtol,gtol,maxfev,epsfcn,diag,mode,factor, nprint)

or

calc_simple(useJac, m, n, tol, x[])

where

fcn (in subclass) is the name of the user-supplied function which calculates the functions. fcn should be written as follows:

boolean fcn(double x[], double y[], boolean printFlag) { //Calculate the functions at x and place this result //vector in y. Return true to continue, false to stop. }

fcn should calculate y = fcn(x), where x is a vector of length n and y is a vector of length m. printFlag indicates whether this call is being made for debug printing purposes only. fcn should return true if processing should continue, false to stop the Levenberg-Marquardt iteration.

jacFcn If calc() is called with useJac true, then jacFcn gets called to calculate the Jacobian. Its arguments are the same as fcn, except that output vector y is replaced with output matrix jac, a matrix of size m x n. Your Jacobian function should place the result in jac, and return true to continue the processing or false to stop it.

If useJac is false, then the Jacobian is estimated by the (slower) forward-difference method.

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 (input and output) 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.

ftol is a nonnegative 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.

xtol is a nonnegative 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.

gtol is a nonnegative 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.

maxfev is a positive integer input variable. Termination occurs when the number of calls to fcn is at least maxfev by the end of an iteration.

epsfcn is an input variable used in determining a suitable step length for the forward-difference approximation. If haveJac is true, epsfcn is ignored. 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.

diag is an input array of length n. If mode = 1 (see below), diag is internally set. If mode = 2, diag must contain positive entries that serve as 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 specified by the input diag. Other values of mode are equivalent to mode = 1.

factor is a positive input variable 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 (.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 printFlag = true at the beginning of the first iteration and every nprint iterations thereafter and immediately prior to return, with x and fvec available for printing. If nprint is not positive, no special calls of fcn with printFlag = true are made.

Output variables: info is an integer output variable specifying why calc() returned:

info = -1 User function terminated execution by returning false. See description of fcn above.

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 has reached or exceeded 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.

info = 9 Out of memory. Doesn't happen in the Java version, since an exceptino gets thrown.

nfev is an integer output variable set to the number of non-printing function calls, i.e., calls to fcn with printFlag=false.

njev is an integer output variable set to the number of Jacobians calculated, i.e., calls to jacFcn.

fjac is an output m 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 calculated Jacobian. Column j of p is column ipvt(j) (see below) of the identity matrix. The lower trapezoidal part of fjac contains information generated during the computation of r.

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.

Functions called:

user-supplied ............. fcn, optionally jacFcn

minpack-supplied (below)... enorm,fdjac2,lmpar,qrfac

Argonne National Laboratory. Minpack Project. March 1980. Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More


Field Summary
(package private) static double DWARF
           
(package private)  double[][] fjac
           
(package private)  double[] fvec
           
(package private)  int iflag
           
(package private)  int info
           
(package private)  int[] ipvt
           
(package private) static double MACHEP
           
(package private)  int nfev
           
(package private)  int njev
           
(package private)  double[] qtf
           
(package private) static double rdwarf
           
(package private) static double rgiant
           
(package private)  double[] x
           
 
Constructor Summary
LM()
           
 
Method Summary
 void calc_simple(boolean useJac, int m, int n, double tol, double[] x)
          Run the Levenberg-Marquardt method using reasonable guesses for many of the input parameters.
 void calc(boolean useJac, int m, int n, double[] x, double ftol, double xtol, double gtol, int maxfev, double epsfcn, double[] diag, int mode, double factor, int nprint)
          See the long comment for the LM class for details.
(package private)  double col_enorm(int n, double[][] x, int i0, int j)
           
(package private)  double enorm(int n, double[] x)
           
(package private) abstract  boolean fcn(double[] x, double[] y, boolean printFlag)
           
(package private)  void fdjac2(int m, int n, double[] x, double[] fvec, double epsfcn, double[] wa)
           
(package private)  boolean jacFcn(double[] x, double[][] jac, boolean printFlag)
           
(package private)  double lmpar(int n, double[][] r, int ldr, int[] ipvt, double[] diag, double[] qtb, double delta, double[] x, double[] sdiag, double[] wa1, double[] wa2)
           
(package private)  void qrfac(int m, int n, double[][] a, int lda, int pivot, int[] ipvt, int lipvt, double[] rdiag, double[] acnorm, double[] wa)
           
(package private)  void qrsolv(int n, double[][] r, int ldr, int[] ipvt, double[] diag, double[] qtb, double[] x, double[] sdiag, double[] wa)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

info

int info

x

double[] x

fvec

double[] fvec

nfev

int nfev

njev

int njev

ipvt

int[] ipvt

fjac

double[][] fjac

qtf

double[] qtf

iflag

int iflag

DWARF

static final double DWARF
See Also:
Constant Field Values

MACHEP

static final double MACHEP
See Also:
Constant Field Values

rdwarf

static final double rdwarf
See Also:
Constant Field Values

rgiant

static final double rgiant
See Also:
Constant Field Values
Constructor Detail

LM

public LM()
Method Detail

fcn

abstract boolean fcn(double[] x,
                     double[] y,
                     boolean printFlag)

jacFcn

boolean jacFcn(double[] x,
               double[][] jac,
               boolean printFlag)

calc_simple

public void calc_simple(boolean useJac,
                        int m,
                        int n,
                        double tol,
                        double[] x)
Run the Levenberg-Marquardt method using reasonable guesses for many of the input parameters.

see See the comment for the class LM for inputs and outputs.


calc

public void calc(boolean useJac,
                 int m,
                 int n,
                 double[] x,
                 double ftol,
                 double xtol,
                 double gtol,
                 int maxfev,
                 double epsfcn,
                 double[] diag,
                 int mode,
                 double factor,
                 int nprint)
See the long comment for the LM class for details.


lmpar

double lmpar(int n,
             double[][] r,
             int ldr,
             int[] ipvt,
             double[] diag,
             double[] qtb,
             double delta,
             double[] x,
             double[] sdiag,
             double[] wa1,
             double[] wa2)

qrfac

void qrfac(int m,
           int n,
           double[][] a,
           int lda,
           int pivot,
           int[] ipvt,
           int lipvt,
           double[] rdiag,
           double[] acnorm,
           double[] wa)

qrsolv

void qrsolv(int n,
            double[][] r,
            int ldr,
            int[] ipvt,
            double[] diag,
            double[] qtb,
            double[] x,
            double[] sdiag,
            double[] wa)

enorm

double enorm(int n,
             double[] x)

col_enorm

double col_enorm(int n,
                 double[][] x,
                 int i0,
                 int j)

fdjac2

void fdjac2(int m,
            int n,
            double[] x,
            double[] fvec,
            double epsfcn,
            double[] wa)