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    }