/* * IterativeProcess.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.math.iterations; import dr.math.functionEval.DrMath; /** * An iterative process is a general structure managing iterations. * * @author Didier H. Besset */ public abstract class IterativeProcess { /** * Number of iterations performed. */ private int iterations; /** * Maximum allowed number of iterations. */ private int maximumIterations = 50; /** * Desired precision. */ private double desiredPrecision = DrMath.defaultNumericalPrecision(); /** * Achieved precision. */ private double precision; /** * Generic constructor. */ public IterativeProcess() { } /** * Performs the iterative process. * Note: this method does not return anything because Java does not * allow mixing double, int, or objects */ public void evaluate() { iterations = 0; initializeIterations(); while ( iterations++ < maximumIterations ) { precision = evaluateIteration(); if ( hasConverged() ) break; } finalizeIterations(); } /** * Evaluate the result of the current interation. * @return the estimated precision of the result. */ abstract public double evaluateIteration(); /** * Perform eventual clean-up operations * (mustbe implement by subclass when needed). */ public void finalizeIterations ( ) { } /** * Returns the desired precision. */ public double getDesiredPrecision( ) { return desiredPrecision; } /** * Returns the number of iterations performed. */ public int getIterations() { return iterations; } /** * Returns the maximum allowed number of iterations. */ public int getMaximumIterations( ) { return maximumIterations; } /** * Returns the attained precision. */ public double getPrecision() { return precision; } /** * Check to see if the result has been attained. * @return boolean */ public boolean hasConverged() { return precision < desiredPrecision; } /** * Initializes internal parameters to start the iterative process. */ public void initializeIterations() { } /** * @return double * @param epsilon double * @param x double */ public double relativePrecision( double epsilon, double x) { return x > DrMath.defaultNumericalPrecision() ? epsilon / x: epsilon; } /** * Defines the desired precision. */ public void setDesiredPrecision( double prec ) throws IllegalArgumentException { if ( prec <= 0 ) throw new IllegalArgumentException ( "Non-positive precision: "+prec); desiredPrecision = prec; } /** * Defines the maximum allowed number of iterations. */ public void setMaximumIterations( int maxIter) throws IllegalArgumentException { if ( maxIter < 1 ) throw new IllegalArgumentException ( "Non-positive maximum iteration: "+maxIter); maximumIterations = maxIter; } }