⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 levenbergmarquardtestimator.java

📁 Apache的common math数学软件包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.math.estimation;import java.io.Serializable;import java.util.Arrays;/**  * 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. * decomposition which has been rewritten following the algorithm described 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. The * 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. *    All rights reserved * </td></tr> * <tr><td> * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * <ol> *  <li>Redistributions of source code must retain the above copyright *      notice, this list of conditions and the following disclaimer.</li> * <li>Redistributions in binary form must reproduce the above *     copyright notice, this list of conditions and the following *     disclaimer in the documentation and/or other materials provided *     with the distribution.</li> * <li>The end-user documentation included with the redistribution, if any, *     must include the following acknowledgment: *     <code>This product includes software developed by the University of *           Chicago, as Operator of Argonne National Laboratory.</code> *     Alternately, this acknowledgment may appear in the software itself, *     if and wherever such third-party acknowledgments normally appear.</li> * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL *     BE CORRECTED.</strong></li> * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li> * <ol></td></tr> * </table> * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran) * @author Burton S. Garbow (original fortran) * @author Kenneth E. Hillstrom (original fortran) * @author Jorge J. More (original fortran) * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $ * @since 1.2 * */public class LevenbergMarquardtEstimator extends AbstractEstimator implements Serializable {  /**    * 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>   *    <li>{@link #setMaxCostEval maximal cost evaluations}: 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>   *   </ul>   * </p>   */  public LevenbergMarquardtEstimator() {    // set up the superclass with a default  max cost evaluations setting    setMaxCostEval(1000);    // default values for the tuning parameters    setInitialStepBoundFactor(100.0);    setCostRelativeTolerance(1.0e-10);    setParRelativeTolerance(1.0e-10);    setOrthoTolerance(1.0e-10);  }  /**    * 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   */  public void setInitialStepBoundFactor(double initialStepBoundFactor) {    this.initialStepBoundFactor = initialStepBoundFactor;  }  /**    * Set the desired relative error in the sum of squares.   *    * @param costRelativeTolerance desired relative error in the sum of squares   * @see #estimate   */  public void setCostRelativeTolerance(double costRelativeTolerance) {    this.costRelativeTolerance = costRelativeTolerance;  }  /**    * Set the desired relative error in the approximate solution parameters.   *    * @param parRelativeTolerance desired relative error   * in the approximate solution parameters   * @see #estimate   */  public void setParRelativeTolerance(double parRelativeTolerance) {    this.parRelativeTolerance = parRelativeTolerance;  }  /**    * 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   */  public void setOrthoTolerance(double orthoTolerance) {    this.orthoTolerance = orthoTolerance;  }  /**    * 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   * is called with the {@link #setInitialStepBoundFactor},   * {@link #setMaxCostEval}, {@link #setCostRelativeTolerance},   * {@link #setParRelativeTolerance} and {@link #setOrthoTolerance} methods.   * If these methods have not been called, the default values set up by the   * {@link #LevenbergMarquardtEstimator() constructor} will be used.</p>   * <p>The authors of the original fortran function are:</p>   * <ul>   *   <li>Argonne National Laboratory. MINPACK project. March 1980</li>   *   <li>Burton  S. Garbow</li>   *   <li>Kenneth E. Hillstrom</li>   *   <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   * than equations   * @see #setInitialStepBoundFactor   * @see #setCostRelativeTolerance   * @see #setParRelativeTolerance   * @see #setOrthoTolerance   */  public void estimate(EstimationProblem problem)    throws EstimationException {    initializeEstimate(problem);    // arrays shared with the other private methods    solvedCols  = Math.min(rows, cols);    diagR       = new double[cols];    jacNorm     = new double[cols];    beta        = new double[cols];    permutation = new int[cols];    lmDir       = new double[cols];    // local variables    double   delta   = 0, xNorm = 0;    double[] diag    = new double[cols];    double[] oldX    = new double[cols];    double[] oldRes  = new double[rows];    double[] work1   = new double[cols];    double[] work2   = new double[cols];    double[] work3   = new double[cols];    // evaluate the function at the starting point and calculate its norm    updateResidualsAndCost();        // outer loop    lmPar = 0;    boolean firstIteration = true;    while (true) {      // compute the Q.R. decomposition of the jacobian matrix      updateJacobian();      qrDecomposition();      // compute Qt.res      qTy(residuals);      // now we don't need Q anymore,      // so let jacobian contain the R matrix with its diagonal elements      for (int k = 0; k < solvedCols; ++k) {        int pk = permutation[k];        jacobian[k * cols + pk] = diagR[pk];      }      if (firstIteration) {        // scale the variables according to the norms of the columns        // of the initial jacobian        xNorm = 0;        for (int k = 0; k < cols; ++k) {          double dk = jacNorm[k];          if (dk == 0) {            dk = 1.0;          }          double xk = dk * parameters[k].getEstimate();          xNorm  += xk * xk;          diag[k] = dk;        }        xNorm = Math.sqrt(xNorm);                // initialize the step bound delta        delta = (xNorm == 0) ? initialStepBoundFactor : (initialStepBoundFactor * xNorm);       }      // check orthogonality between function vector and jacobian columns      double maxCosine = 0;      if (cost != 0) {        for (int j = 0; j < solvedCols; ++j) {          int    pj = permutation[j];          double s  = jacNorm[pj];          if (s != 0) {            double sum = 0;            for (int i = 0, index = pj; i <= j; ++i, index += cols) {              sum += jacobian[index] * residuals[i];            }            maxCosine = Math.max(maxCosine, Math.abs(sum) / (s * cost));          }        }      }      if (maxCosine <= orthoTolerance) {        return;      }      // rescale if necessary      for (int j = 0; j < cols; ++j) {        diag[j] = Math.max(diag[j], jacNorm[j]);      }      // inner loop

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -