1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math.distribution;
19  
20  /**
21   * Test cases for NormalDistribution.
22   * Extends ContinuousDistributionAbstractTest.  See class javadoc for
23   * ContinuousDistributionAbstractTest for details.
24   * 
25   * @version $Revision: 563850 $ $Date: 2007-08-08 06:18:46 -0700 (Wed, 08 Aug 2007) $
26   */
27  public class NormalDistributionTest extends ContinuousDistributionAbstractTest  {
28      
29      /**
30       * Constructor for NormalDistributionTest.
31       * @param arg0
32       */
33      public NormalDistributionTest(String arg0) {
34          super(arg0);
35      }
36      
37      //-------------- Implementations for abstract methods -----------------------
38      
39      /** Creates the default continuous distribution instance to use in tests. */
40      public ContinuousDistribution makeDistribution() {
41          return new NormalDistributionImpl(2.1, 1.4);
42      }   
43      
44      /** Creates the default cumulative probability distribution test input values */
45      public double[] makeCumulativeTestPoints() {
46          // quantiles computed using R 
47          return new double[] {-2.226325d, -1.156887d, -0.6439496d, -0.2027951d, 0.3058278d, 
48                  6.426325d, 5.356887d, 4.84395d, 4.402795d, 3.894172d};
49      }
50      
51      /** Creates the default cumulative probability density test expected values */
52      public double[] makeCumulativeTestValues() {
53          return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.999d,
54                  0.990d, 0.975d, 0.950d, 0.900d}; 
55      }
56      
57      // --------------------- Override tolerance  --------------
58      protected void setUp() throws Exception {
59          super.setUp();
60          setTolerance(1E-6);
61      }
62      
63      //---------------------------- Additional test cases -------------------------
64      
65      private void verifyQuantiles() throws Exception {
66          NormalDistribution distribution = (NormalDistribution) getDistribution();
67          double mu = distribution.getMean();
68          double sigma = distribution.getStandardDeviation();
69          setCumulativeTestPoints( new double[] {mu - 2 *sigma, mu - sigma, 
70                  mu, mu + sigma, mu +2 * sigma,  mu +3 * sigma, mu + 4 * sigma,
71                  mu + 5 * sigma});
72          // Quantiles computed using R (same as Mathematica)
73          setCumulativeTestValues(new double[] {0.02275013, 0.1586553, 0.5, 0.8413447, 
74                  0.9772499, 0.9986501, 0.9999683,  0.9999997});
75          verifyCumulativeProbabilities();       
76      }
77      
78      public void testQuantiles() throws Exception {
79          verifyQuantiles();
80          setDistribution(new NormalDistributionImpl(0, 1));
81          verifyQuantiles();
82          setDistribution(new NormalDistributionImpl(0, 0.1));
83          verifyQuantiles();
84      }
85      
86      public void testInverseCumulativeProbabilityExtremes() throws Exception {
87          setInverseCumulativeTestPoints(new double[] {0, 1});
88          setInverseCumulativeTestValues(
89                  new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
90          verifyInverseCumulativeProbabilities();
91      }
92      
93      public void testGetMean() {
94          NormalDistribution distribution = (NormalDistribution) getDistribution();
95          assertEquals(2.1, distribution.getMean(), 0);
96      }
97      
98      public void testSetMean() throws Exception {
99          double mu = Math.random();
100         NormalDistribution distribution = (NormalDistribution) getDistribution();
101         distribution.setMean(mu);
102         verifyQuantiles();
103     }
104     
105     public void testGetStandardDeviation() {
106         NormalDistribution distribution = (NormalDistribution) getDistribution();
107         assertEquals(1.4, distribution.getStandardDeviation(), 0);  
108     }
109     
110     public void testSetStandardDeviation() throws Exception {
111         double sigma = 0.1d + Math.random();
112         NormalDistribution distribution = (NormalDistribution) getDistribution();
113         distribution.setStandardDeviation(sigma);
114         assertEquals(sigma, distribution.getStandardDeviation(), 0);
115         verifyQuantiles();
116         try {
117             distribution.setStandardDeviation(0);
118             fail("Expecting IllegalArgumentException for sd = 0");
119         } catch (IllegalArgumentException ex) {
120             // Expected
121         }
122     }
123     
124     /**
125      * Check to make sure top-coding of extreme values works correctly.
126      * Verifies fix for JIRA MATH-167
127      */
128     public void testExtremeValues() throws Exception {
129         NormalDistribution distribution = (NormalDistribution) getDistribution();
130         distribution.setMean(0);
131         distribution.setStandardDeviation(1);
132         for (int i = 0; i < 100; i+=5) { // make sure no convergence exception
133             double lowerTail = distribution.cumulativeProbability((double)-i);
134             double upperTail = distribution.cumulativeProbability((double) i);
135             if (i < 10) { // make sure not top-coded
136                 assertTrue(lowerTail > 0.0d);
137                 assertTrue(upperTail < 1.0d);
138             }
139             else { // make sure top coding not reversed
140                 assertTrue(lowerTail < 0.00001);
141                 assertTrue(upperTail > 0.99999);
142             }
143         } 
144    }
145 }