001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.math.distribution;
019
020 import org.apache.commons.math.MathException;
021
022 /**
023 * Test cases for NormalDistribution.
024 * Extends ContinuousDistributionAbstractTest. See class javadoc for
025 * ContinuousDistributionAbstractTest for details.
026 *
027 * @version $Revision: 791766 $ $Date: 2009-07-07 05:19:46 -0400 (Tue, 07 Jul 2009) $
028 */
029 public class NormalDistributionTest extends ContinuousDistributionAbstractTest {
030
031 /**
032 * Constructor for NormalDistributionTest.
033 * @param arg0
034 */
035 public NormalDistributionTest(String arg0) {
036 super(arg0);
037 }
038
039 //-------------- Implementations for abstract methods -----------------------
040
041 /** Creates the default continuous distribution instance to use in tests. */
042 @Override
043 public ContinuousDistribution makeDistribution() {
044 return new NormalDistributionImpl(2.1, 1.4);
045 }
046
047 /** Creates the default cumulative probability distribution test input values */
048 @Override
049 public double[] makeCumulativeTestPoints() {
050 // quantiles computed using R
051 return new double[] {-2.226325d, -1.156887d, -0.6439496d, -0.2027951d, 0.3058278d,
052 6.426325d, 5.356887d, 4.84395d, 4.402795d, 3.894172d};
053 }
054
055 /** Creates the default cumulative probability density test expected values */
056 @Override
057 public double[] makeCumulativeTestValues() {
058 return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.999d,
059 0.990d, 0.975d, 0.950d, 0.900d};
060 }
061
062 // --------------------- Override tolerance --------------
063 @Override
064 protected void setUp() throws Exception {
065 super.setUp();
066 setTolerance(1E-6);
067 }
068
069 //---------------------------- Additional test cases -------------------------
070
071 private void verifyQuantiles() throws Exception {
072 NormalDistribution distribution = (NormalDistribution) getDistribution();
073 double mu = distribution.getMean();
074 double sigma = distribution.getStandardDeviation();
075 setCumulativeTestPoints( new double[] {mu - 2 *sigma, mu - sigma,
076 mu, mu + sigma, mu +2 * sigma, mu +3 * sigma, mu + 4 * sigma,
077 mu + 5 * sigma});
078 // Quantiles computed using R (same as Mathematica)
079 setCumulativeTestValues(new double[] {0.02275013, 0.1586553, 0.5, 0.8413447,
080 0.9772499, 0.9986501, 0.9999683, 0.9999997});
081 verifyCumulativeProbabilities();
082 }
083
084 public void testQuantiles() throws Exception {
085 verifyQuantiles();
086 setDistribution(new NormalDistributionImpl(0, 1));
087 verifyQuantiles();
088 setDistribution(new NormalDistributionImpl(0, 0.1));
089 verifyQuantiles();
090 }
091
092 public void testInverseCumulativeProbabilityExtremes() throws Exception {
093 setInverseCumulativeTestPoints(new double[] {0, 1});
094 setInverseCumulativeTestValues(
095 new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
096 verifyInverseCumulativeProbabilities();
097 }
098
099 public void testGetMean() {
100 NormalDistribution distribution = (NormalDistribution) getDistribution();
101 assertEquals(2.1, distribution.getMean(), 0);
102 }
103
104 public void testSetMean() throws Exception {
105 double mu = Math.random();
106 NormalDistribution distribution = (NormalDistribution) getDistribution();
107 distribution.setMean(mu);
108 verifyQuantiles();
109 }
110
111 public void testGetStandardDeviation() {
112 NormalDistribution distribution = (NormalDistribution) getDistribution();
113 assertEquals(1.4, distribution.getStandardDeviation(), 0);
114 }
115
116 public void testSetStandardDeviation() throws Exception {
117 double sigma = 0.1d + Math.random();
118 NormalDistribution distribution = (NormalDistribution) getDistribution();
119 distribution.setStandardDeviation(sigma);
120 assertEquals(sigma, distribution.getStandardDeviation(), 0);
121 verifyQuantiles();
122 try {
123 distribution.setStandardDeviation(0);
124 fail("Expecting IllegalArgumentException for sd = 0");
125 } catch (IllegalArgumentException ex) {
126 // Expected
127 }
128 }
129
130 public void testDensity() {
131 double [] x = new double[]{-2, -1, 0, 1, 2};
132 // R 2.5: print(dnorm(c(-2,-1,0,1,2)), digits=10)
133 checkDensity(0, 1, x, new double[]{0.05399096651, 0.24197072452, 0.39894228040, 0.24197072452, 0.05399096651});
134 // R 2.5: print(dnorm(c(-2,-1,0,1,2), mean=1.1), digits=10)
135 checkDensity(1.1, 1, x, new double[]{0.003266819056,0.043983595980,0.217852177033,0.396952547477,0.266085249899});
136 }
137
138 private void checkDensity(double mean, double sd, double[] x, double[] expected) {
139 NormalDistribution d = new NormalDistributionImpl(mean, sd);
140 for (int i = 0; i < x.length; i++) {
141 assertEquals(expected[i], d.density(x[i]), 1e-9);
142 }
143 }
144
145 /**
146 * Check to make sure top-coding of extreme values works correctly.
147 * Verifies fix for JIRA MATH-167
148 */
149 public void testExtremeValues() throws Exception {
150 NormalDistribution distribution = (NormalDistribution) getDistribution();
151 distribution.setMean(0);
152 distribution.setStandardDeviation(1);
153 for (int i = 0; i < 100; i+=5) { // make sure no convergence exception
154 double lowerTail = distribution.cumulativeProbability(-i);
155 double upperTail = distribution.cumulativeProbability(i);
156 if (i < 10) { // make sure not top-coded
157 assertTrue(lowerTail > 0.0d);
158 assertTrue(upperTail < 1.0d);
159 }
160 else { // make sure top coding not reversed
161 assertTrue(lowerTail < 0.00001);
162 assertTrue(upperTail > 0.99999);
163 }
164 }
165 }
166
167 public void testMath280() throws MathException {
168 NormalDistribution normal = new NormalDistributionImpl(0,1);
169 double result = normal.inverseCumulativeProbability(0.9772498680518209);
170 assertEquals(2.0, result, 1.0e-12);
171 }
172
173 }