Javadoc formatting and minor edits.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@542048 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2007-05-27 23:02:13 +00:00
parent 11d16247b4
commit ed2a644830
7 changed files with 156 additions and 91 deletions

View File

@ -19,16 +19,16 @@ package org.apache.commons.math.estimation;
import java.io.Serializable;
/** This class represent the estimated parameters of an estimation problem.
/** This class represents the estimated parameters of an estimation problem.
*
* <p>The parameters of an estimation problem have a name, a value and
* a bound flag. The value of bound parameters is considered trusted
* and the solvers should not adjust them. On the other hand, the
* solvers should adjust the value of unbounds parameters until they
* satisfy convergence criterions specific to each solver.</p>
*
* @version $Id: EstimatedParameter.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public class EstimatedParameter

View File

@ -19,10 +19,11 @@ package org.apache.commons.math.estimation;
import org.apache.commons.math.MathException;
/** This class represents exceptions thrown by the estimation solvers.
/**
* This class represents exceptions thrown by the estimation solvers.
*
* @version $Id: EstimationException.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public class EstimationException
@ -31,7 +32,8 @@ extends MathException {
/** Serializable version identifier. */
private static final long serialVersionUID = -7414806622114810487L;
/** Simple constructor.
/**
* Simple constructor.
* Build an exception by translating and formating a message
* @param specifier format specifier (to be translated)
* @param parts to insert in the format (no translation)
@ -40,7 +42,8 @@ extends MathException {
super(specifier, parts);
}
/** Simple constructor.
/**
* Simple constructor.
* Build an exception from a cause
* @param cause cause of this exception
*/

View File

@ -17,12 +17,13 @@
package org.apache.commons.math.estimation;
/** This interface represents an estimation problem.
/**
* This interface represents an estimation problem.
*
* <p>This interface should be implemented by all real estimation
* problems before they can be handled by the estimators through the
* {@link Estimator#estimate Estimator.estimate} method.</p>
*
* <p>An estimation problem, as seen by a solver is a set of
* parameters and a set of measurements. The parameters are adjusted
* during the estimation through the {@link #getUnboundParameters
@ -33,26 +34,29 @@ package org.apache.commons.math.estimation;
* the parameters are adjusted. The purpose of the solver is to reduce
* the residual between these values, it can retrieve the measurements
* through the {@link #getMeasurements getMeasurements} method.</p>
*
* @see Estimator
* @see WeightedMeasurement
*
* @version $Id: EstimationProblem.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public interface EstimationProblem {
/** Get the measurements of an estimation problem.
/**
* Get the measurements of an estimation problem.
* @return measurements
*/
public WeightedMeasurement[] getMeasurements();
/** Get the unbound parameters of the problem.
/**
* Get the unbound parameters of the problem.
* @return unbound parameters
*/
public EstimatedParameter[] getUnboundParameters();
/** Get all the parameters of the problem.
/**
* Get all the parameters of the problem.
* @return parameters
*/
public EstimatedParameter[] getAllParameters();

View File

@ -17,46 +17,50 @@
package org.apache.commons.math.estimation;
/** This interface represents solvers for estimation problems.
/**
* This interface represents solvers for estimation problems.
*
* <p>The classes which are devoted to solve estimation problems
* should implement this interface. The problems which can be handled
* should implement the {@link EstimationProblem} interface which
* gather all the information needed by the solver.</p>
*
* <p>The interface is composed only of the {@link #estimate estimate}
* method.</p>
*
* @see EstimationProblem
*
* @version $Id: Estimator.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public interface Estimator {
/** Solve an estimation problem.
/**
* Solve an estimation problem.
*
* <p>The method should set the parameters of the problem to several
* trial values until it reaches convergence. If this method returns
* normally (i.e. without throwing an exception), then the best
* estimate of the parameters can be retrieved from the problem
* itself, through the {@link EstimationProblem#getAllParameters
* EstimationProblem.getAllParameters} method.</p>
*
* @param problem estimation problem to solve
* @exception EstimationException if the problem cannot be solved
*
*/
public void estimate(EstimationProblem problem)
throws EstimationException;
/** Get the Root Mean Square value.
/**
* Get the Root Mean Square value.
* Get the Root Mean Square value, i.e. the root of the arithmetic
* mean of the square of all weighted residuals. This is related to the
* criterion that is minimized by the estimator as follows: if
* <em>c</em> if the criterion, and <em>n</em> is the number of
* measurements, the the RMS is <em>sqrt (c/n)</em>.
* <em>c</em> is the criterion, and <em>n</em> is the number of
* measurements, then the RMS is <em>sqrt (c/n)</em>.
*
* @param problem estimation problem
* @return RMS value
*/

View File

@ -23,39 +23,41 @@ import org.apache.commons.math.linear.InvalidMatrixException;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.linear.RealMatrixImpl;
/** This class implements a solver for estimation problems.
/**
* This class implements a solver for estimation problems.
*
* <p>This class solves estimation problems using a weighted least
* squares criterion on the measurement residuals. It uses a
* Gauss-Newton algorithm.</p>
*
* @version $Id: GaussNewtonEstimator.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public class GaussNewtonEstimator
implements Estimator, Serializable {
/** Simple constructor.
* <p>This constructor build an estimator and store its convergence
/**
* Simple constructor.
*
* <p>This constructor builds an estimator and stores its convergence
* characteristics.</p>
*
* <p>An estimator is considered to have converged whenever either
* the criterion goes below a physical threshold under which
* improvements are considered useless or when the algorithm is
* unable to improve it (even if it is still high). The first
* condition that is met stops the iterations.</p>
*
* <p>The fact an estimator has converged does not mean that the
* model accurately fits the measurements. It only means no better
* solution can be found, it does not mean this one is good. Such an
* analysis is left to the caller.</p>
*
* <p>If neither conditions are fulfilled before a given number of
* iterations, the algorithm is considered to have failed and an
* {@link EstimationException} is thrown.</p>
*
* @param maxIterations maximum number of iterations allowed
* @param convergence criterion threshold below which we do not need
* to improve the criterion anymore
@ -74,14 +76,15 @@ public class GaussNewtonEstimator
this.convergence = convergence;
}
/** Solve an estimation problem using a least squares criterion.
/**
* Solve an estimation problem using a least squares criterion.
*
* <p>This method set the unbound parameters of the given problem
* starting from their current values through several iterations. At
* each step, the unbound parameters are changed in order to
* minimize a weighted least square criterion based on the
* measurements of the problem.</p>
*
* <p>The iterations are stopped either when the criterion goes
* below a physical threshold under which improvement are considered
* useless or when the algorithm is unable to improve it (even if it
@ -89,12 +92,12 @@ public class GaussNewtonEstimator
* iterations. If the convergence it nos reached before the maximum
* number of iterations, an {@link EstimationException} is
* thrown.</p>
*
* @param problem estimation problem to solve
* @exception EstimationException if the problem cannot be solved
*
* @see EstimationProblem
*
*/
public void estimate(EstimationProblem problem)
throws EstimationException {
@ -124,20 +127,21 @@ public class GaussNewtonEstimator
}
/** Estimate the solution of a linear least square problem.
/**
* Estimate the solution of a linear least square problem.
*
* <p>The Gauss-Newton algorithm is iterative. Each iteration
* consist in solving a linearized least square problem. Several
* consists in solving a linearized least square problem. Several
* iterations are needed for general problems since the
* linearization is only an approximation of the problem
* behaviour. However, for linear problems one iteration is enough
* to get the solution. This method is provided in the public
* interface in order to handle more efficiently these linear
* problems.</p>
*
* @param problem estimation problem to solve
* @exception EstimationException if the problem cannot be solved
*
*/
public void linearEstimate(EstimationProblem problem)
throws EstimationException {
@ -210,7 +214,8 @@ public class GaussNewtonEstimator
}
/** Get the Root Mean Square value.
/**
* Get the Root Mean Square value.
* Get the Root Mean Square value, i.e. the root of the arithmetic
* mean of the square of all weighted residuals. This is related to the
* criterion that is minimized by the estimator as follows: if

View File

@ -19,15 +19,16 @@ package org.apache.commons.math.estimation;
import java.io.Serializable;
import java.util.Arrays;
/** This class solves a least squares problem.
/**
* This class solves a least squares problem.
*
* <p>This implementation <em>should</em> work even for over-determined systems
* (i.e. systems having more variables than equations). Over-determined systems
* are solved by ignoring the variables which have the smallest impact according
* to their jacobian column norm. Only the rank of the matrix and some loop bounds
* are changed to implement this. This feature has undergone only basic testing
* for now and should still be considered experimental.</p>
*
* <p>The resolution engine is a simple translation of the MINPACK <a
* href="http://www.netlib.org/minpack/lmder.f">lmder</a> routine with minor
* changes. The changes include the over-determined resolution and the Q.R.
@ -37,7 +38,7 @@ import java.util.Arrays;
* redistribution policy for MINPACK is available <a
* href="http://www.netlib.org/minpack/disclaimer">here</a>, for convenience, it
* is reproduced below.</p>
*
* <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
* <tr><td>
* Minpack Copyright Notice (1999) University of Chicago.
@ -93,7 +94,8 @@ import java.util.Arrays;
*/
public class LevenbergMarquardtEstimator implements Serializable, Estimator {
/** Build an estimator for least squares problems.
/**
* Build an estimator for least squares problems.
* <p>The default values for the algorithm settings are:
* <ul>
* <li>{@link #setInitialStepBoundFactor initial step bound factor}: 100.0</li>
@ -113,10 +115,12 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
setOrthoTolerance(1.0e-10);
}
/** Set the positive input variable used in determining the initial step bound.
/**
* Set the positive input variable used in determining the initial step bound.
* This bound is set to the product of initialStepBoundFactor and the euclidean norm of diag*x if nonzero,
* or else to initialStepBoundFactor itself. In most cases factor should lie
* in the interval (0.1, 100.0). 100.0 is a generally recommended value
*
* @param initialStepBoundFactor initial step bound factor
* @see #estimate
*/
@ -124,15 +128,19 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
this.initialStepBoundFactor = initialStepBoundFactor;
}
/** Set the maximal number of cost evaluations.
* @param maxCostEval maximal number of cost evaluations
/**
* Set the maximal number of cost evaluations.
*
* @param maxCostEval maximal number of cost evaluations
* @see #estimate
*/
public void setMaxCostEval(int maxCostEval) {
this.maxCostEval = maxCostEval;
}
/** Set the desired relative error in the sum of squares.
/**
* Set the desired relative error in the sum of squares.
*
* @param costRelativeTolerance desired relative error in the sum of squares
* @see #estimate
*/
@ -140,7 +148,9 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
this.costRelativeTolerance = costRelativeTolerance;
}
/** Set the desired relative error in the approximate solution parameters.
/**
* Set the desired relative error in the approximate solution parameters.
*
* @param parRelativeTolerance desired relative error
* in the approximate solution parameters
* @see #estimate
@ -149,7 +159,9 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
this.parRelativeTolerance = parRelativeTolerance;
}
/** Set the desired max cosine on the orthogonality.
/**
* Set the desired max cosine on the orthogonality.
*
* @param orthoTolerance desired max cosine on the orthogonality
* between the function vector and the columns of the jacobian
* @see #estimate
@ -158,21 +170,26 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
this.orthoTolerance = orthoTolerance;
}
/** Get the number of cost evaluations.
/**
* Get the number of cost evaluations.
*
* @return number of cost evaluations
* */
public int getCostEvaluations() {
return costEvaluations;
}
/** Get the number of jacobian evaluations.
/**
* Get the number of jacobian evaluations.
*
* @return number of jacobian evaluations
* */
public int getJacobianEvaluations() {
return jacobianEvaluations;
}
/** Update the jacobian matrix.
/**
* Update the jacobian matrix.
*/
private void updateJacobian() {
++jacobianEvaluations;
@ -186,7 +203,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
}
}
/** Update the residuals array and cost function value.
/**
* Update the residuals array and cost function value.
*/
private void updateResidualsAndCost() {
++costEvaluations;
@ -200,12 +218,14 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
cost = Math.sqrt(cost);
}
/** Get the Root Mean Square value.
/**
* Get the Root Mean Square value.
* Get the Root Mean Square value, i.e. the root of the arithmetic
* mean of the square of all weighted residuals. This is related to the
* criterion that is minimized by the estimator as follows: if
* <em>c</em> if the criterion, and <em>n</em> is the number of
* measurements, then the RMS is <em>sqrt (c/n)</em>.
*
* @param problem estimation problem
* @return RMS value
*/
@ -219,7 +239,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
return Math.sqrt(criterion / wm.length);
}
/** Solve an estimation problem using the Levenberg-Marquardt algorithm.
/**
* Solve an estimation problem using the Levenberg-Marquardt algorithm.
* <p>The algorithm used is a modified Levenberg-Marquardt one, based
* on the MINPACK <a href="http://www.netlib.org/minpack/lmder.f">lmder</a>
* routine. The algorithm settings must have been set up before this method
@ -236,6 +257,7 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
* <li>Jorge J. More</li>
* </ul>
* <p>Luc Maisonobe did the Java translation.</p>
*
* @param problem estimation problem to solve
* @exception EstimationException if convergence cannot be
* reached with the specified algorithm settings or if there are more variables
@ -493,7 +515,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
}
/** Determine the Levenberg-Marquardt parameter.
/**
* Determine the Levenberg-Marquardt parameter.
* <p>This implementation is a translation in Java of the MINPACK
* <a href="http://www.netlib.org/minpack/lmpar.f">lmpar</a>
* routine.</p>
@ -506,6 +529,7 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
* <li>Jorge J. More</li>
* </ul>
* <p>Luc Maisonobe did the Java translation.</p>
*
* @param qy array containing qTy
* @param delta upper bound on the euclidean norm of diagR * lmDir
* @param diag diagonal matrix
@ -661,7 +685,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
}
}
/** Solve a*x = b and d*x = 0 in the least squares sense.
/**
* Solve a*x = b and d*x = 0 in the least squares sense.
* <p>This implementation is a translation in Java of the MINPACK
* <a href="http://www.netlib.org/minpack/qrsolv.f">qrsolv</a>
* routine.</p>
@ -674,6 +699,7 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
* <li>Jorge J. More</li>
* </ul>
* <p>Luc Maisonobe did the Java translation.</p>
*
* @param qy array containing qTy
* @param diag diagonal matrix
* @param lmDiag diagonal elements associated with lmDir
@ -783,7 +809,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
}
/** Decompose a matrix A as A.P = Q.R using Householder transforms.
/**
* Decompose a matrix A as A.P = Q.R using Householder transforms.
* <p>As suggested in the P. Lascaux and R. Theodor book
* <i>Analyse num&eacute;rique matricielle appliqu&eacute;e &agrave;
* l'art de l'ing&eacute;nieur</i> (Masson, 1986), instead of representing
@ -872,7 +899,9 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
}
/** Compute the product Qt.y for some Q.R. decomposition.
/**
* Compute the product Qt.y for some Q.R. decomposition.
*
* @param y vector to multiply (will be overwritten with the result)
*/
private void qTy(double[] y) {
@ -896,7 +925,8 @@ public class LevenbergMarquardtEstimator implements Serializable, Estimator {
/** Array of parameters. */
private EstimatedParameter[] parameters;
/** Jacobian matrix.
/**
* Jacobian matrix.
* <p>Depending on the computation phase, this matrix is either in
* canonical form (just after the calls to updateJacobian) or in
* Q.R. decomposed form (after calls to qrDecomposition)</p>

View File

@ -19,14 +19,15 @@ package org.apache.commons.math.estimation;
import java.io.Serializable;
/** This class represents measurements in estimation problems.
/**
* This class represents measurements in estimation problems.
*
* <p>This abstract class implements all the methods needed to handle
* measurements in a general way. It defines neither the {@link
* #getTheoreticalValue getTheoreticalValue} nor the {@link
* #getPartial getPartial} methods, which should be defined by
* sub-classes according to the specific problem.</p>
*
* <p>The {@link #getTheoreticalValue getTheoreticalValue} and {@link
* #getPartial getPartial} methods must always use the current
* estimate of the parameters set by the solver in the problem. These
@ -35,27 +36,29 @@ import java.io.Serializable;
* EstimationProblem.getAllParameters} method if the measurements are
* independant of the problem, or directly if they are implemented as
* inner classes of the problem.</p>
*
* <p>The instances for which the <code>ignored</code> flag is set
* through the {@link #setIgnored setIgnored} method are ignored by the
* solvers. This can be used to reject wrong measurements at some
* steps of the estimation.</p>
*
* @see EstimationProblem
*
* @version $Id: WeightedMeasurement.java 1705 2006-09-17 19:57:39Z luc $
*
*/
public abstract class WeightedMeasurement implements Serializable {
/** Simple constructor.
/**
* Simple constructor.
* Build a measurement with the given parameters, and set its ignore
* flag to false.
* @param weight weight of the measurement in the least squares problem
* (two common choices are either to use 1.0 for all measurements, or to
* use a value proportional to the inverse of the variance of the measurement
* type)
*
* @param measuredValue measured value
*/
public WeightedMeasurement(double weight, double measuredValue) {
@ -65,7 +68,9 @@ public abstract class WeightedMeasurement implements Serializable {
}
/** Simple constructor.
*
* Build a measurement with the given parameters
*
* @param weight weight of the measurement in the least squares problem
* @param measuredValue measured value
* @param ignored true if the measurement should be ignored
@ -77,41 +82,51 @@ public abstract class WeightedMeasurement implements Serializable {
this.ignored = ignored;
}
/** Get the weight of the measurement in the least squares problem
/**
* Get the weight of the measurement in the least squares problem
*
* @return weight
*/
public double getWeight() {
return weight;
}
/** Get the measured value
/**
* Get the measured value
*
* @return measured value
*/
public double getMeasuredValue() {
return measuredValue;
}
/** Get the residual for this measurement
/**
* Get the residual for this measurement
* The residual is the measured value minus the theoretical value.
*
* @return residual
*/
public double getResidual() {
return measuredValue - getTheoreticalValue();
}
/** Get the theoretical value expected for this measurement
/**
* Get the theoretical value expected for this measurement
* <p>The theoretical value is the value expected for this measurement
* if the model and its parameter were all perfectly known.</p>
* <p>The value must be computed using the current estimate of the parameters
* set by the solver in the problem.</p>
*
* @return theoretical value
*/
public abstract double getTheoreticalValue();
/** Get the partial derivative of the {@link #getTheoreticalValue
/**
* Get the partial derivative of the {@link #getTheoreticalValue
* theoretical value} according to the parameter.
* <p>The value must be computed using the current estimate of the parameters
* set by the solver in the problem.</p>
*
* @param parameter parameter against which the partial derivative
* should be computed
* @return partial derivative of the {@link #getTheoreticalValue
@ -119,16 +134,20 @@ public abstract class WeightedMeasurement implements Serializable {
*/
public abstract double getPartial(EstimatedParameter parameter);
/** Set the ignore flag to the specified value
/**
* Set the ignore flag to the specified value
* Setting the ignore flag to true allow to reject wrong
* measurements, which sometimes can be detected only rather late.
*
* @param ignored value for the ignore flag
*/
public void setIgnored(boolean ignored) {
this.ignored = ignored;
}
/** Check if this measurement should be ignored
/**
* Check if this measurement should be ignored
*
* @return true if the measurement should be ignored
*/
public boolean isIgnored() {