/* * LogNormalDistribution.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.distributions; import dr.math.UnivariateFunction; /** * log normal distribution (pdf, cdf, quantile) * * @author Korbinian Strimmer * @version $Id: LogNormalDistribution.java,v 1.3 2005/06/21 16:25:15 beth Exp $ */ public class LogNormalDistribution implements Distribution { // // Public stuff // /** * @param M the mean of the random variable's natural logarithm * @param S the stdev of the random variable's natural logarithm */ public LogNormalDistribution(double M, double S) { this.M = M; this.S = S; } public final double getM() { return M; } public final void setM(double M) { this.M = M; } public final double getS() { return S; } public final void setS(double S) { this.S = S; } public double pdf(double x) { return pdf(x, M, S); } public double logPdf(double x) { return logPdf(x, M, S); } public double cdf(double x) { return cdf(x, M, S); } public double quantile(double y) { return quantile(y, M, S); } public double mean() { return mean(M, S); } public double variance() { return variance(M, S); } public double mode() { return mode(M, S); } public final UnivariateFunction getProbabilityDensityFunction() { return pdfFunction; } private final UnivariateFunction pdfFunction = new UnivariateFunction() { public final double evaluate(double x) { return pdf(x); } public final double getLowerBound() { return 0.0; } public final double getUpperBound() { return Double.POSITIVE_INFINITY; } }; /** * probability density function * * @param x argument * @param M log mean * @param S log standard deviation * @return pdf at x */ public static double pdf(double x, double M, double S) { if (x <= 0) return 0; // no density for x<=0 return NormalDistribution.pdf(Math.log(x), M, S) / x; } /** * the natural log of the probability density function of the distribution * * @param x argument * @param M log mean * @param S log standard deviation * @return log pdf at x */ public static double logPdf(double x, double M, double S) { if (x < 0) return Double.NEGATIVE_INFINITY; // no density for x<0 return NormalDistribution.logPdf(Math.log(x), M, S) - Math.log(x); } /** * cumulative density function * * @param x argument * @param M log mean * @param S log standard deviation * @return cdf at x */ public static double cdf(double x, double M, double S) { if (x < 0) return 0; // no density for x<0 return NormalDistribution.cdf(Math.log(x), M, S, false); //return NormalDistribution.cdf(Math.log(x), M, S); } /** * quantiles (=inverse cumulative density function) * * @param z argument * @param M log mean * @param S log standard deviation * @return icdf at z */ public static double quantile(double z, double M, double S) { return Math.exp(NormalDistribution.quantile(z, M, S)); } /** * mean * * @param M log mean * @param S log standard deviation * @return mean */ public static double mean(double M, double S) { return Math.exp(M + (S * S / 2)); } /** * mode * * @param M log mean * @param S log standard deviation * @return mode */ public static double mode(double M, double S) { return Math.exp(M - S * S); } /** * variance * * @param M log mean * @param S log standard deviation * @return variance */ public static double variance(double M, double S) { final double S2 = S * S; return Math.exp(S2 + 2 * M) * (Math.exp(S2) - 1); } // Private protected double M, S; }