Return-Path: X-Original-To: apmail-commons-dev-archive@www.apache.org Delivered-To: apmail-commons-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id F3CC59918 for ; Tue, 17 Jan 2012 07:17:15 +0000 (UTC) Received: (qmail 80600 invoked by uid 500); 17 Jan 2012 07:17:15 -0000 Delivered-To: apmail-commons-dev-archive@commons.apache.org Received: (qmail 79982 invoked by uid 500); 17 Jan 2012 07:17:08 -0000 Mailing-List: contact dev-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Commons Developers List" Delivered-To: mailing list dev@commons.apache.org Received: (qmail 79966 invoked by uid 99); 17 Jan 2012 07:17:04 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Jan 2012 07:17:04 +0000 X-ASF-Spam-Status: No, hits=2.2 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_NEUTRAL X-Spam-Check-By: apache.org Received-SPF: neutral (athena.apache.org: local policy) Received: from [209.85.213.171] (HELO mail-yx0-f171.google.com) (209.85.213.171) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Jan 2012 07:17:00 +0000 Received: by yenr9 with SMTP id r9so3091449yen.30 for ; Mon, 16 Jan 2012 23:16:38 -0800 (PST) MIME-Version: 1.0 Received: by 10.236.193.70 with SMTP id j46mr21227820yhn.108.1326784598403; Mon, 16 Jan 2012 23:16:38 -0800 (PST) Received: by 10.147.77.12 with HTTP; Mon, 16 Jan 2012 23:16:38 -0800 (PST) Received: by 10.147.77.12 with HTTP; Mon, 16 Jan 2012 23:16:38 -0800 (PST) In-Reply-To: <20120117071203.4A189238897D@eris.apache.org> References: <20120117071203.4A189238897D@eris.apache.org> Date: Tue, 17 Jan 2012 08:16:38 +0100 Message-ID: Subject: [MATH] Re: svn commit: r1232324 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/distribution/ test/R/ test/java/org/apache/commons/math/distribution/ From: Mikkel Meyer Andersen To: dev@commons.apache.org Content-Type: multipart/alternative; boundary=20cf30563c21ae6b9704b6b41c85 --20cf30563c21ae6b9704b6b41c85 Content-Type: text/plain; charset=ISO-8859-1 Hi, You write for x >= 0, but isn't only x > 0? Cheers, Mikkel. Den 17/01/2012 08.12 skrev : > Author: celestin > Date: Tue Jan 17 07:12:02 2012 > New Revision: 1232324 > > URL: http://svn.apache.org/viewvc?rev=1232324&view=rev > Log: > Implementation of log-normal distributions (MATH-733). Patch contributed > by Dennis Hendriks. > > Added: > > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > (with props) > commons/proper/math/trunk/src/test/R/logNormalTestCases (with props) > > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > (with props) > Modified: > > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java > > Added: > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > URL: > http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java?rev=1232324&view=auto > > ============================================================================== > --- > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > (added) > +++ > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > Tue Jan 17 07:12:02 2012 > @@ -0,0 +1,295 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file distributed with > + * this work for additional information regarding copyright ownership. > + * The ASF licenses this file to You under the Apache License, Version 2.0 > + * (the "License"); you may not use this file except in compliance with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +package org.apache.commons.math.distribution; > + > +import org.apache.commons.math.exception.NotStrictlyPositiveException; > +import org.apache.commons.math.exception.NumberIsTooLargeException; > +import org.apache.commons.math.exception.util.LocalizedFormats; > +import org.apache.commons.math.special.Erf; > +import org.apache.commons.math.util.FastMath; > + > +/** > + * Implementation of the log-normal (gaussian) distribution. > + * > + *

> + * Parameters: > + * {@code X} is log-normally distributed if its natural logarithm {@code > log(X)} > + * is normally distributed. The probability distribution function of > {@code X} > + * is given by (for {@code x >= 0}) > + *

> + *

> + * {@code exp(-0.5 * ((ln(x) - m) / s)^2) / (s * sqrt(2 * pi) * x)} > + *

> + *
    > + *
  • {@code m} is the scale parameter: this is the mean of the > + * normally distributed natural logarithm of this distribution,
  • > + *
  • {@code s} is the shape parameter: this is the standard > + * deviation of the normally distributed natural logarithm of this > + * distribution. > + *
> + * > + * @see > + * Log-normal distribution (Wikipedia) > + * @see > + * Log Normal distribution (MathWorld) > + * > + * @version $Id$ > + * @since 3.0 > + */ > +public class LogNormalDistribution extends AbstractRealDistribution { > + /** Default inverse cumulative probability accuracy. */ > + public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; > + > + /** Serializable version identifier. */ > + private static final long serialVersionUID = 20120112; > + > + /** √(2 π) */ > + private static final double SQRT2PI = FastMath.sqrt(2 * FastMath.PI); > + > + /** √(2) */ > + private static final double SQRT2 = FastMath.sqrt(2.0); > + > + /** The scale parameter of this > distribution. */ > + private final double scale; > + > + /** The shape parameter of this > distribution. */ > + private final double shape; > + > + /** Inverse cumulative probability accuracy. */ > + private final double solverAbsoluteAccuracy; > + > + /** > + * Create a log-normal distribution using the specified > + * scale and > + * shape. > + * > + * @param scale the scale parameter of this distribution > + * @param shape the shape parameter of this distribution > + * @throws NotStrictlyPositiveException if {@code shape <= 0}. > + */ > + public LogNormalDistribution(double scale, double shape) > + throws NotStrictlyPositiveException { > + this(scale, shape, DEFAULT_INVERSE_ABSOLUTE_ACCURACY); > + } > + > + /** > + * Create a log-normal distribution using the specified > + * scale, shape > and > + * inverse cumulative distribution accuracy. > + * > + * @param scale the scale parameter of this distribution > + * @param shape the shape parameter of this distribution > + * @param inverseCumAccuracy Inverse cumulative probability accuracy. > + * @throws NotStrictlyPositiveException if {@code shape <= 0}. > + */ > + public LogNormalDistribution(double scale, double shape, > + double inverseCumAccuracy) throws NotStrictlyPositiveException { > + if (shape <= 0) { > + throw new > NotStrictlyPositiveException(LocalizedFormats.STANDARD_DEVIATION, shape); > + } > + > + this.scale = scale; > + this.shape = shape; > + this.solverAbsoluteAccuracy = inverseCumAccuracy; > + } > + > + /** > + * Create a log-normal distribution, where the mean and standard > deviation > + * of the {@link NormalDistribution normally distributed} natural > + * logarithm of the log-normal distribution are equal to zero and one > + * respectively. In other words, the scale of the returned > distribution is > + * {@code 0}, while its shape is {@code 1}. > + */ > + public LogNormalDistribution() { > + this(0, 1); > + } > + > + /** > + * Returns the scale parameter of this > distribution. > + * > + * @return the scale parameter > + */ > + public double getScale() { > + return scale; > + } > + > + /** > + * Returns the shape parameter of this > + * distribution. > + * > + * @return the shape parameter > + */ > + public double getShape() { > + return shape; > + } > + > + /** > + * {@inheritDoc} > + * > + * For this distribution {@code P(X = x)} always evaluates to 0. > + * > + * @return 0 > + */ > + public double probability(double x) { > + return 0.0; > + } > + > + /** > + * {@inheritDoc} > + * > + * For scale {@code m}, and shape {@code s} of this distribution, the > PDF > + * is given by > + *
    > + *
  • {@code 0} if {@code x <= 0},
  • > + *
  • {@code exp(-0.5 * ((ln(x) - m) / s)^2) / (s * sqrt(2 * pi) * > x)} > + * otherwise.
  • > + *
> + */ > + public double density(double x) { > + if (x <= 0) { > + return 0; > + } > + final double x0 = FastMath.log(x) - scale; > + final double x1 = x0 / shape; > + return FastMath.exp(-0.5 * x1 * x1) / (shape * SQRT2PI * x); > + } > + > + /** > + * {@inheritDoc} > + * > + * For scale {@code m}, and shape {@code s} of this distribution, the > CDF > + * is given by > + *
    > + *
  • {@code 0} if {@code x <= 0},
  • > + *
  • {@code 0} if {@code ln(x) - m < 0} and {@code m - ln(x) > 40 * > s}, as > + * in these cases the actual value is within {@code Double.MIN_VALUE} > of 0, > + *
  • {@code 1} if {@code ln(x) - m >= 0} and {@code ln(x) - m > 40 > * s}, > + * as in these cases the actual value is within {@code > Double.MIN_VALUE} of > + * 1,
  • > + *
  • {@code 0.5 + 0.5 * erf((ln(x) - m) / (s * sqrt(2))} > otherwise.
  • > + *
> + */ > + public double cumulativeProbability(double x) { > + if (x <= 0) { > + return 0; > + } > + final double dev = FastMath.log(x) - scale; > + if (FastMath.abs(dev) > 40 * shape) { > + return dev < 0 ? 0.0d : 1.0d; > + } > + return 0.5 + 0.5 * Erf.erf(dev / (shape * SQRT2)); > + } > + > + /** {@inheritDoc} */ > + @Override > + public double cumulativeProbability(double x0, double x1) > + throws NumberIsTooLargeException { > + if (x0 > x1) { > + throw new > NumberIsTooLargeException(LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, > + x0, x1, true); > + } > + if (x0 <= 0 || x1 <= 0) { > + return super.cumulativeProbability(x0, x1); > + } > + final double denom = shape * SQRT2; > + final double v0 = (FastMath.log(x0) - scale) / denom; > + final double v1 = (FastMath.log(x1) - scale) / denom; > + return 0.5 * Erf.erf(v0, v1); > + } > + > + /** {@inheritDoc} */ > + @Override > + protected double getSolverAbsoluteAccuracy() { > + return solverAbsoluteAccuracy; > + } > + > + /** > + * {@inheritDoc} > + * > + * For scale {@code m} and shape {@code s}, the mean is > + * {@code exp(m + s^2 / 2)}. > + */ > + public double getNumericalMean() { > + double s = shape; > + return FastMath.exp(scale + (s * s / 2)); > + } > + > + /** > + * {@inheritDoc} > + * > + * For scale {@code m} and shape {@code s}, the variance is > + * {@code (exp(s^2) - 1) * exp(2 * m + s^2)}. > + */ > + public double getNumericalVariance() { > + final double s = shape; > + final double ss = s * s; > + return (FastMath.exp(ss) - 1) * FastMath.exp(2 * scale + ss); > + } > + > + /** > + * {@inheritDoc} > + * > + * The lower bound of the support is always 0 no matter the > parameters. > + * > + * @return lower bound of the support (always 0) > + */ > + public double getSupportLowerBound() { > + return 0; > + } > + > + /** > + * {@inheritDoc} > + * > + * The upper bound of the support is always positive infinity > + * no matter the parameters. > + * > + * @return upper bound of the support (always > + * {@code Double.POSITIVE_INFINITY}) > + */ > + public double getSupportUpperBound() { > + return Double.POSITIVE_INFINITY; > + } > + > + /** {@inheritDoc} */ > + public boolean isSupportLowerBoundInclusive() { > + return true; > + } > + > + /** {@inheritDoc} */ > + public boolean isSupportUpperBoundInclusive() { > + return false; > + } > + > + /** > + * {@inheritDoc} > + * > + * The support of this distribution is connected. > + * > + * @return {@code true} > + */ > + public boolean isSupportConnected() { > + return true; > + } > + > + /** {@inheritDoc} */ > + @Override > + public double sample() { > + double n = randomData.nextGaussian(0, 1); > + return FastMath.exp(scale + shape * n); > + } > +} > > Propchange: > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > commons/proper/math/trunk/src/main/java/org/apache/commons/math/distribution/LogNormalDistribution.java > > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision > > Added: commons/proper/math/trunk/src/test/R/logNormalTestCases > URL: > http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/R/logNormalTestCases?rev=1232324&view=auto > > ============================================================================== > --- commons/proper/math/trunk/src/test/R/logNormalTestCases (added) > +++ commons/proper/math/trunk/src/test/R/logNormalTestCases Tue Jan 17 > 07:12:02 2012 > @@ -0,0 +1,107 @@ > +# Licensed to the Apache Software Foundation (ASF) under one or more > +# contributor license agreements. See the NOTICE file distributed with > +# this work for additional information regarding copyright ownership. > +# The ASF licenses this file to You under the Apache License, Version 2.0 > +# (the "License"); you may not use this file except in compliance with > +# the License. You may obtain a copy of the License at > +# > +# http://www.apache.org/licenses/LICENSE-2.0 > +# > +# Unless required by applicable law or agreed to in writing, software > +# distributed under the License is distributed on an "AS IS" BASIS, > +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +# See the License for the specific language governing permissions and > +# limitations under the License. > +# > > +#------------------------------------------------------------------------------ > +# R source file to validate LogNormal distribution tests in > +# org.apache.commons.math.distribution.LogNormalDistributionTest > +# > +# To run the test, install R, put this file and testFunctions > +# into the same directory, launch R from this directory and then enter > +# source("") > +# > +# R functions used > +# plnorm(q, mean=0, sd=1, lower.tail = TRUE, log.p = FALSE) <-- > distribution > > +#----------------------------------------------------------------------------- > +tol <- 1E-9 > + > +# Function definitions > + > +source("testFunctions") # utility test functions > + > +# function to verify distribution computations > + > +verifyDistribution <- function(points, expected, mu, sigma, tol) { > + rDistValues <- rep(0, length(points)) > + i <- 0 > + for (point in points) { > + i <- i + 1 > + rDistValues[i] <- plnorm(point, mu, sigma, log = FALSE) > + } > + output <- c("Distribution test mu = ",mu,", sigma = ", sigma) > + if (assertEquals(expected, rDistValues, tol, "Distribution Values")) { > + displayPadded(output, SUCCEEDED, WIDTH) > + } else { > + displayPadded(output, FAILED, WIDTH) > + } > +} > + > +# function to verify density computations > + > +verifyDensity <- function(points, expected, mu, sigma, tol) { > + rDensityValues <- rep(0, length(points)) > + i <- 0 > + for (point in points) { > + i <- i + 1 > + rDensityValues[i] <- dlnorm(point, mu, sigma, log = FALSE) > + } > + output <- c("Density test mu = ",mu,", sigma = ", sigma) > + if (assertEquals(expected, rDensityValues, tol, "Density Values")) { > + displayPadded(output, SUCCEEDED, WIDTH) > + } else { > + displayPadded(output, FAILED, WIDTH) > + } > +} > + > > +#-------------------------------------------------------------------------- > +cat("LogNormal test cases\n") > + > +mu <- 2.1 > +sigma <- 1.4 > +distributionValues <- c(0, 0, 0, 0, 0.00948199951485, 0.432056525076, > 0.381648158697, 0.354555726206, 0.329513316888, 0.298422824228) > +densityValues <- c(0, 0, 0, 0, 0.0594218160072, 0.0436977691036, > 0.0508364857798, 0.054873528325, 0.0587182664085, 0.0636229042785) > +distributionPoints <- c(-2.226325228634938, -1.156887023657177, > -0.643949578356075, -0.2027950777320613, 0.305827808237559, > + 6.42632522863494, 5.35688702365718, 4.843949578356074, > 4.40279507773206, 3.89417219176244) > +verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) > +verifyDensity(distributionPoints, densityValues, mu, sigma, tol) > + > +distributionValues <- c(0, 0.0396495152787, 0.16601209243, > 0.272533253269, 0.357618409638, 0.426488363093, 0.483255136841, > 0.530823013877) > +densityValues <- c(0, 0.0873055825147, 0.0847676303432, 0.0677935186237, > 0.0544105523058, 0.0444614628804, 0.0369750288945, 0.0312206409653) > +distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, > + mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, > + mu + 5 * sigma) > +verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) > +verifyDensity(distributionPoints, densityValues, mu, sigma, tol) > + > +mu <- 0 > +sigma <- 1 > +distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, > + mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, > + mu + 5 * sigma) > +distributionValues <- c(0, 0, 0, 0.5, 0.755891404214, 0.864031392359, > 0.917171480998, 0.946239689548) > +densityValues <- c(0, 0, 0, 0.398942280401, 0.156874019279, > 0.07272825614, 0.0381534565119, 0.0218507148303) > +verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) > +verifyDensity(distributionPoints, densityValues, mu, sigma, tol) > + > +mu <- 0 > +sigma <- 0.1 > +distributionPoints <- c(mu - 2 *sigma, mu - sigma, mu, mu + sigma, > + mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma, > + mu + 5 * sigma) > +distributionValues <- c(0, 0, 0, 1.28417563064e-117, 1.39679883412e-58, > 1.09839325447e-33, 2.52587961726e-20, 2.0824223487e-12) > +densityValues <- c(0, 0, 0, 2.96247992535e-114, 1.1283370232e-55, > 4.43812313223e-31, 5.85346445002e-18, 2.9446618076e-10) > +verifyDistribution(distributionPoints, distributionValues, mu, sigma, tol) > +verifyDensity(distributionPoints, densityValues, mu, sigma, tol) > + > +displayDashes(WIDTH) > > Propchange: commons/proper/math/trunk/src/test/R/logNormalTestCases > > ------------------------------------------------------------------------------ > svn:eol-style = native > > Added: > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java?rev=1232324&view=auto > > ============================================================================== > --- > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > (added) > +++ > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > Tue Jan 17 07:12:02 2012 > @@ -0,0 +1,245 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one or more > + * contributor license agreements. See the NOTICE file distributed with > + * this work for additional information regarding copyright ownership. > + * The ASF licenses this file to You under the Apache License, Version 2.0 > + * (the "License"); you may not use this file except in compliance with > + * the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, software > + * distributed under the License is distributed on an "AS IS" BASIS, > + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or > implied. > + * See the License for the specific language governing permissions and > + * limitations under the License. > + */ > + > +package org.apache.commons.math.distribution; > + > +import org.apache.commons.math.exception.NotStrictlyPositiveException; > +import org.junit.Assert; > +import org.junit.Test; > + > +/** > + * Test cases for {@link LogNormalDistribution}. Extends > + * {@link RealDistributionAbstractTest}. See class javadoc of that class > + * for details. > + * > + * @version $Id$ > + * @since 3.0 > + */ > +public class LogNormalDistributionTest extends > RealDistributionAbstractTest { > + > + //-------------- Implementations for abstract methods > ----------------------- > + > + /** Creates the default real distribution instance to use in tests. */ > + @Override > + public LogNormalDistribution makeDistribution() { > + return new LogNormalDistribution(2.1, 1.4); > + } > + > + /** Creates the default cumulative probability distribution test > input values */ > + @Override > + public double[] makeCumulativeTestPoints() { > + // quantiles computed using R > + return new double[] { -2.226325228634938, -1.156887023657177, > + -0.643949578356075, -0.2027950777320613, > + 0.305827808237559, 6.42632522863494, > + 5.35688702365718, 4.843949578356074, > + 4.40279507773206, 3.89417219176244 }; > + } > + > + /** Creates the default cumulative probability density test expected > values */ > + @Override > + public double[] makeCumulativeTestValues() { > + return new double[] { 0, 0, 0, 0, 0.00948199951485, > 0.432056525076, > + 0.381648158697, 0.354555726206, > 0.329513316888, > + 0.298422824228 }; > + } > + > + /** Creates the default probability density test expected values */ > + @Override > + public double[] makeDensityTestValues() { > + return new double[] { 0, 0, 0, 0, 0.0594218160072, > 0.0436977691036, > + 0.0508364857798, 0.054873528325, > 0.0587182664085, > + 0.0636229042785 }; > + } > + > + /** > + * Creates the default inverse cumulative probability distribution > test > + * input values. > + */ > + @Override > + public double[] makeInverseCumulativeTestPoints() { > + // Exclude the test points less than zero, as they have cumulative > + // probability of zero, meaning the inverse returns zero, and not > the > + // points less than zero. > + double[] points = makeCumulativeTestValues(); > + double[] points2 = new double[points.length - 4]; > + System.arraycopy(points, 4, points2, 0, points2.length - 4); > + return points2; > + //return Arrays.copyOfRange(points, 4, points.length - 4); > + } > + > + /** > + * Creates the default inverse cumulative probability test expected > + * values. > + */ > + @Override > + public double[] makeInverseCumulativeTestValues() { > + // Exclude the test points less than zero, as they have cumulative > + // probability of zero, meaning the inverse returns zero, and not > the > + // points less than zero. > + double[] points = makeCumulativeTestPoints(); > + double[] points2 = new double[points.length - 4]; > + System.arraycopy(points, 4, points2, 0, points2.length - 4); > + return points2; > + //return Arrays.copyOfRange(points, 1, points.length - 4); > + } > + > + // --------------------- Override tolerance -------------- > + @Override > + public void setUp() throws Exception { > + super.setUp(); > + > setTolerance(LogNormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY); > + } > + > + //---------------------------- Additional test cases > ------------------------- > + > + private void verifyQuantiles() throws Exception { > + LogNormalDistribution distribution = > (LogNormalDistribution)getDistribution(); > + double mu = distribution.getScale(); > + double sigma = distribution.getShape(); > + setCumulativeTestPoints( new double[] { mu - 2 *sigma, mu - sigma, > + mu, mu + sigma, mu + 2 * > sigma, > + mu + 3 * sigma,mu + 4 * > sigma, > + mu + 5 * sigma }); > + verifyCumulativeProbabilities(); > + } > + > + @Test > + public void testQuantiles() throws Exception { > + setCumulativeTestValues(new double[] {0, 0.0396495152787, > + 0.16601209243, > 0.272533253269, > + 0.357618409638, > 0.426488363093, > + 0.483255136841, > 0.530823013877}); > + setDensityTestValues(new double[] {0, 0.0873055825147, > 0.0847676303432, > + 0.0677935186237, > 0.0544105523058, > + 0.0444614628804, > 0.0369750288945, > + 0.0312206409653}); > + verifyQuantiles(); > + verifyDensities(); > + > + setDistribution(new LogNormalDistribution(0, 1)); > + setCumulativeTestValues(new double[] {0, 0, 0, 0.5, > 0.755891404214, > + 0.864031392359, > 0.917171480998, > + 0.946239689548}); > + setDensityTestValues(new double[] {0, 0, 0, 0.398942280401, > + 0.156874019279, 0.07272825614, > + 0.0381534565119, > 0.0218507148303}); > + verifyQuantiles(); > + verifyDensities(); > + > + setDistribution(new LogNormalDistribution(0, 0.1)); > + setCumulativeTestValues(new double[] {0, 0, 0, 1.28417563064e-117, > + 1.39679883412e-58, > + 1.09839325447e-33, > + 2.52587961726e-20, > + 2.0824223487e-12}); > + setDensityTestValues(new double[] {0, 0, 0, 2.96247992535e-114, > + 1.1283370232e-55, > 4.43812313223e-31, > + 5.85346445002e-18, > + 2.9446618076e-10}); > + verifyQuantiles(); > + verifyDensities(); > + } > + > + @Test > + public void testInverseCumulativeProbabilityExtremes() throws > Exception { > + setInverseCumulativeTestPoints(new double[] {0, 1}); > + setInverseCumulativeTestValues( > + new double[] {0, Double.POSITIVE_INFINITY}); > + verifyInverseCumulativeProbabilities(); > + } > + > + @Test > + public void testGetMean() { > + LogNormalDistribution distribution = > (LogNormalDistribution)getDistribution(); > + Assert.assertEquals(2.1, distribution.getScale(), 0); > + } > + > + @Test > + public void testGetStandardDeviation() { > + LogNormalDistribution distribution = > (LogNormalDistribution)getDistribution(); > + Assert.assertEquals(1.4, distribution.getShape(), 0); > + } > + > + @Test(expected=NotStrictlyPositiveException.class) > + public void testPreconditions() { > + new LogNormalDistribution(1, 0); > + } > + > + @Test > + public void testDensity() { > + double [] x = new double[]{-2, -1, 0, 1, 2}; > + // R 2.13: print(dlnorm(c(-2,-1,0,1,2)), digits=10) > + checkDensity(0, 1, x, new double[] { 0.0000000000, 0.0000000000, > + 0.0000000000, 0.3989422804, > + 0.1568740193 }); > + // R 2.13: print(dlnorm(c(-2,-1,0,1,2), mean=1.1), digits=10) > + checkDensity(1.1, 1, x, new double[] { 0.0000000000, 0.0000000000, > + 0.0000000000, 0.2178521770, > + 0.1836267118}); > + } > + > + private void checkDensity(double mean, double sd, double[] x, > double[] expected) { > + LogNormalDistribution d = new LogNormalDistribution(mean, sd); > + for (int i = 0; i < x.length; i++) { > + Assert.assertEquals(expected[i], d.density(x[i]), 1e-9); > + } > + } > + > + /** > + * Check to make sure top-coding of extreme values works correctly. > + * Verifies fixes for JIRA MATH-167, MATH-414 > + */ > + @Test > + public void testExtremeValues() throws Exception { > + LogNormalDistribution d = new LogNormalDistribution(0, 1); > + for (int i = 0; i < 1e5; i++) { // make sure no convergence > exception > + double upperTail = d.cumulativeProbability(i); > + if (i <= 72) { // make sure not top-coded > + Assert.assertTrue(upperTail < 1.0d); > + } > + else { // make sure top coding not reversed > + Assert.assertTrue(upperTail > 0.99999); > + } > + } > + > + Assert.assertEquals(d.cumulativeProbability(Double.MAX_VALUE), 1, > 0); > + Assert.assertEquals(d.cumulativeProbability(-Double.MAX_VALUE), > 0, 0); > + > Assert.assertEquals(d.cumulativeProbability(Double.POSITIVE_INFINITY), 1, > 0); > + > Assert.assertEquals(d.cumulativeProbability(Double.NEGATIVE_INFINITY), 0, > 0); > + } > + > + @Test > + public void testMeanVariance() { > + final double tol = 1e-9; > + LogNormalDistribution dist; > + > + dist = new LogNormalDistribution(0, 1); > + Assert.assertEquals(dist.getNumericalMean(), 1.6487212707001282, > tol); > + Assert.assertEquals(dist.getNumericalVariance(), > + 4.670774270471604, tol); > + > + dist = new LogNormalDistribution(2.2, 1.4); > + Assert.assertEquals(dist.getNumericalMean(), 24.046753552064498, > tol); > + Assert.assertEquals(dist.getNumericalVariance(), > + 3526.913651880464, tol); > + > + dist = new LogNormalDistribution(-2000.9, 10.4); > + Assert.assertEquals(dist.getNumericalMean(), 0.0, tol); > + Assert.assertEquals(dist.getNumericalVariance(), 0.0, tol); > + } > +} > > Propchange: > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/LogNormalDistributionTest.java > > ------------------------------------------------------------------------------ > svn:keywords = Author Date Id Revision > > Modified: > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java > URL: > http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java?rev=1232324&r1=1232323&r2=1232324&view=diff > > ============================================================================== > --- > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java > (original) > +++ > commons/proper/math/trunk/src/test/java/org/apache/commons/math/distribution/NormalDistributionTest.java > Tue Jan 17 07:12:02 2012 > @@ -22,9 +22,9 @@ import org.junit.Assert; > import org.junit.Test; > > /** > - * Test cases for NormalDistribution. > - * Extends ContinuousDistributionAbstractTest. See class javadoc for > - * ContinuousDistributionAbstractTest for details. > + * Test cases for {@link NormalDistribution}. Extends > + * {@link RealDistributionAbstractTest}. See class javadoc of that class > + * for details. > * > * @version $Id$ > */ > @@ -32,7 +32,7 @@ public class NormalDistributionTest exte > > //-------------- Implementations for abstract methods > ----------------------- > > - /** Creates the default continuous distribution instance to use in > tests. */ > + /** Creates the default real distribution instance to use in tests. */ > @Override > public NormalDistribution makeDistribution() { > return new NormalDistribution(2.1, 1.4); > @@ -170,8 +170,7 @@ public class NormalDistributionTest exte > > Assert.assertEquals(distribution.cumulativeProbability(-Double.MAX_VALUE), > 0, 0); > > Assert.assertEquals(distribution.cumulativeProbability(Double.POSITIVE_INFINITY), > 1, 0); > > Assert.assertEquals(distribution.cumulativeProbability(Double.NEGATIVE_INFINITY), > 0, 0); > - > - } > + } > > @Test > public void testMath280() { > > > --20cf30563c21ae6b9704b6b41c85--