package com.nus;

/**
 * Created by duy on 20/1/15.
 */
public class LMSolver {
  // Configuration parameters for Levenberg-Marquadt algorithm
  private double lambda;
  private int maxNumIter;
  private double termEpsilon;

  private IErrorFunc errorFunc;

  public LMSolver(IErrorFunc inErrorFunc) {
    this.lambda = 10;
    this.maxNumIter = 10;
    this.termEpsilon = 0.00001;
    this.errorFunc = inErrorFunc;
  }

  public LMSolver(
      double lambda,
      int maxNumIter,
      double termEpsilon,
      IErrorFunc errorFunc) {
    this.lambda = lambda;
    this.maxNumIter = maxNumIter;
    this.termEpsilon = termEpsilon;
    this.errorFunc = errorFunc;
  }

  public double getLambda() {
    return lambda;
  }

  public void setLambda(double lambda) {
    this.lambda = lambda;
  }

  public int getMaxNumIter() {
    return maxNumIter;
  }

  public IErrorFunc getErrorFunc() {
    return errorFunc;
  }

  public void setMaxNumIter(int maxNumIter) {
    this.maxNumIter = maxNumIter;
  }

  public double getTermEpsilon() {
    return termEpsilon;
  }

  public void setTermEpsilon(double termEpsilon) {
    this.termEpsilon = termEpsilon;
  }
}

@@ -11,16 +11,37 @@
 m.nus;%0A%0A
+import Jama.Matrix;%0A%0A
 /**%0A * C
@@ -1174,11 +1174,1767 @@
 lon;%0A  %7D
+%0A%0A  /**%0A   * Applies Levenberg-Marquadt on the input error function with the input%0A   * initial guess of optimization parameters%0A   *%0A   * @param optParams A vector of initial guess of values of parameters%0A   *                  for optimization%0A   */%0A  public void solve(double%5B%5D optParams) %7B%0A    int iter = 0;%0A    int count = 0;%0A    boolean stopFlag = false;%0A    int numOptParams = optParams.length;%0A%0A    double errValue = errorFunc.eval(optParams);%0A%0A    double curLambda = lambda;%0A%0A    do %7B%0A      stopFlag = false;%0A      iter++;%0A%0A      // Compute matrices and vectors needed in augmented normal equation%0A      double%5B%5D gradient = errorFunc.jacobian(optParams);%0A      double%5B%5D%5B%5D modifiedHessian = errorFunc.hessian(optParams);%0A      for (int i = 0; i %3C numOptParams; ++i) %7B%0A        modifiedHessian%5Bi%5D%5Bi%5D *= (1 + curLambda);%0A      %7D%0A%0A      // Solve augmented normal equation%0A      Matrix direction = solveMatrixEq(%0A        new Matrix(modifiedHessian),%0A        new Matrix(gradient, numOptParams)%0A      );%0A      double%5B%5D newOptParams =%0A        (new Matrix(gradient, numOptParams)).plus(direction).getRowPackedCopy();%0A%0A      double newErrValue = errorFunc.eval(newOptParams);%0A%0A      if (Math.abs(newErrValue - errValue) %3C termEpsilon) %7B%0A        count++;%0A        if (count == 4) %7B%0A          stopFlag = true;%0A        %7D%0A      %7D%0A%0A      if (newErrValue %3E errValue) %7B%0A        curLambda *= 10.0;%0A      %7D else %7B%0A        curLambda /= 10.0;%0A        errValue = newErrValue;%0A        for (int i = 0; i %3C numOptParams; ++i) %7B%0A          optParams%5Bi%5D = newOptParams%5Bi%5D;%0A        %7D%0A      %7D%0A%0A      if (iter %3E maxNumIter) %7B%0A        stopFlag = true;%0A      %7D%0A%0A    %7D while (!stopFlag);%0A  %7D%0A%0A  private static Matrix solveMatrixEq(Matrix A, Matrix b) %7B%0A    return A.lu().solve(b);%0A  %7D
 %0A%7D%0A

Implement lightweight LM algorithm