/** * @return The covariance matrix of the fit parameters. * @throws LMAMatrix.InvertException if the inversion of alpha fails. Note that even if the fit * does NOT throw the invert exception, this method can still do it, because here alpha is * inverted with lambda = 0. */ public double[][] getCovarianceMatrixOfStandardErrorsInParameters() throws LMAMatrix.InvertException { double[][] result = new double[parameters.length][parameters.length]; double oldLambda = lambda; lambda = 0; updateAlpha(); try { alpha.invert(); } catch (LMAMatrix.InvertException e) { // restore alpha just in case lambda = oldLambda; updateAlpha(); throw new LMAMatrix.InvertException( "Inverting alpha failed with lambda = 0\n" + e.getMessage()); } for (int i = 0; i < result.length; i++) { for (int j = 0; j < result.length; j++) { result[i][j] = alpha.getElement(i, j); } } alpha.invert(); lambda = oldLambda; updateAlpha(); return result; }
/** * The default fit. If used after calling fit(lambda, minDeltaChi2, maxIterations), uses those * values. The stop condition is fetched from <code>this.stop()</code>. Override <code>this.stop() * </code> if you want to use another stop condition. */ public void fit() throws LMAMatrix.InvertException { iterationCount = 0; if (Double.isNaN(calculateChi2())) { throw new RuntimeException("INITIAL PARAMETERS ARE ILLEGAL."); } do { chi2 = calculateChi2(); if (verbose) { System.out.println( iterationCount + ": chi2 = " + chi2 + ", " + Arrays.toString(parameters)); } updateAlpha(); updateBeta(); try { solveIncrements(); incrementedChi2 = calculateIncrementedChi2(); // The guess results to worse chi2 or NaN - make the step smaller if (incrementedChi2 >= chi2 || Double.isNaN(incrementedChi2)) { lambda *= lambdaFactor; } // The guess results to better chi2 - move and make the step larger else { lambda /= lambdaFactor; updateParameters(); } } catch (LMAMatrix.InvertException e) { // If the error happens on the last round, the fit has failed - throw the error out if (iterationCount == maxIterations) { throw e; } // otherwise make the step smaller and try again if (verbose) { System.out.println(e.getMessage()); } lambda *= lambdaFactor; } iterationCount++; } while (!stop()); printEndReport(); }