/* * DirichletProcessLikelihood.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.distribution; import dr.inference.model.*; /** * A class that returns the log likelihood of a set of discrete entities * being distributed in k classes according to a Dirichlet process. * * @author Andrew Rambaut * @author Trevor Bedford * @author Marc Suchard * @version $Id: DirichletProcessLikelihood.java,v 1.7 2005/05/24 20:25:59 rambaut Exp $ */ public class DirichletProcessLikelihood extends AbstractModelLikelihood { public static final String DIRICHLET_PROCESS_LIKELIHOOD = "dirichletProcessLikelihood"; public DirichletProcessLikelihood(Statistic etaParameter, Parameter chiParameter) { super(DIRICHLET_PROCESS_LIKELIHOOD); this.etaParameter = etaParameter; this.chiParameter = chiParameter; addVariable(chiParameter); K = etaParameter.getDimension(); int count = 0; for (int i = 0; i < K; i++) { count += (int)etaParameter.getStatisticValue(i); } N = count; // create a look up table for all log factorials up to N logFactorials = new double[N]; logFactorials[0] = 0.0; for (int j = 1; j < N; j++) { // logFactorials[j] = 0; // the log factorial for 0 // for (int k = 1; k <= j; k++) { // logFactorials[j] += Math.log(k); // } logFactorials[j] = logFactorials[j - 1] + Math.log(j); } } // ************************************************************** // Likelihood IMPLEMENTATION // ************************************************************** public Model getModel() { return this; } /** * Calculate the log likelihood of the current state. * * @return the log likelihood. */ public double getLogLikelihood() { double chi = chiParameter.getParameterValue(0); double logEtaj = 0; int K1 = 0; for (int j = 0; j < K; j++) { int eta = (int)etaParameter.getStatisticValue(j); if (eta > N) { throw new RuntimeException("Illegal eta value"); } if (eta > 0) { // double logFactorial = 0; // for (int k = 1; k <= (eta - 1); k++) { // logFactorial += Math.log(k); // } double logFactorial = logFactorials[eta - 1]; logEtaj += logFactorial; // count the number of actually occupied classes K1++; } } double logDenominator = 0; for (int i = 1; i <= N; i++) { logDenominator += Math.log(chi + i - 1); } double logP = K1 * Math.log(chi) + logEtaj - logDenominator; return logP; } public void makeDirty() { } public void acceptState() { // DO NOTHING } public void restoreState() { // DO NOTHING } public void storeState() { // DO NOTHING } protected void handleModelChangedEvent(Model model, Object object, int index) { // DO NOTHING } protected final void handleVariableChangedEvent(Variable variable, int index, Parameter.ChangeType type) { // DO NOTHING } public Statistic getEtaParameter() { return etaParameter; } public Parameter getChiParameter() { return chiParameter; } public int getN() { return N; } private final Statistic etaParameter; private final Parameter chiParameter; private final int N, K; private final double[] logFactorials; }