/* * MLOptimizer.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.inference.ml; import dr.inference.loggers.Logger; import dr.inference.markovchain.MarkovChain; import dr.inference.markovchain.MarkovChainListener; import dr.inference.model.Likelihood; import dr.inference.model.Model; import dr.inference.operators.OperatorSchedule; import dr.util.Identifiable; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * A heuristic optimizer that uses the MCMC framework. * * @author Andrew Rambaut * * @version $Id: MLOptimizer.java,v 1.5 2006/06/13 03:50:54 alexei Exp $ */ public class MLOptimizer implements Runnable, Identifiable { /** the likelihood function */ private final Likelihood likelihood; /** the operator schedule */ private OperatorSchedule schedule; private final Logger[] loggers; int chainLength; private String id = null; /** * Constructor * @param chainLength the chain length * @param schedule operator schedule to be used in chain. */ public MLOptimizer(String id, int chainLength, Likelihood likelihood, OperatorSchedule schedule, Logger[] loggers) { this.id = id; mc = new MarkovChain(likelihood, schedule, new GreatDelugeCriterion(0.2), 2000, 1, MarkovChain.EVALUATION_TEST_THRESHOLD, false); //mc = new MarkovChain(null, likelihood, schedule, new HillClimbingCriterion(), false); this.chainLength = chainLength; this.likelihood = likelihood; this.loggers = loggers; setOperatorSchedule(schedule); //initialize transients currentState = 0; } public void run() { chain(); } /** * This method actually intiates the MCMC analysis. * the site patterns have been dropped from the site model * to reduce the footprint of the sample. */ public void chain() { currentState = 0; if (loggers != null) { for (Logger logger : loggers) { logger.startLogging(); } } timer.start(); mc.reset(); timer.start(); mc.addMarkovChainListener(chainListener); mc.runChain(getChainLength(), true/*, 0*/); mc.removeMarkovChainListener(chainListener); timer.stop(); } /** @return the likelihood function. */ public Likelihood getLikelihood() { return likelihood; } /** @return the timer. */ public dr.util.Timer getTimer() { return timer; } /** set the operator schedule used in this MCMC analysis. * MUST be called before chain! */ public void setOperatorSchedule(OperatorSchedule sched) { this.schedule = sched; } /** @return the operator schedule used in this MCMC analysis. */ public OperatorSchedule getOperatorSchedule() { return schedule; } /** @return the length of this analysis.*/ public final int getChainLength() { return chainLength; } // TRANSIENT PUBLIC METHODS ***************************************** /** @return the current state of the MCMC analysis. */ public final long getCurrentState() { return currentState; } /** @return the progress (0 to 1) of the MCMC analysis. */ public final double getProgress() { return (double)currentState / chainLength; } private final MarkovChainListener chainListener = new MarkovChainListener() { @Override public void bestState(long state, MarkovChain markovChain, Model bestModel) { currentState = state; } @Override public void currentState(long state, MarkovChain markovChain, Model currentModel) { currentState = state; if (loggers != null) { for (Logger logger : loggers) { logger.log(state); } } } @Override public void finished(long chainLength, MarkovChain markovChain) { currentState = chainLength; if (loggers != null) { for (Logger logger : loggers) { logger.log(currentState); logger.stopLogging(); } } /* if (false) { NumberFormatter formatter = new NumberFormatter(8); System.out.println(); System.out.println("Operator analysis"); for (int i =0; i < schedule.getOperatorCount(); i++) { MCMCOperator op = schedule.getOperator(i); double acceptanceProb = MCMCOperator.Utils.getAcceptanceProbability(op); System.out.println(formatter.formatToFieldWidth(op.getOperatorName(), 30) + "\t" + formatter.formatDecimal(op.getMeanDeviation(), 2) + "\t" + formatter.formatDecimal(acceptanceProb, 4)); } System.out.println(); } */ } // for receiving /** Called when a new new best likelihood state is found. */ public void bestLklModel(long state, Model bestModel) { currentState = state; } }; /** * Creates a DOM element that represents this MCMC analysis. */ public Element createElement(Document d) { throw new RuntimeException("Not implemented!"); } public String getId() { return id; } public void setId(String id) { this.id = id; } // PRIVATE TRANSIENTS private long currentState; private final dr.util.Timer timer = new dr.util.Timer(); /** this markov chain does most of the work. */ private MarkovChain mc = null; }