fixed crashes in AbstractEstimator when some parameters are bound.

getCovariances() and guessParametersErrors() now only give result
about unbound parameters
JIRA: MATH-200

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@642357 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2008-03-28 20:06:54 +00:00
parent b736c8bda6
commit 2c443ab8b0
3 changed files with 48 additions and 5 deletions

View File

@ -149,7 +149,7 @@ public abstract class AbstractEstimator implements Estimator {
}
/**
* Get the covariance matrix of estimated parameters.
* Get the covariance matrix of unbound estimated parameters.
* @param problem estimation problem
* @return covariance matrix
* @exception EstimationException if the covariance matrix
@ -163,7 +163,7 @@ public abstract class AbstractEstimator implements Estimator {
// compute transpose(J).J, avoiding building big intermediate matrices
final int rows = problem.getMeasurements().length;
final int cols = problem.getAllParameters().length;
final int cols = problem.getUnboundParameters().length;
final int max = cols * rows;
double[][] jTj = new double[cols][cols];
for (int i = 0; i < cols; ++i) {
@ -188,7 +188,7 @@ public abstract class AbstractEstimator implements Estimator {
}
/**
* Guess the errors in estimated parameters.
* Guess the errors in unbound estimated parameters.
* <p>Guessing is covariance-based, it only gives rough order of magnitude.</p>
* @param problem estimation problem
* @return errors in estimated parameters
@ -199,12 +199,12 @@ public abstract class AbstractEstimator implements Estimator {
public double[] guessParametersErrors(EstimationProblem problem)
throws EstimationException {
int m = problem.getMeasurements().length;
int p = problem.getAllParameters().length;
int p = problem.getUnboundParameters().length;
if (m <= p) {
throw new EstimationException("no degrees of freedom ({0} measurements, {1} parameters)",
new Object[] { new Integer(m), new Integer(p)});
}
double[] errors = new double[problem.getAllParameters().length];
double[] errors = new double[problem.getUnboundParameters().length];
final double c = Math.sqrt(getChiSquare(problem) / (m - p));
double[][] covar = getCovariances(problem);
for (int i = 0; i < errors.length; ++i) {

View File

@ -51,6 +51,11 @@ Commons Math Release Notes</title>
detect numerical problems in Q.R decomposition for Levenberg-Marquardt estimator
and report them appropriately
</action>
<action dev="luc" type="fix" issue="MATH-200" due-to="Plamen Petrov">
fixed several crashes in getCovariances() and guessParametersErrors() in
AbstractEstimator when some parameters are bound. The methods now explicitly
give result only about unbound parameters.
</action>
</release>
<release version="1.2" date="2008-02-24"
description="This release combines bug fixes and new features. Most notable

View File

@ -448,6 +448,44 @@ public class GaussNewtonEstimatorTest
}
public void testBoundParameters() throws EstimationException {
EstimatedParameter[] p = {
new EstimatedParameter("unbound0", 2, false),
new EstimatedParameter("unbound1", 2, false),
new EstimatedParameter("bound", 2, true)
};
LinearProblem problem = new LinearProblem(new LinearMeasurement[] {
new LinearMeasurement(new double[] { 1.0, 1.0, 1.0 },
new EstimatedParameter[] { p[0], p[1], p[2] },
3.0),
new LinearMeasurement(new double[] { 1.0, -1.0, 1.0 },
new EstimatedParameter[] { p[0], p[1], p[2] },
1.0),
new LinearMeasurement(new double[] { 1.0, 3.0, 2.0 },
new EstimatedParameter[] { p[0], p[1], p[2] },
7.0)
});
GaussNewtonEstimator estimator = new GaussNewtonEstimator(100, 1.0e-6, 1.0e-6);
estimator.estimate(problem);
assertTrue(estimator.getRMS(problem) < 1.0e-10);
double[][] covariances = estimator.getCovariances(problem);
int i0 = 0, i1 = 1;
if (problem.getUnboundParameters()[0].getName().endsWith("1")) {
i0 = 1;
i1 = 0;
}
assertEquals(11.0 / 24, covariances[i0][i0], 1.0e-10);
assertEquals(-3.0 / 24, covariances[i0][i1], 1.0e-10);
assertEquals(-3.0 / 24, covariances[i1][i0], 1.0e-10);
assertEquals( 3.0 / 24, covariances[i1][i1], 1.0e-10);
double[] errors = estimator.guessParametersErrors(problem);
assertEquals(0, errors[i0], 1.0e-10);
assertEquals(0, errors[i1], 1.0e-10);
}
public void testMaxIterations() {
Circle circle = new Circle(98.680, 47.345);
circle.addPoint( 30.0, 68.0);