Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save anonymous/6184665 to your computer and use it in GitHub Desktop.
Save anonymous/6184665 to your computer and use it in GitHub Desktop.
Interfaces and hierarchy for implementing Immutability+Fluent API in the non-linear least squares package. The sample user code is at the bottom.
public interface NonLinearLeastSquaresOptimizer {
NonLinearLeastSquaresOptimizer withMaxIterations(int max);
NonLinearLeastSquaresOptimizer withMaxEvaluations(int max);
//similarly for the other withXxx methods common to both Gauss-Newton
//and Levenburg-Marquardt. If withXxx methods are inherited from another
//interface they must be redeclared here to have the correct return type.
PointVectorValuePair optimize();
}
//users should not use AbstractNonLinearLeastSquaresOptimizer<T> in their code.
//Use the interface, or a concrete implementation.
public abstract class AbstractNonLinearLeastSquaresOptimizer<T extends AbstractNonLinearLeastSquaresOptimizer>
implements NonLinearLeastSquaresOptimizer {
private final int maxIter;
private final int maxEval;
//and all other fields specified by the interface
public AbstractNonLinearLeastSquaresOptimizer(int maxIter, .../*other fields*/){
super();
this.maxIter = maxIter;
//similarly for the other fields
}
public T withMaxIterations(int max){
return create(max, this.getMaxEval(), .../*other fields declared in this class's constructor*/);
}
protected abstract T create(int maxIter, int maxEval, .../*other fields declared in constructor*/);
}
//concrete class is *not* extensible
public final class GaussNewton extends AbstractNonLinearLeastSquaresOptimizer<GaussNewton> {
private final boolean useLu;
public GaussNewton() { /* set default values */ }
private GaussNewton(/*super class constructor parameters*/,
boolean useLu /* this class's fields */ ){
super(/*superclass parameters*/);
this.useLu = useLu;
}
@Override
protected GaussNewton create(/*superclass constructor paramters*/){
return new GaussNewton(/*superclass constructor paramters*/, this.getUseLu());
}
//implement doOptimize
}
/* the user code */
//using the interface. Finally polymorphism for LM and GN! :)
NonLinearLeastSquaresOptimizer opt = new GaussNewton();
//configure
opt = opt.withMaxIterations(5)./*continue configuring*/;
//run
PointVectorValuePair solu = opt.optimize();
//using a concrete class
GaussNewton opt = new GaussNewton();
//configure
opt = opt.withMaxIterations(5)./*continue configuring*/;
//run
PointVectorValuePair solu = opt.optimize();
//using the abstract base class is technically possible, but it is ugly
//and unessecary because of the interface.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment