View Javadoc
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    *      https://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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.stat.descriptive;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertNotEquals;
26  import static org.junit.Assert.assertTrue;
27  
28  import java.util.Arrays;
29  
30  import org.hipparchus.UnitTestUtils;
31  import org.hipparchus.random.RandomDataGenerator;
32  import org.hipparchus.stat.descriptive.moment.SecondMoment;
33  import org.hipparchus.util.FastMath;
34  import org.junit.Test;
35  
36  /**
37   * Test cases for {@link StorelessUnivariateStatistic} classes.
38   */
39  public abstract class StorelessUnivariateStatisticAbstractTest
40      extends UnivariateStatisticAbstractTest {
41  
42      /** Small sample arrays */
43      protected double[][] smallSamples = {{}, {1}, {1,2}, {1,2,3}, {1,2,3,4}};
44  
45      /** Return a new instance of the statistic */
46      @Override
47      public abstract StorelessUnivariateStatistic getUnivariateStatistic();
48  
49      /**Expected value for the testArray defined in UnivariateStatisticAbstractTest */
50      @Override
51      public abstract double expectedValue();
52  
53      /**
54       * Verifies that increment() and incrementAll work properly.
55       */
56      @Test
57      public void testIncrementation() {
58  
59          StorelessUnivariateStatistic statistic = getUnivariateStatistic();
60  
61          // Add testArray one value at a time and check result
62          for (int i = 0; i < testArray.length; i++) {
63              statistic.increment(testArray[i]);
64          }
65  
66          assertEquals(expectedValue(), statistic.getResult(), getTolerance());
67          assertEquals(testArray.length, statistic.getN());
68  
69          statistic.clear();
70  
71          // Add testArray all at once and check again
72          statistic.incrementAll(testArray);
73          assertEquals(expectedValue(), statistic.getResult(), getTolerance());
74          assertEquals(testArray.length, statistic.getN());
75  
76          statistic.clear();
77  
78          // Cleared
79          checkClearValue(statistic);
80          assertEquals(0, statistic.getN());
81      }
82  
83      protected void checkClearValue(StorelessUnivariateStatistic statistic){
84          assertTrue(Double.isNaN(statistic.getResult()));
85      }
86  
87      @Test
88      public void testSerialization() {
89          StorelessUnivariateStatistic statistic = getUnivariateStatistic();
90  
91          UnitTestUtils.checkSerializedEquality(statistic);
92          statistic.clear();
93  
94          for (int i = 0; i < testArray.length; i++) {
95              statistic.increment(testArray[i]);
96              if(i % 5 == 0) {
97                  statistic = (StorelessUnivariateStatistic)UnitTestUtils.serializeAndRecover(statistic);
98              }
99          }
100 
101         UnitTestUtils.checkSerializedEquality(statistic);
102         assertEquals(expectedValue(), statistic.getResult(), getTolerance());
103 
104         statistic.clear();
105         checkClearValue(statistic);
106     }
107 
108     @Test
109     public void testEqualsAndHashCode() {
110         StorelessUnivariateStatistic statistic = getUnivariateStatistic();
111         StorelessUnivariateStatistic statistic2 = null;
112 
113         assertTrue("non-null, compared to null", !statistic.equals(statistic2));
114         assertTrue("reflexive, non-null", statistic.equals(statistic));
115 
116         int emptyHash = statistic.hashCode();
117         statistic2 = getUnivariateStatistic();
118         assertTrue("empty stats should be equal", statistic.equals(statistic2));
119         assertEquals("empty stats should have the same hashcode",
120                      emptyHash, statistic2.hashCode());
121 
122         statistic.increment(1d);
123         assertTrue("reflexive, non-empty", statistic.equals(statistic));
124         assertTrue("non-empty, compared to empty", !statistic.equals(statistic2));
125         assertTrue("non-empty, compared to empty", !statistic2.equals(statistic));
126         assertTrue("non-empty stat should have different hashcode from empty stat",
127                    statistic.hashCode() != emptyHash);
128 
129         statistic2.increment(1d);
130         assertTrue("stats with same data should be equal", statistic.equals(statistic2));
131         assertEquals("stats with same data should have the same hashcode",
132                      statistic.hashCode(), statistic2.hashCode());
133 
134         statistic.increment(Double.POSITIVE_INFINITY);
135         assertTrue("stats with different n's should not be equal", !statistic2.equals(statistic));
136         assertTrue("stats with different n's should have different hashcodes",
137                    statistic.hashCode() != statistic2.hashCode());
138 
139         statistic2.increment(Double.POSITIVE_INFINITY);
140         assertTrue("stats with same data should be equal", statistic.equals(statistic2));
141         assertEquals("stats with same data should have the same hashcode",
142                      statistic.hashCode(), statistic2.hashCode());
143 
144         statistic.clear();
145         statistic2.clear();
146         assertTrue("cleared stats should be equal", statistic.equals(statistic2));
147         assertEquals("cleared stats should have thashcode of empty stat",
148                      emptyHash, statistic2.hashCode());
149         assertEquals("cleared stats should have thashcode of empty stat",
150                      emptyHash, statistic.hashCode());
151 
152     }
153 
154     @Test
155     public void testMomentSmallSamples() {
156         UnivariateStatistic stat = getUnivariateStatistic();
157         if (stat instanceof SecondMoment) {
158             SecondMoment moment = (SecondMoment) getUnivariateStatistic();
159             assertTrue(Double.isNaN(moment.getResult()));
160             moment.increment(1d);
161             assertEquals(0d, moment.getResult(), 0);
162         }
163     }
164 
165     /**
166      * Make sure that evaluate(double[]) and inrementAll(double[]),
167      * getResult() give same results.
168      */
169     @Test
170     public void testConsistency() {
171         StorelessUnivariateStatistic stat = getUnivariateStatistic();
172         stat.incrementAll(testArray);
173         assertEquals(stat.getResult(), stat.evaluate(testArray), getTolerance());
174         for (int i = 0; i < smallSamples.length; i++) {
175             stat.clear();
176             for (int j =0; j < smallSamples[i].length; j++) {
177                 stat.increment(smallSamples[i][j]);
178             }
179             UnitTestUtils.assertEquals(stat.getResult(), stat.evaluate(smallSamples[i]), getTolerance());
180         }
181     }
182 
183     /**
184      * Verifies that copied statistics remain equal to originals when
185      * incremented the same way.
186      */
187     @Test
188     public void testCopyConsistency() {
189 
190         StorelessUnivariateStatistic master = getUnivariateStatistic();
191 
192         StorelessUnivariateStatistic replica = null;
193 
194         // Randomly select a portion of testArray to load first
195         long index = FastMath.round((FastMath.random()) * testArray.length);
196 
197         // Put first half in master and copy master to replica
198         master.incrementAll(testArray, 0, (int) index);
199         replica = master.copy();
200 
201         // Check same
202         assertTrue(replica.equals(master));
203         assertTrue(master.equals(replica));
204 
205         // Now add second part to both and check again
206         master.incrementAll(testArray, (int) index, (int) (testArray.length - index));
207         replica.incrementAll(testArray, (int) index, (int) (testArray.length - index));
208         assertTrue(replica.equals(master));
209         assertTrue(master.equals(replica));
210     }
211 
212     @Test
213     public void testSerial() {
214         StorelessUnivariateStatistic s = getUnivariateStatistic();
215         assertEquals(s, UnitTestUtils.serializeAndRecover(s));
216     }
217 
218     /**
219      * Make sure that evaluate(double[]) does not alter the internal state.
220      */
221     @Test
222     public void testEvaluateInternalState() {
223         StorelessUnivariateStatistic stat = getUnivariateStatistic();
224         stat.evaluate(testArray);
225         assertEquals(0, stat.getN());
226 
227         stat.incrementAll(testArray);
228 
229         StorelessUnivariateStatistic savedStatistic = stat.copy();
230 
231         assertNotEquals(stat.getResult(), stat.evaluate(testArray, 0, 5), getTolerance());
232 
233         assertEquals(savedStatistic.getResult(), stat.getResult(), 0.0);
234         assertEquals(savedStatistic.getN(), stat.getN());
235     }
236 
237     /**
238      * Test that the aggregate operation is consistent with individual increment.
239      */
240     @Test
241     @SuppressWarnings("unchecked")
242     public <T> void testAggregate() {
243         // Union of both statistics.
244         StorelessUnivariateStatistic statU = getUnivariateStatistic();
245         if (!(statU instanceof AggregatableStatistic<?>)) {
246             return;
247         }
248 
249         // Aggregated statistic.
250         AggregatableStatistic<T> aggregated = (AggregatableStatistic<T>) getUnivariateStatistic();
251         StorelessUnivariateStatistic statAgg = (StorelessUnivariateStatistic) aggregated;
252 
253         final RandomDataGenerator randomDataGenerator = new RandomDataGenerator(100);
254         // Create Set A
255         StorelessUnivariateStatistic statA = getUnivariateStatistic();
256         for (int i = 0; i < 10; i++) {
257             final double val = randomDataGenerator.nextGaussian();
258             statA.increment(val);
259             statU.increment(val);
260         }
261 
262         aggregated.aggregate((T) statA);
263         assertEquals(statA.getN(), statAgg.getN(), getTolerance());
264         assertEquals(statA.getResult(), statAgg.getResult(), getTolerance());
265 
266         // Create Set B
267         StorelessUnivariateStatistic statB = getUnivariateStatistic();
268         for (int i = 0; i < 4; i++) {
269             final double val = randomDataGenerator.nextGaussian();
270             statB.increment(val);
271             statU.increment(val);
272         }
273 
274         aggregated.aggregate((T) statB);
275         assertEquals(statU.getN(), statAgg.getN(), getTolerance());
276         assertEquals(statU.getResult(), statAgg.getResult(), getTolerance());
277     }
278 
279     @Test
280     public void testConsume() {
281         StorelessUnivariateStatistic stat = getUnivariateStatistic();
282 
283         Arrays.stream(testArray)
284               .forEach(stat);
285 
286         assertEquals(expectedValue(), stat.getResult(), getTolerance());
287 
288         StorelessUnivariateStatistic stat2 = getUnivariateStatistic();
289         stat2.incrementAll(testArray);
290         assertEquals(stat2.getResult(), stat.getResult(), getTolerance());
291     }
292 }