package edu.stanford.rsl.conrad.fitting; import java.util.Random; /** * Method for RANSACing with constraints on the parameter bounds. * Tries that create out-of-bounds solutions are not counted. * * @author Jiang * */ public class ConstrainedRANSACFittedFunction extends RANSACFittedFunction { /** * Uneducational Constructor that initializes the bounds in a redandant way. * Prevents the software from crashing if no bounds are set. * * @param func */ public ConstrainedRANSACFittedFunction(Function func) { super(func); upperbound = new double[func.getNumberOfParameters()]; lowerbound = new double[func.getNumberOfParameters()]; for (int i=0;i< func.getNumberOfParameters(); i++){ upperbound[i] = Double.POSITIVE_INFINITY; lowerbound[i] = Double.NEGATIVE_INFINITY; } } /** * */ private static final long serialVersionUID = -4078810270398436119L; private double [] upperbound; private double [] lowerbound; public void fitToPoints(double[] x, double[] y) { int corresp = baseFunction.getMinimumNumberOfCorrespondences(); double bestFit = 0; Function bestModel = null; double [] randX = new double [corresp]; double [] randY = new double [corresp]; Random random = new Random(); for (int i = 0; i < numberOfTries; i++){ try { Function currentTry = (Function) baseFunction.getClass().newInstance(); // compute next try: for (int j=0;j<corresp;j++){ int index = (int) (random.nextDouble() * (x.length-1)); randX[j] = x[index]; randY[j] = y[index]; } currentTry.fitToPoints(randX, randY); boolean parameterCheck = true; double [] param = currentTry.getParametersAsDoubleArray(); for (int j=0; j < currentTry.getNumberOfParameters(); j++){ if (param[j] > upperbound[j]) parameterCheck = false; if (param[j] < lowerbound[j]) parameterCheck = false; } if (!parameterCheck) { i--; } else { double fitness = evaluateModelFittnes(x, y, currentTry ); if (fitness > bestFit) { bestModel = currentTry; bestFit = fitness; } } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } if ((bestModel != null)) { baseFunction = bestModel; fittingDone = true; } else { System.err.println("RANSACFittedFunction: Warining increasing epsilon to " + epsilon +"\nChoose a bigger epsilon or more tries in the future!"); epsilon *= 1.1; fitToPoints(x, y); } } /** * @return the upperbound */ public double[] getUpperbound() { return upperbound; } /** * @param upperbound the upperbound to set */ public void setUpperbound(double[] upperbound) { this.upperbound = upperbound; } /** * @return the lowerbound */ public double[] getLowerbound() { return lowerbound; } /** * @param lowerbound the lowerbound to set */ public void setLowerbound(double[] lowerbound) { this.lowerbound = lowerbound; } }