    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: 1.19 $ $Date: 2004/10/08 05:08:19 $
    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
    120     /***
    121       * Generate 1000 random values and make sure they look OK.<br>
    122       * Note that there is a non-zero (but very small) probability that
    123       * these tests will fail even if the code is working as designed.
    124       */
    125     public void testNext() throws Exception {
    126         tstGen(0.1);
    127         tstDoubleGen(0.1);
    128     }
    129
    130     /***
    131       * Make sure exception thrown if digest getNext is attempted
    132       * before loading empiricalDistribution.
    133      */
    134     public void testNexFail() {
    135         try {
    136             empiricalDistribution.getNextValue();
    137             empiricalDistribution2.getNextValue();
    138             fail("Expecting IllegalStateException");
    139         } catch (IllegalStateException ex) {;}
    140     }
    141
    142     /***
    143      * Make sure we can handle a grid size that is too fine
    144      */
    145     public void testGridTooFine() throws Exception {
    146         empiricalDistribution = new EmpiricalDistributionImpl(1001);
    147         tstGen(0.1);
    148         empiricalDistribution2 = new EmpiricalDistributionImpl(1001);
    149         tstDoubleGen(0.1);
    150     }
    151
    152     /***
    153      * How about too fat?
    154      */
    155     public void testGridTooFat() throws Exception {
    156         empiricalDistribution = new EmpiricalDistributionImpl(1);
    157         tstGen(5); // ridiculous tolerance; but ridiculous grid size
    158                    // really just checking to make sure we do not bomb
    159         empiricalDistribution2 = new EmpiricalDistributionImpl(1);
    160         tstDoubleGen(5);
    161     }
    162
    163     public void testSerialization() {
    164         // Empty
    165         EmpiricalDistribution dist = new EmpiricalDistributionImpl();
    166         EmpiricalDistribution dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(dist);
    167         verifySame(dist, dist2);
    168
    169         // Loaded
    170         empiricalDistribution2.load(dataArray);
    171         dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(empiricalDistribution2);
    172         verifySame(empiricalDistribution2, dist2);
    173     }
    174
    175     private void verifySame(EmpiricalDistribution d1, EmpiricalDistribution d2) {
    176         assertEquals(d1.isLoaded(), d2.isLoaded());
    177         assertEquals(d1.getBinCount(), d2.getBinCount());
    178         assertEquals(d1.getSampleStats(), d2.getSampleStats());
    179         if (d1.isLoaded()) {
    180             for (int i = 0;  i < d1.getUpperBounds().length; i++) {
    181                 assertEquals(d1.getUpperBounds()[i], d2.getUpperBounds()[i], 0);
    182             }
    183             assertEquals(d1.getBinStats(), d2.getBinStats());
    184         }
    185     }
    186
    187     private void tstGen(double tolerance)throws Exception {
    188         empiricalDistribution.load(url);
    189         SummaryStatistics stats = SummaryStatistics.newInstance();
    190         for (int i = 1; i < 1000; i++) {
    191             stats.addValue(empiricalDistribution.getNextValue());
    192         }
    193         assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
    194         assertEquals
    195          ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
    196     }
    197
    198     private void tstDoubleGen(double tolerance)throws Exception {
    199         empiricalDistribution2.load(dataArray);
    200         SummaryStatistics stats = SummaryStatistics.newInstance();
    201         for (int i = 1; i < 1000; i++) {
    202             stats.addValue(empiricalDistribution2.getNextValue());
    203         }
    204         assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
    205         assertEquals
    206          ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
    207     }
    208 }