View Javadoc
1   package org.djutils.stats.summarizers.quantileaccumulator;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertTrue;
5   import static org.junit.Assert.fail;
6   
7   import org.junit.Test;
8   
9   /**
10   * FixedBinsAccumulatorTest.java. <br>
11   * <br>
12   * Copyright (c) 2021-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
13   * for project information <a href="https://djutils.org" target="_blank"> https://djutils.org</a>. The DJUTILS project is
14   * distributed under a three-clause BSD-style license, which can be found at
15   * <a href="https://djutils.org/docs/license.html" target="_blank"> https://djutils.org/docs/license.html</a>. <br>
16   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="https://www.tudelft.nl/pknoppers">Peter Knoppers</a>
18   */
19  public class FixedBinsAccumulatorTest
20  {
21      /**
22       * Test the FixedBinsAccumulator.
23       */
24      @Test
25      public void testFixedBinsAccumulator()
26      {
27          try
28          {
29              new FixedBinsAccumulator(Double.NaN, 0.25, 100);
30              fail("Illegal minimumBinCenter should have thrown an IllegalArgumentException");
31          }
32          catch (IllegalArgumentException iae)
33          {
34              // Ignore expected exception
35          }
36  
37          try
38          {
39              new FixedBinsAccumulator(Double.NEGATIVE_INFINITY, 0.25, 100);
40              fail("Illegal minimumBinCenter should have thrown an IllegalArgumentException");
41          }
42          catch (IllegalArgumentException iae)
43          {
44              // Ignore expected exception
45          }
46  
47          try
48          {
49              new FixedBinsAccumulator(Double.POSITIVE_INFINITY, 0.25, 100);
50              fail("Illegal minimumBinCenter should have thrown an IllegalArgumentException");
51          }
52          catch (IllegalArgumentException iae)
53          {
54              // Ignore expected exception
55          }
56  
57          try
58          {
59              new FixedBinsAccumulator(0.0, Double.NaN, 100);
60              fail("Illegal binWidth should have thrown an IllegalArgumentException");
61          }
62          catch (IllegalArgumentException iae)
63          {
64              // Ignore expected exception
65          }
66  
67          try
68          {
69              new FixedBinsAccumulator(0.0, Double.POSITIVE_INFINITY, 100);
70              fail("Illegal binWidth should have thrown an IllegalArgumentException");
71          }
72          catch (IllegalArgumentException iae)
73          {
74              // Ignore expected exception
75          }
76  
77          try
78          {
79              new FixedBinsAccumulator(0.0, Double.NEGATIVE_INFINITY, 100);
80              fail("Illegal binWidth should have thrown an IllegalArgumentException");
81          }
82          catch (IllegalArgumentException iae)
83          {
84              // Ignore expected exception
85          }
86  
87          try
88          {
89              new FixedBinsAccumulator(0.0, 0.0, 100);
90              fail("Illegal binWidth should have thrown an IllegalArgumentException");
91          }
92          catch (IllegalArgumentException iae)
93          {
94              // Ignore expected exception
95          }
96  
97          try
98          {
99              new FixedBinsAccumulator(0.0, 0.25, 0);
100             fail("Illegal binCount should have thrown an IllegalArgumentException");
101         }
102         catch (IllegalArgumentException iae)
103         {
104             // Ignore expected exception
105         }
106 
107         FixedBinsAccumulator fba = new FixedBinsAccumulator(10.0, 0.25, 100);
108         assertEquals("binWidth", 0.25, fba.getBinWidth(), 0.0);
109         assertEquals("bin count", 100, fba.getBinCount());
110         assertEquals("total count", 0, fba.getN());
111         assertEquals("below count", 0, fba.getBelowCount());
112         assertEquals("above count", 0, fba.getAboveCount());
113         assertTrue("quantile cannot be computed yet", Double.isNaN(fba.getQuantile(null, 0.5)));
114 
115         for (int bin = 0; bin < 100; bin++)
116         {
117             assertEquals("Bin center", 10.0 + 0.25 * bin, fba.getBinCenter(bin), 0.0001);
118         }
119         try
120         {
121             fba.getBinCenter(-1);
122             fail("negative bin number should have thrown an IllegalArgumentException");
123         }
124         catch (IllegalArgumentException iae)
125         {
126             // Ignore expected exception
127         }
128 
129         try
130         {
131             fba.getBinCenter(100);
132             fail("Too large bin number should have thrown an IllegalArgumentException");
133         }
134         catch (IllegalArgumentException iae)
135         {
136             // Ignore expected exception
137         }
138 
139         fba = new FixedBinsAccumulator(1, (Math.E - 1) / 1000, 1001);
140         assertEquals("highest bin is near e", Math.E, fba.getBinCenter(fba.getBinCount() - 1), 0.00001);
141         // ingest some values with an exponential density distribution
142         int max = 1000000;
143         for (int i = 0; i < max; i++)
144         {
145             double range0to1 = 1.0 * i / max;
146             double value = Math.exp(range0to1); // Should be in range 0..e
147             fba.register(value);
148         }
149         assertEquals("total values is max", max, fba.getN());
150         assertEquals("no values below 1", 0, fba.getBelowCount());
151         assertEquals("no values above e", 0, fba.getAboveCount());
152         assertEquals("0% quantile", 1.0, fba.getQuantile(null, 0.0), 0.001);
153         assertEquals("100% quantile", Math.E, fba.getQuantile(null, 1.0), Math.E / 1000);
154         assertEquals("50% quantile", Math.sqrt(Math.E), fba.getQuantile(null, 0.5), Math.E / 1000);
155         assertEquals("25% quantile", Math.sqrt(Math.sqrt(Math.E)), fba.getQuantile(null, 0.25), Math.E / 1000);
156         
157         // Check the below and above counters
158         for (int i = 0; i < 5; i++)
159         {
160             fba.register(-i);
161             assertEquals("below counter", i + 1, fba.getBelowCount());
162             assertEquals("above counter", 0, fba.getAboveCount());
163         }
164         for (int i = 0; i < 5; i++)
165         {
166             fba.register(10);
167             assertEquals("below counter", 5, fba.getBelowCount());
168             assertEquals("above counter", i + 1, fba.getAboveCount());
169         }
170         
171         try
172         {
173             fba.getQuantile(null, -0.001);
174             fail("Negative probability should have thrown an IllegalArgumentException");
175         }
176         catch (IllegalArgumentException iae)
177         {
178             // Ignore expected exception
179         }
180         
181         try
182         {
183             fba.getQuantile(null, 1.001);
184             fail("Negative probability should have thrown an IllegalArgumentException");
185         }
186         catch (IllegalArgumentException iae)
187         {
188             // Ignore expected exception
189         }
190         
191         try
192         {
193             fba.getQuantile(null, Double.POSITIVE_INFINITY);
194             fail("Negative probability should have thrown an IllegalArgumentException");
195         }
196         catch (IllegalArgumentException iae)
197         {
198             // Ignore expected exception
199         }
200         
201         try
202         {
203             fba.getQuantile(null, Double.NEGATIVE_INFINITY);
204             fail("Negative probability should have thrown an IllegalArgumentException");
205         }
206         catch (IllegalArgumentException iae)
207         {
208             // Ignore expected exception
209         }
210         
211         try
212         {
213             fba.getQuantile(null, Double.NaN);
214             fail("Negative probability should have thrown an IllegalArgumentException");
215         }
216         catch (IllegalArgumentException iae)
217         {
218             // Ignore expected exception
219         }
220         
221         fba.initialize();
222         assertEquals("binWidth", (Math.E - 1) / 1001, fba.getBinWidth(), 0.00001);
223         assertEquals("bin count", 1001, fba.getBinCount());
224         assertEquals("total count", 0, fba.getN());
225         assertEquals("below count", 0, fba.getBelowCount());
226         assertEquals("above count", 0, fba.getAboveCount());
227         assertTrue("quantile cannot be computed yet", Double.isNaN(fba.getQuantile(null, 0.5)));
228         
229         assertTrue("toString returns something descriptive", fba.toString().startsWith("FixedBinsAccumulator "));
230     }
231 
232 }