/* * SpeciesTreeBMPrior.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.evomodel.speciation; import dr.evolution.tree.NodeRef; import dr.inference.distribution.ParametricDistributionModel; import dr.inference.model.CompoundModel; import dr.inference.model.Likelihood; import dr.inference.model.Parameter; /** * @author Joseph Heled * Date: 8/12/2008 */ public class SpeciesTreeBMPrior extends Likelihood.Abstract { private final SpeciesTreeModel sTree; //private final ParametricDistributionModel dist; private final ParametricDistributionModel tips; private final Parameter popSigma; private final Parameter stSigma; private static final double d1 = (1 - Math.exp(-1)); private static final double f2 = -0.5 * Math.log(2*Math.PI); private final boolean logRoot; // public SpeciesTreeSimplePrior(SpeciesTreeModel sTree, ParametricDistributionModel dist, ParametricDistributionModel tipsPrior) { // super(new CompoundModel("STprior")); // this.sTree = sTree; // this.dist = dist; // this.tips = tipsPrior; // // final CompoundModel cm = (CompoundModel)this.getModel(); // cm.addModel(tipsPrior); // cm.addModel(dist); // cm.addModel(sTree); // } public SpeciesTreeBMPrior(SpeciesTreeModel sTree, Parameter popSigma, Parameter stSigma, ParametricDistributionModel tipsPrior, boolean logRoot) { super(new CompoundModel("STBMprior")); this.sTree = sTree; this.popSigma = popSigma; this.stSigma = stSigma; this.tips = tipsPrior; this.logRoot = logRoot; final CompoundModel cm = (CompoundModel)this.getModel(); cm.addModel(tipsPrior); cm.addModel(sTree); } protected double calculateLogLikelihood() { double logLike = 0; //if( true ) { final NodeRef root = sTree.getRoot(); final double stRootHeight = sTree.getNodeHeight(root); final SpeciesTreeModel.RawPopulationHelper helper = sTree.getPopulationHelper(); final double lim = stRootHeight ;//helper.geneTreesRootHeight() ; { final double sigma = stSigma.getParameterValue(0); final double s2 = 2 * sigma * sigma; int count = 0; double[] pops = new double[2]; for(int nn = 0; nn < sTree.getNodeCount(); ++nn) { final NodeRef n = sTree.getNode(nn); if( sTree.isExternal(n) ) { logLike += tips.logPdf(helper.tipPopulation(n)); } else { for(int nc = 0; nc < 2; ++nc) { final NodeRef child = sTree.getChild(n, nc); helper.getPopulations(n, nc, pops); final double dt = sTree.getBranchLength(child) / lim; final double pDiff = (pops[1] - pops[0]) / lim; logLike -= pDiff * pDiff / (s2 * dt); //need to adjest for dt! logLike -= .5 * Math.log(dt); count += 1; } } } if( ! helper.perSpeciesPopulation() ) { helper.getRootPopulations(pops); final double dt = helper.geneTreesRootHeight()/lim - 1; //final double dt = (lim - stRootHeight) / lim; // log(p1/lim) - log(p0/lim) = log(p1/p0) final double pDiff = logRoot ? Math.log(pops[1]/pops[0]) : (pops[1] - pops[0])/lim; logLike -= pDiff * pDiff / (s2 * dt); //need to adjust for dt! logLike -= .5 * Math.log(dt); count += 1; } logLike += count * (f2 - Math.log(sigma)); } if( helper.perSpeciesPopulation() ) { final double sigma = (popSigma != null ? popSigma : stSigma).getParameterValue(0); final double s2 = 2 * sigma * sigma; for(int ns = 0; ns < helper.nSpecies(); ++ns) { double[] times = helper.getTimes(ns); double[] pops = helper.getPops(ns); final double tMax = times[times.length-1]; double ll = 0.0; double x = pops[0]/tMax; double t0 = 0.0; for(int k = 1; k < times.length; ++k) { final double y = pops[k]/tMax; final double dt = (times[k-1] - t0) / tMax; ll -= (y - x)*(y-x) / (s2*dt); // need to adjest for dt! ll -= .5 * Math.log(dt); x = y; t0 = times[k-1]; } ll += (times.length-1) * (f2 - Math.log(sigma)); logLike += ll; } } //} return logLike; } protected boolean getLikelihoodKnown() { return false; } }