Skip to content

Commit

Permalink
Updated the readme, and fixed the fitters to throw exceptions and not…
Browse files Browse the repository at this point in the history
… swallow them.
  • Loading branch information
msmith committed Mar 7, 2016
1 parent cfc0d1c commit b688be2
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 12 deletions.
80 changes: 73 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,81 @@ least-squares-in-java
=====================

Java Least Squares fitting library.
-----------------------------------

This is a small least squares fitting library made in java.
It was originally used in the development of an image analysis tool
SpeckleTrackerJ. Which has a lot of functions, this is a smaller package that
only does the least squares portion. It is being written to include tests
and a few more features.
SpeckleTrackerJ. http://athena.physics.lehigh.edu/speckletrackerj/ It uses
methods described in "Numerical Recipes in C", Second Edition (1992).

SpeckleTrackerJ can be found at:
http://athena.physics.lehigh.edu/speckletrackerj/
The outline of using this library is you have a set of data that you
would like fit a function to. Define the Function, how it evaluates
the input and paramters. Create a Fitter (three types currently) initialized
to the function. Set the fitter with the data and make an initial guess of the
parameters. Tell the fitter to find the best set of parameters which minimizes the
sum of squares of error.

and the source code is hosted at google code.
https://code.google.com/p/speckletrackerj/
Example
-------

Lets say we have some data.

double[][] xs = {
{0}, {1}, {2}, {3}, {4}, {5}
};
double[] z = {1.1, 0.9, 1.0, 1.35, 1.82, 2.5};

And we want to fit a quadratic function f(x) = A*x*x + B*x + C. The parameters are A, B, C and the
input is x. So we have 3 parameters and 1 input.

Function fun = new Function(){
@Override
public double evaluate(double[] values, double[] parameters) {
double A = parameters[0];
double B = parameters[1];
double C = parameters[2];
double x = values[0];
return A*x*x + B*x + C;
}
@Override
public int getNParameters() {
return 3;
}

@Override
public int getNInputs() {
return 1;
}
};

The next step is to create a fitter.

Fitter fit = new LinearFitter(fun);

Set the data, and make a guess at the initial parameters.

fit.setData(xs, zs);
fit.setParameters(new double[]{0,0,0});

fit.fitData();

The results can be obtained by using getParameters.

System.out.println(Arrays.toString(fit.getParameters()));
#[0.10000000000000023, -0.20000000000000123, 1.000000000000001]

This example is included in the examples package.


Fitter implementations
----------------------

LinearFitter: for use with equations that are linearly dependent on the input parameters. Standard
linear regression where derivatives are taken by setting all of the parameters to zero, except for the
one of interest.

NonLinearSolver: Similar to the LinearSolver, except it will run multiple iterations, there is a damping
factor, and the derivatives are calculated by taken by varying the parameters a small amount from the
previous guess.

MarquardtFitter: Similar to the NonLinearSolver except the damping is adaptive.
49 changes: 49 additions & 0 deletions main/org/orangepalantir/leastsquares/examples/ParabolaExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.orangepalantir.leastsquares.examples;

import org.orangepalantir.leastsquares.Fitter;
import org.orangepalantir.leastsquares.Function;
import org.orangepalantir.leastsquares.fitters.LinearFitter;

import java.util.Arrays;

/**
* Created by msmith on 3/7/16.
*/
public class ParabolaExample {

public static void main(String[] args){
double[][] xs = {
{0}, {1}, {2}, {3}, {4}, {5}
};
double[] zs = {1.0, 0.9, 1.0, 1.3, 1.8, 2.5};

Function fun = new Function(){
@Override
public double evaluate(double[] values, double[] parameters) {
double A = parameters[0];
double B = parameters[1];
double C = parameters[2];
double x = values[0];
return A*x*x + B*x + C;
}
@Override
public int getNParameters() {
return 3;
}

@Override
public int getNInputs() {
return 1;
}
};

Fitter fit = new LinearFitter(fun);
fit.setData(xs, zs);
fit.setParameters(new double[]{0,0,0});

fit.fitData();

System.out.println(Arrays.toString(fit.getParameters()));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,10 @@ public void fitData(){

try{
iterateValues();

} catch(Exception exc){
printMatrix();
exc.printStackTrace();

throw exc;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,9 @@ public void fitData(){

} catch(Exception exc){
System.out.println("Broke after " + i + " iterations");
printMatrix();
//printMatrix();
throw(new RuntimeException(printMatrix()));
throw exc;
}

nerror = calculateErrors();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public void fitData(){
if(changes< MIN_CHANGE)
break;
} catch(Exception exc){
break;
throw exc;
}
}
if(i==MAX_ITERATIONS){
Expand Down Expand Up @@ -207,7 +207,7 @@ public void setMinError(double error){
}

/**
* When the parameters change less than this the program will stop iterating
* When the parameters change less than the change parameter the program will stop iterating
*
* @param change
*/
Expand Down

0 comments on commit b688be2

Please sign in to comment.