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 s * 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.math3.stat.descriptive;
18 
19 import java.util.ArrayList;
20 import java.util.List;
21 
22 
23 import org.apache.commons.math3.TestUtils;
24 import org.apache.commons.math3.distribution.IntegerDistribution;
25 import org.apache.commons.math3.distribution.UniformIntegerDistribution;
26 import org.apache.commons.math3.distribution.RealDistribution;
27 import org.apache.commons.math3.distribution.NormalDistribution;
28 import org.apache.commons.math3.util.FastMath;
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 = FastMath.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 = FastMath.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 
getUnivariateStatistic()88     public abstract UnivariateStatistic getUnivariateStatistic();
89 
expectedValue()90     public abstract double expectedValue();
91 
getTolerance()92     public double getTolerance() {
93         return tolerance;
94     }
95 
96     @Test
testEvaluation()97     public void testEvaluation() {
98         Assert.assertEquals(
99             expectedValue(),
100             getUnivariateStatistic().evaluate(testArray),
101             getTolerance());
102     }
103 
104     @Test
testEvaluateArraySegment()105     public void testEvaluateArraySegment() {
106         final UnivariateStatistic stat = getUnivariateStatistic();
107         final double[] arrayZero = new double[5];
108         System.arraycopy(testArray, 0, arrayZero, 0, 5);
109         Assert.assertEquals(stat.evaluate(arrayZero), stat.evaluate(testArray, 0, 5), 0);
110         final double[] arrayOne = new double[5];
111         System.arraycopy(testArray, 5, arrayOne, 0, 5);
112         Assert.assertEquals(stat.evaluate(arrayOne), stat.evaluate(testArray, 5, 5), 0);
113         final double[] arrayEnd = new double[5];
114         System.arraycopy(testArray, testArray.length - 5, arrayEnd, 0, 5);
115         Assert.assertEquals(stat.evaluate(arrayEnd), stat.evaluate(testArray, testArray.length - 5, 5), 0);
116     }
117 
118     @Test
testEvaluateArraySegmentWeighted()119     public void testEvaluateArraySegmentWeighted() {
120         // See if this statistic computes weighted statistics
121         // If not, skip this test
122         UnivariateStatistic statistic = getUnivariateStatistic();
123         if (!(statistic instanceof WeightedEvaluation)) {
124             return;
125         }
126         final WeightedEvaluation stat = (WeightedEvaluation) getUnivariateStatistic();
127         final double[] arrayZero = new double[5];
128         final double[] weightZero = new double[5];
129         System.arraycopy(testArray, 0, arrayZero, 0, 5);
130         System.arraycopy(testWeightsArray, 0, weightZero, 0, 5);
131         Assert.assertEquals(stat.evaluate(arrayZero, weightZero),
132                 stat.evaluate(testArray, testWeightsArray, 0, 5), 0);
133         final double[] arrayOne = new double[5];
134         final double[] weightOne = new double[5];
135         System.arraycopy(testArray, 5, arrayOne, 0, 5);
136         System.arraycopy(testWeightsArray, 5, weightOne, 0, 5);
137         Assert.assertEquals(stat.evaluate(arrayOne, weightOne),
138                 stat.evaluate(testArray, testWeightsArray, 5, 5), 0);
139         final double[] arrayEnd = new double[5];
140         final double[] weightEnd = new double[5];
141         System.arraycopy(testArray, testArray.length - 5, arrayEnd, 0, 5);
142         System.arraycopy(testWeightsArray, testArray.length - 5, weightEnd, 0, 5);
143         Assert.assertEquals(stat.evaluate(arrayEnd, weightEnd),
144                 stat.evaluate(testArray, testWeightsArray, testArray.length - 5, 5), 0);
145     }
146 
147     @Test
testCopy()148     public void testCopy() {
149         UnivariateStatistic original = getUnivariateStatistic();
150         UnivariateStatistic copy = original.copy();
151         Assert.assertEquals(
152                 expectedValue(),
153                 copy.evaluate(testArray),
154                 getTolerance());
155     }
156 
157     /**
158      * Tests consistency of weighted statistic computation.
159      * For statistics that support weighted evaluation, this test case compares
160      * the result of direct computation on an array with repeated values with
161      * a weighted computation on the corresponding (shorter) array with each
162      * value appearing only once but with a weight value equal to its multiplicity
163      * in the repeating array.
164      */
165 
166     @Test
testWeightedConsistency()167     public void testWeightedConsistency() {
168 
169         // See if this statistic computes weighted statistics
170         // If not, skip this test
171         UnivariateStatistic statistic = getUnivariateStatistic();
172         if (!(statistic instanceof WeightedEvaluation)) {
173             return;
174         }
175 
176         // Create arrays of values and corresponding integral weights
177         // and longer array with values repeated according to the weights
178         final int len = 10;        // length of values array
179         final double mu = 0;       // mean of test data
180         final double sigma = 5;    // std dev of test data
181         double[] values = new double[len];
182         double[] weights = new double[len];
183 
184         // Fill weights array with random int values between 1 and 5
185         int[] intWeights = new int[len];
186         final IntegerDistribution weightDist = new UniformIntegerDistribution(1, 5);
187         for (int i = 0; i < len; i++) {
188             intWeights[i] = weightDist.sample();
189             weights[i] = intWeights[i];
190         }
191 
192         // Fill values array with random data from N(mu, sigma)
193         // and fill valuesList with values from values array with
194         // values[i] repeated weights[i] times, each i
195         final RealDistribution valueDist = new NormalDistribution(mu, sigma);
196         List<Double> valuesList = new ArrayList<Double>();
197         for (int i = 0; i < len; i++) {
198             double value = valueDist.sample();
199             values[i] = value;
200             for (int j = 0; j < intWeights[i]; j++) {
201                 valuesList.add(new Double(value));
202             }
203         }
204 
205         // Dump valuesList into repeatedValues array
206         int sumWeights = valuesList.size();
207         double[] repeatedValues = new double[sumWeights];
208         for (int i = 0; i < sumWeights; i++) {
209             repeatedValues[i] = valuesList.get(i);
210         }
211 
212         // Compare result of weighted statistic computation with direct computation
213         // on array of repeated values
214         WeightedEvaluation weightedStatistic = (WeightedEvaluation) statistic;
215         TestUtils.assertRelativelyEquals(statistic.evaluate(repeatedValues),
216                 weightedStatistic.evaluate(values, weights, 0, values.length),
217                 10E-12);
218 
219         // Check consistency of weighted evaluation methods
220         Assert.assertEquals(weightedStatistic.evaluate(values, weights, 0, values.length),
221                 weightedStatistic.evaluate(values, weights), Double.MIN_VALUE);
222 
223     }
224 
225 }
226