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    *      http://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  package org.apache.commons.math4.legacy.stat.descriptive;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.math4.legacy.TestUtils;
23  import org.apache.commons.statistics.distribution.DiscreteDistribution;
24  import org.apache.commons.statistics.distribution.NormalDistribution;
25  import org.apache.commons.statistics.distribution.ContinuousDistribution;
26  import org.apache.commons.statistics.distribution.UniformDiscreteDistribution;
27  import org.apache.commons.math4.core.jdkmath.JdkMath;
28  import org.apache.commons.rng.simple.RandomSource;
29  import org.junit.Assert;
30  import org.junit.Test;
31  
32  /**
33   * Test cases for the {@link UnivariateStatistic} class.
34   */
35  public abstract class UnivariateStatisticAbstractTest {
36  
37      protected double mean = 12.404545454545455d;
38      protected double geoMean = 12.070589161633011d;
39  
40      protected double var = 10.00235930735931d;
41      protected double std = JdkMath.sqrt(var);
42      protected double skew = 1.437423729196190d;
43      protected double kurt = 2.377191264804700d;
44  
45      protected double min = 8.2d;
46      protected double max = 21d;
47      protected double median = 12d;
48      protected double percentile5 = 8.29d;
49      protected double percentile95 = 20.82d;
50  
51      protected double product = 628096400563833396009676.9200400128d;
52      protected double sumLog = 54.7969806116451507d;
53      protected double sumSq = 3595.250d;
54      protected double sum = 272.90d;
55      protected double secondMoment = 210.04954545454547d;
56      protected double thirdMoment = 868.0906859504136;
57      protected double fourthMoment = 9244.080993773481;
58  
59  
60      protected double weightedMean = 12.366995073891626d;
61      protected double weightedVar =   9.974760968886391d;
62      protected double weightedStd = JdkMath.sqrt(weightedVar);
63      protected double weightedProduct = 8517647448765288000000d;
64      protected double weightedSum = 251.05d;
65  
66      protected double tolerance = 10E-12;
67  
68      protected double[] testArray =
69          { 12.5, 12.0, 11.8, 14.2, 14.9, 14.5, 21.0,  8.2, 10.3, 11.3,
70            14.1,  9.9, 12.2, 12.0, 12.1, 11.0, 19.8, 11.0, 10.0,  8.8,
71             9.0, 12.3 };
72  
73      protected double[] testWeightsArray =
74          {  1.5,  0.8,  1.2,  0.4,  0.8,  1.8,  1.2,  1.1,  1.0,  0.7,
75             1.3,  0.6,  0.7,  1.3,  0.7,  1.0,  0.4,  0.1,  1.4,  0.9,
76             1.1,  0.3 };
77  
78      protected double[] identicalWeightsArray =
79          {  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
80             0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
81             0.5,  0.5 };
82  
83      protected double[] unitWeightsArray =
84          {  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,
85             1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,
86             1.0,  1.0 };
87  
88      public abstract UnivariateStatistic getUnivariateStatistic();
89  
90      public abstract double expectedValue();
91  
92      public double getTolerance() {
93          return tolerance;
94      }
95  
96      @Test
97      public void testEvaluation() {
98          Assert.assertEquals(expectedValue(), getUnivariateStatistic().evaluate(testArray), getTolerance());
99      }
100 
101     @Test
102     public void testEvaluateArraySegment() {
103         final UnivariateStatistic stat = getUnivariateStatistic();
104         final double[] arrayZero = new double[5];
105         System.arraycopy(testArray, 0, arrayZero, 0, 5);
106         Assert.assertEquals(stat.evaluate(arrayZero), stat.evaluate(testArray, 0, 5), 0);
107         final double[] arrayOne = new double[5];
108         System.arraycopy(testArray, 5, arrayOne, 0, 5);
109         Assert.assertEquals(stat.evaluate(arrayOne), stat.evaluate(testArray, 5, 5), 0);
110         final double[] arrayEnd = new double[5];
111         System.arraycopy(testArray, testArray.length - 5, arrayEnd, 0, 5);
112         Assert.assertEquals(stat.evaluate(arrayEnd), stat.evaluate(testArray, testArray.length - 5, 5), 0);
113     }
114 
115     @Test
116     public void testEvaluateArraySegmentWeighted() {
117         // See if this statistic computes weighted statistics
118         // If not, skip this test
119         UnivariateStatistic statistic = getUnivariateStatistic();
120         if (!(statistic instanceof WeightedEvaluation)) {
121             return;
122         }
123         final WeightedEvaluation stat = (WeightedEvaluation) getUnivariateStatistic();
124         final double[] arrayZero = new double[5];
125         final double[] weightZero = new double[5];
126         System.arraycopy(testArray, 0, arrayZero, 0, 5);
127         System.arraycopy(testWeightsArray, 0, weightZero, 0, 5);
128         Assert.assertEquals(stat.evaluate(arrayZero, weightZero),
129                 stat.evaluate(testArray, testWeightsArray, 0, 5), 0);
130         final double[] arrayOne = new double[5];
131         final double[] weightOne = new double[5];
132         System.arraycopy(testArray, 5, arrayOne, 0, 5);
133         System.arraycopy(testWeightsArray, 5, weightOne, 0, 5);
134         Assert.assertEquals(stat.evaluate(arrayOne, weightOne),
135                 stat.evaluate(testArray, testWeightsArray, 5, 5), 0);
136         final double[] arrayEnd = new double[5];
137         final double[] weightEnd = new double[5];
138         System.arraycopy(testArray, testArray.length - 5, arrayEnd, 0, 5);
139         System.arraycopy(testWeightsArray, testArray.length - 5, weightEnd, 0, 5);
140         Assert.assertEquals(stat.evaluate(arrayEnd, weightEnd),
141                 stat.evaluate(testArray, testWeightsArray, testArray.length - 5, 5), 0);
142     }
143 
144     @Test
145     public void testCopy() {
146         UnivariateStatistic original = getUnivariateStatistic();
147         UnivariateStatistic copy = original.copy();
148         Assert.assertEquals(expectedValue(), copy.evaluate(testArray), getTolerance());
149     }
150 
151     /**
152      * Tests consistency of weighted statistic computation.
153      * For statistics that support weighted evaluation, this test case compares
154      * the result of direct computation on an array with repeated values with
155      * a weighted computation on the corresponding (shorter) array with each
156      * value appearing only once but with a weight value equal to its multiplicity
157      * in the repeating array.
158      */
159 
160     @Test
161     public void testWeightedConsistency() {
162 
163         // See if this statistic computes weighted statistics
164         // If not, skip this test
165         UnivariateStatistic statistic = getUnivariateStatistic();
166         if (!(statistic instanceof WeightedEvaluation)) {
167             return;
168         }
169 
170         // Create arrays of values and corresponding integral weights
171         // and longer array with values repeated according to the weights
172         final int len = 10;        // length of values array
173         final double mu = 0;       // mean of test data
174         final double sigma = 5;    // std dev of test data
175         double[] values = new double[len];
176         double[] weights = new double[len];
177 
178         // Fill weights array with random int values between 1 and 5
179         int[] intWeights = new int[len];
180         final DiscreteDistribution.Sampler weightDist =
181             UniformDiscreteDistribution.of(1, 5).createSampler(RandomSource.WELL_512_A.create(234878544L));
182         for (int i = 0; i < len; i++) {
183             intWeights[i] = weightDist.sample();
184             weights[i] = intWeights[i];
185         }
186 
187         // Fill values array with random data from N(mu, sigma)
188         // and fill valuesList with values from values array with
189         // values[i] repeated weights[i] times, each i
190         final ContinuousDistribution.Sampler valueDist =
191             NormalDistribution.of(mu, sigma).createSampler(RandomSource.WELL_512_A.create(64925784252L));
192         List<Double> valuesList = new ArrayList<>();
193         for (int i = 0; i < len; i++) {
194             double value = valueDist.sample();
195             values[i] = value;
196             for (int j = 0; j < intWeights[i]; j++) {
197                 valuesList.add(Double.valueOf(value));
198             }
199         }
200 
201         // Dump valuesList into repeatedValues array
202         int sumWeights = valuesList.size();
203         double[] repeatedValues = new double[sumWeights];
204         for (int i = 0; i < sumWeights; i++) {
205             repeatedValues[i] = valuesList.get(i);
206         }
207 
208         // Compare result of weighted statistic computation with direct computation
209         // on array of repeated values
210         WeightedEvaluation weightedStatistic = (WeightedEvaluation) statistic;
211         TestUtils.assertRelativelyEquals(statistic.evaluate(repeatedValues),
212                 weightedStatistic.evaluate(values, weights, 0, values.length),
213                 10E-12);
214 
215         // Check consistency of weighted evaluation methods
216         Assert.assertEquals(weightedStatistic.evaluate(values, weights, 0, values.length),
217                 weightedStatistic.evaluate(values, weights), Double.MIN_VALUE);
218     }
219 }