    1   /*
    2    * Copyright 2003-2004 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.math.random;
    17
    18  import junit.framework.Test;
    19  import junit.framework.TestSuite;
    20
    21  import java.io.BufferedReader;
    22  import java.io.File;
    23  import java.io.IOException;
    24  import java.io.InputStreamReader;
    25  import java.net.URL;
    26  import java.util.ArrayList;
    27  import java.util.Iterator;
    28
    29  import org.apache.commons.math.RetryTestCase;
    30  import org.apache.commons.math.TestUtils;
    31  import org.apache.commons.math.stat.descriptive.SummaryStatistics;
    32
    33  /***
    34   * Test cases for the EmpiricalDistribution class
    35   *
    36   * @version $Revision: 348772 $ $Date: 2005-11-24 10:26:34 -0700 (Thu, 24 Nov 2005) $
    37   */
    38
    39  public final class EmpiricalDistributionTest extends RetryTestCase {
    40
    41      protected EmpiricalDistribution empiricalDistribution = null;
    42      protected EmpiricalDistribution empiricalDistribution2 = null;
    43      protected File file = null;
    44      protected URL url = null;
    45      protected double[] dataArray = null;
    46
    47      public EmpiricalDistributionTest(String name) {
    48          super(name);
    49      }
    50
    51      public void setUp() throws IOException {
    52          empiricalDistribution = new EmpiricalDistributionImpl(100);
    53          url = getClass().getResource("testData.txt");
    54
    55          empiricalDistribution2 = new EmpiricalDistributionImpl(100);
    56          BufferedReader in =
    57                  new BufferedReader(new InputStreamReader(
    58                          url.openStream()));
    59          String str = null;
    60          ArrayList list = new ArrayList();
    61          while ((str = in.readLine()) != null) {
    62              list.add(Double.valueOf(str));
    63          }
    64          in.close();
    65          in = null;
    66
    67          dataArray = new double[list.size()];
    68          int i = 0;
    69          for (Iterator iter = list.iterator(); iter.hasNext();) {
    70              dataArray[i] = ((Double)iter.next()).doubleValue();
    71              i++;
    72          }
    73      }
    74
    75      public static Test suite() {
    76          TestSuite suite = new TestSuite(EmpiricalDistributionTest.class);
    77          suite.setName("EmpiricalDistribution Tests");
    78          return suite;
    79      }
    80
    81      /***
    82       * Test EmpiricalDistrbution.load() using sample data file.<br>
    83       * Check that the sampleCount, mu and sigma match data in
    84       * the sample data file.
    85       */
    86      public void testLoad() throws Exception {
    87          empiricalDistribution.load(url);
    88          // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1
    89          // Make sure that loaded distribution matches this
    90          assertEquals(empiricalDistribution.getSampleStats().getN(),1000,10E-7);
    91          //TODO: replace with statistical tests
    92          assertEquals
    93              (empiricalDistribution.getSampleStats().getMean(),
    94                  5.069831575018909,10E-7);
    95          assertEquals
    96            (empiricalDistribution.getSampleStats().getStandardDeviation(),
    97                  1.0173699343977738,10E-7);
    98      }
    99
    100     /***
    101      * Test EmpiricalDistrbution.load(double[]) using data taken from
    102      * sample data file.<br>
    103      * Check that the sampleCount, mu and sigma match data in
    104      * the sample data file.
    105      */
    106     public void testDoubleLoad() throws Exception {
    107         empiricalDistribution2.load(dataArray);
    108         // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1
    109         // Make sure that loaded distribution matches this
    110         assertEquals(empiricalDistribution2.getSampleStats().getN(),1000,10E-7);
    111         //TODO: replace with statistical tests
    112         assertEquals
    113             (empiricalDistribution2.getSampleStats().getMean(),
    114                 5.069831575018909,10E-7);
    115         assertEquals
    116           (empiricalDistribution2.getSampleStats().getStandardDeviation(),
    117                 1.0173699343977738,10E-7);
    118
    119         double[] bounds = empiricalDistribution2.getUpperBounds();
    120         assertEquals(bounds.length, 100);
    121         assertEquals(bounds[99], 1.0, 10e-12);
    122
    123     }
    124
    125     /***
    126       * Generate 1000 random values and make sure they look OK.<br>
    127       * Note that there is a non-zero (but very small) probability that
    128       * these tests will fail even if the code is working as designed.
    129       */
    130     public void testNext() throws Exception {
    131         tstGen(0.1);
    132         tstDoubleGen(0.1);
    133     }
    134
    135     /***
    136       * Make sure exception thrown if digest getNext is attempted
    137       * before loading empiricalDistribution.
    138      */
    139     public void testNexFail() {
    140         try {
    141             empiricalDistribution.getNextValue();
    142             empiricalDistribution2.getNextValue();
    143             fail("Expecting IllegalStateException");
    144         } catch (IllegalStateException ex) {;}
    145     }
    146
    147     /***
    148      * Make sure we can handle a grid size that is too fine
    149      */
    150     public void testGridTooFine() throws Exception {
    151         empiricalDistribution = new EmpiricalDistributionImpl(1001);
    152         tstGen(0.1);
    153         empiricalDistribution2 = new EmpiricalDistributionImpl(1001);
    154         tstDoubleGen(0.1);
    155     }
    156
    157     /***
    158      * How about too fat?
    159      */
    160     public void testGridTooFat() throws Exception {
    161         empiricalDistribution = new EmpiricalDistributionImpl(1);
    162         tstGen(5); // ridiculous tolerance; but ridiculous grid size
    163                    // really just checking to make sure we do not bomb
    164         empiricalDistribution2 = new EmpiricalDistributionImpl(1);
    165         tstDoubleGen(5);
    166     }
    167
    168     /***
    169      * Test bin index overflow problem (BZ 36450)
    170      */
    171     public void testBinIndexOverflow() throws Exception {
    172         double[] x = new double[] {9474.94326071674, 2080107.8865462579};
    173         new EmpiricalDistributionImpl().load(x);
    174     }
    175
    176     public void testSerialization() {
    177         // Empty
    178         EmpiricalDistribution dist = new EmpiricalDistributionImpl();
    179         EmpiricalDistribution dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(dist);
    180         verifySame(dist, dist2);
    181
    182         // Loaded
    183         empiricalDistribution2.load(dataArray);
    184         dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(empiricalDistribution2);
    185         verifySame(empiricalDistribution2, dist2);
    186     }
    187
    188     private void verifySame(EmpiricalDistribution d1, EmpiricalDistribution d2) {
    189         assertEquals(d1.isLoaded(), d2.isLoaded());
    190         assertEquals(d1.getBinCount(), d2.getBinCount());
    191         assertEquals(d1.getSampleStats(), d2.getSampleStats());
    192         if (d1.isLoaded()) {
    193             for (int i = 0;  i < d1.getUpperBounds().length; i++) {
    194                 assertEquals(d1.getUpperBounds()[i], d2.getUpperBounds()[i], 0);
    195             }
    196             assertEquals(d1.getBinStats(), d2.getBinStats());
    197         }
    198     }
    199
    200     private void tstGen(double tolerance)throws Exception {
    201         empiricalDistribution.load(url);
    202         SummaryStatistics stats = SummaryStatistics.newInstance();
    203         for (int i = 1; i < 1000; i++) {
    204             stats.addValue(empiricalDistribution.getNextValue());
    205         }
    206         assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
    207         assertEquals
    208          ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
    209     }
    210
    211     private void tstDoubleGen(double tolerance)throws Exception {
    212         empiricalDistribution2.load(dataArray);
    213         SummaryStatistics stats = SummaryStatistics.newInstance();
    214         for (int i = 1; i < 1000; i++) {
    215             stats.addValue(empiricalDistribution2.getNextValue());
    216         }
    217         assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
    218         assertEquals
    219          ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
    220     }
    221 }