Added a setQRRankingThreshold method to Levenberg-Marquardt optimizer to improve robustness of rank determination.

JIRA: MATH-352

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@951864 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2010-06-06 14:01:51 +00:00
parent 9fdb084383
commit 6f54422e96
3 changed files with 36 additions and 11 deletions

View File

@ -21,6 +21,7 @@ import java.util.Arrays;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.optimization.OptimizationException;
import org.apache.commons.math.optimization.VectorialPointValuePair;
import org.apache.commons.math.util.MathUtils;
/**
@ -140,16 +141,20 @@ public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer {
* and the columns of the jacobian. */
private double orthoTolerance;
/** Threshold for QR ranking. */
private double qrRankingThreshold;
/**
* Build an optimizer for least squares problems.
* <p>The default values for the algorithm settings are:
* <ul>
* <li>{@link #setConvergenceChecker vectorial convergence checker}: null</li>
* <li>{@link #setInitialStepBoundFactor initial step bound factor}: 100.0</li>
* <li>{@link #setMaxIterations maximal iterations}: 1000</li>
* <li>{@link #setCostRelativeTolerance cost relative tolerance}: 1.0e-10</li>
* <li>{@link #setParRelativeTolerance parameters relative tolerance}: 1.0e-10</li>
* <li>{@link #setOrthoTolerance orthogonality tolerance}: 1.0e-10</li>
* <li>{@link #setConvergenceChecker(VectorialConvergenceChecker) vectorial convergence checker}: null</li>
* <li>{@link #setInitialStepBoundFactor(double) initial step bound factor}: 100.0</li>
* <li>{@link #setMaxIterations(int) maximal iterations}: 1000</li>
* <li>{@link #setCostRelativeTolerance(double) cost relative tolerance}: 1.0e-10</li>
* <li>{@link #setParRelativeTolerance(double) parameters relative tolerance}: 1.0e-10</li>
* <li>{@link #setOrthoTolerance(double) orthogonality tolerance}: 1.0e-10</li>
* <li>{@link #setQRRankingThreshold(double) QR ranking threshold}: {@link MathUtils#SAFE_MIN}</li>
* </ul>
* </p>
* <p>These default values may be overridden after construction. If the {@link
@ -168,6 +173,7 @@ public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer {
setCostRelativeTolerance(1.0e-10);
setParRelativeTolerance(1.0e-10);
setOrthoTolerance(1.0e-10);
setQRRankingThreshold(MathUtils.SAFE_MIN);
}
@ -216,6 +222,19 @@ public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer {
this.orthoTolerance = orthoTolerance;
}
/**
* Set the desired threshold for QR ranking.
* <p>
* If the squared norm of a column vector is smaller or equal to this threshold
* during QR decomposition, it is considered to be a zero vector and hence the
* rank of the matrix is reduced.
* </p>
* @param qrRankingThreshold threshold for QR ranking
*/
public void setQRRankingThreshold(final double qrRankingThreshold) {
this.qrRankingThreshold = qrRankingThreshold;
}
/** {@inheritDoc} */
@Override
protected VectorialPointValuePair doOptimize()
@ -805,7 +824,7 @@ public class LevenbergMarquardtOptimizer extends AbstractLeastSquaresOptimizer {
ak2 = norm2;
}
}
if (ak2 == 0) {
if (ak2 <= qrRankingThreshold) {
rank = k;
return;
}

View File

@ -52,6 +52,10 @@ The <action> type attribute can be add,update,fix,remove.
If the output is not quite correct, check for invisible trailing spaces!
-->
<release version="2.2" date="TBD" description="TBD">
<action dev="luc" type="fix" issue="MATH-352" >
Added a setQRRankingThreshold method to Levenberg-Marquardt optimizer to improve robustness
of rank determination.
</action>
<action dev="psteitz" type="update" issue="MATH-310">
Added random data generation methods to RandomDataImpl for the remaining distributions in the
distributions package. Added a generic nextInversionDeviate method that takes a discrete

View File

@ -505,7 +505,9 @@ public class LevenbergMarquardtOptimizerTest
problem.addPoint (2, -2.1488478161387325);
problem.addPoint (3, -1.9122489313410047);
problem.addPoint (4, 1.7785661310051026);
new LevenbergMarquardtOptimizer().optimize(problem,
LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer();
optimizer.setQRRankingThreshold(0);
optimizer.optimize(problem,
new double[] { 0, 0, 0, 0, 0 },
new double[] { 0.0, 4.4e-323, 1.0, 4.4e-323, 0.0 },
new double[] { 0, 0, 0 });