/** * Get the covariance matrix of unbound estimated parameters. * * @param problem estimation problem * @return covariance matrix * @exception EstimationException if the covariance matrix cannot be computed (singular problem) */ public double[][] getCovariances(EstimationProblem problem) throws EstimationException { // set up the jacobian updateJacobian(); // compute transpose(J).J, avoiding building big intermediate matrices final int n = problem.getMeasurements().length; final int m = problem.getUnboundParameters().length; final int max = m * n; double[][] jTj = new double[m][m]; for (int i = 0; i < m; ++i) { for (int j = i; j < m; ++j) { double sum = 0; for (int k = 0; k < max; k += m) { sum += jacobian[k + i] * jacobian[k + j]; } jTj[i][j] = sum; jTj[j][i] = sum; } } try { // compute the covariances matrix RealMatrix inverse = new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse(); return inverse.getData(); } catch (InvalidMatrixException ime) { throw new EstimationException("unable to compute covariances: singular problem"); } }
/** * Get the Chi-Square value. * * @param problem estimation problem * @return chi-square value */ public double getChiSquare(EstimationProblem problem) { WeightedMeasurement[] wm = problem.getMeasurements(); double chiSquare = 0; for (int i = 0; i < wm.length; ++i) { double residual = wm[i].getResidual(); chiSquare += residual * residual / wm[i].getWeight(); } return chiSquare; }
/** * 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 */ public double getRMS(EstimationProblem problem) { WeightedMeasurement[] wm = problem.getMeasurements(); double criterion = 0; for (int i = 0; i < wm.length; ++i) { double residual = wm[i].getResidual(); criterion += wm[i].getWeight() * residual * residual; } return Math.sqrt(criterion / wm.length); }
/** * Guess the errors in unbound estimated parameters. * * <p>Guessing is covariance-based, it only gives rough order of magnitude. * * @param problem estimation problem * @return errors in estimated parameters * @exception EstimationException if the covariances matrix cannot be computed or the number of * degrees of freedom is not positive (number of measurements lesser or equal to number of * parameters) */ public double[] guessParametersErrors(EstimationProblem problem) throws EstimationException { int m = problem.getMeasurements().length; int p = problem.getUnboundParameters().length; if (m <= p) { throw new EstimationException( "no degrees of freedom ({0} measurements, {1} parameters)", m, p); } 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) { errors[i] = Math.sqrt(covar[i][i]) * c; } return errors; }
/** * Initialization of the common parts of the estimation. * * <p>This method <em>must</em> be called at the start of the {@link #estimate(EstimationProblem) * estimate} method. * * @param problem estimation problem to solve */ protected void initializeEstimate(EstimationProblem problem) { // reset counters costEvaluations = 0; jacobianEvaluations = 0; // retrieve the equations and the parameters measurements = problem.getMeasurements(); parameters = problem.getUnboundParameters(); // arrays shared with the other private methods rows = measurements.length; cols = parameters.length; jacobian = new double[rows * cols]; residuals = new double[rows]; cost = Double.POSITIVE_INFINITY; }