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.ranking;
18  
19  import org.junit.Assert;
20  import org.apache.commons.math4.legacy.TestUtils;
21  import org.apache.commons.math4.legacy.exception.NotANumberException;
22  import org.junit.Test;
23  import org.junit.Ignore;
24  import org.apache.commons.rng.UniformRandomProvider;
25  import org.apache.commons.rng.simple.RandomSource;
26  
27  
28  /**
29   * Test cases for NaturalRanking class
30   *
31   * @since 2.0
32   */
33  public class NaturalRankingTest {
34  
35      private final double[] exampleData = { 20, 17, 30, 42.3, 17, 50,
36              Double.NaN, Double.NEGATIVE_INFINITY, 17 };
37      private final double[] tiesFirst = { 0, 0, 2, 1, 4 };
38      private final double[] tiesLast = { 4, 4, 1, 0 };
39      private final double[] multipleNaNs = { 0, 1, Double.NaN, Double.NaN };
40      private final double[] multipleTies = { 3, 2, 5, 5, 6, 6, 1 };
41      private final double[] allSame = { 0, 0, 0, 0 };
42  
43      @Test
44      public void testDefault() { // Ties averaged, NaNs failed
45          NaturalRanking ranking = new NaturalRanking();
46          double[] ranks;
47  
48          try {
49              ranks = ranking.rank(exampleData);
50              Assert.fail("expected NotANumberException due to NaNStrategy.FAILED");
51          } catch (NotANumberException e) {
52              // expected
53          }
54  
55          ranks = ranking.rank(tiesFirst);
56          double[] correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 };
57          TestUtils.assertEquals(correctRanks, ranks, 0d);
58          ranks = ranking.rank(tiesLast);
59          correctRanks = new double[] { 3.5, 3.5, 2, 1 };
60          TestUtils.assertEquals(correctRanks, ranks, 0d);
61  
62          try {
63              ranks = ranking.rank(multipleNaNs);
64              Assert.fail("expected NotANumberException due to NaNStrategy.FAILED");
65          } catch (NotANumberException e) {
66              // expected
67          }
68  
69          ranks = ranking.rank(multipleTies);
70          correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 };
71          TestUtils.assertEquals(correctRanks, ranks, 0d);
72          ranks = ranking.rank(allSame);
73          correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 };
74          TestUtils.assertEquals(correctRanks, ranks, 0d);
75      }
76  
77      @Test
78      public void testNaNsMaximalTiesMinimum() {
79          NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL, TiesStrategy.MINIMUM);
80          double[] ranks = ranking.rank(exampleData);
81          double[] correctRanks = { 5, 2, 6, 7, 2, 8, 9, 1, 2 };
82          TestUtils.assertEquals(correctRanks, ranks, 0d);
83          ranks = ranking.rank(tiesFirst);
84          correctRanks = new double[] { 1, 1, 4, 3, 5 };
85          TestUtils.assertEquals(correctRanks, ranks, 0d);
86          ranks = ranking.rank(tiesLast);
87          correctRanks = new double[] { 3, 3, 2, 1 };
88          TestUtils.assertEquals(correctRanks, ranks, 0d);
89          ranks = ranking.rank(multipleNaNs);
90          correctRanks = new double[] { 1, 2, 3, 3 };
91          TestUtils.assertEquals(correctRanks, ranks, 0d);
92          ranks = ranking.rank(multipleTies);
93          correctRanks = new double[] { 3, 2, 4, 4, 6, 6, 1 };
94          TestUtils.assertEquals(correctRanks, ranks, 0d);
95          ranks = ranking.rank(allSame);
96          correctRanks = new double[] { 1, 1, 1, 1 };
97          TestUtils.assertEquals(correctRanks, ranks, 0d);
98      }
99  
100     @Test
101     public void testNaNsRemovedTiesSequential() {
102         NaturalRanking ranking = new NaturalRanking(NaNStrategy.REMOVED,
103                 TiesStrategy.SEQUENTIAL);
104         double[] ranks = ranking.rank(exampleData);
105         double[] correctRanks = { 5, 2, 6, 7, 3, 8, 1, 4 };
106         TestUtils.assertEquals(correctRanks, ranks, 0d);
107         ranks = ranking.rank(tiesFirst);
108         correctRanks = new double[] { 1, 2, 4, 3, 5 };
109         TestUtils.assertEquals(correctRanks, ranks, 0d);
110         ranks = ranking.rank(tiesLast);
111         correctRanks = new double[] { 3, 4, 2, 1 };
112         TestUtils.assertEquals(correctRanks, ranks, 0d);
113         ranks = ranking.rank(multipleNaNs);
114         correctRanks = new double[] { 1, 2 };
115         TestUtils.assertEquals(correctRanks, ranks, 0d);
116         ranks = ranking.rank(multipleTies);
117         correctRanks = new double[] { 3, 2, 4, 5, 6, 7, 1 };
118         TestUtils.assertEquals(correctRanks, ranks, 0d);
119         ranks = ranking.rank(allSame);
120         correctRanks = new double[] { 1, 2, 3, 4 };
121         TestUtils.assertEquals(correctRanks, ranks, 0d);
122     }
123 
124     @Test
125     public void testNaNsMinimalTiesMaximum() {
126         NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL,
127                 TiesStrategy.MAXIMUM);
128         double[] ranks = ranking.rank(exampleData);
129         double[] correctRanks = { 6, 5, 7, 8, 5, 9, 2, 2, 5 };
130         TestUtils.assertEquals(correctRanks, ranks, 0d);
131         ranks = ranking.rank(tiesFirst);
132         correctRanks = new double[] { 2, 2, 4, 3, 5 };
133         TestUtils.assertEquals(correctRanks, ranks, 0d);
134         ranks = ranking.rank(tiesLast);
135         correctRanks = new double[] { 4, 4, 2, 1 };
136         TestUtils.assertEquals(correctRanks, ranks, 0d);
137         ranks = ranking.rank(multipleNaNs);
138         correctRanks = new double[] { 3, 4, 2, 2 };
139         TestUtils.assertEquals(correctRanks, ranks, 0d);
140         ranks = ranking.rank(multipleTies);
141         correctRanks = new double[] { 3, 2, 5, 5, 7, 7, 1 };
142         TestUtils.assertEquals(correctRanks, ranks, 0d);
143         ranks = ranking.rank(allSame);
144         correctRanks = new double[] { 4, 4, 4, 4 };
145         TestUtils.assertEquals(correctRanks, ranks, 0d);
146     }
147 
148     @Test
149     public void testNaNsMinimalTiesAverage() {
150         NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL);
151         double[] ranks = ranking.rank(exampleData);
152         double[] correctRanks = { 6, 4, 7, 8, 4, 9, 1.5, 1.5, 4 };
153         TestUtils.assertEquals(correctRanks, ranks, 0d);
154         ranks = ranking.rank(tiesFirst);
155         correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 };
156         TestUtils.assertEquals(correctRanks, ranks, 0d);
157         ranks = ranking.rank(tiesLast);
158         correctRanks = new double[] { 3.5, 3.5, 2, 1 };
159         TestUtils.assertEquals(correctRanks, ranks, 0d);
160         ranks = ranking.rank(multipleNaNs);
161         correctRanks = new double[] { 3, 4, 1.5, 1.5 };
162         TestUtils.assertEquals(correctRanks, ranks, 0d);
163         ranks = ranking.rank(multipleTies);
164         correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 };
165         TestUtils.assertEquals(correctRanks, ranks, 0d);
166         ranks = ranking.rank(allSame);
167         correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 };
168         TestUtils.assertEquals(correctRanks, ranks, 0d);
169     }
170 
171     /*
172      * Cf. MATH-1361
173      * XXX To be removed when issue is fixed.
174      */
175     @Ignore
176     @Test
177     public void testNaNsFixedTiesRandomDEBUG() {
178         int count = 0;
179         final long start = 0;
180         final int num = 10000000;
181         final long max = start + num;
182         for (long i = start; i <= max; i++) {
183             UniformRandomProvider randomGenerator = RandomSource.MT.create(i);
184             NaturalRanking ranking = new NaturalRanking(NaNStrategy.FIXED,
185                                                         randomGenerator);
186             double[] ranks = ranking.rank(exampleData);
187             double[] correctRanks = { 5, 3, 6, 7, 3, 8, Double.NaN, 1, 2 };
188             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
189                 continue;
190             }
191 
192             ranks = ranking.rank(tiesFirst);
193             correctRanks = new double[] { 1, 2, 4, 3, 5 };
194             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
195                 continue;
196             }
197 
198             ranks = ranking.rank(tiesLast);
199             correctRanks = new double[] { 3, 3, 2, 1 };
200             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
201                 continue;
202             }
203 
204             ranks = ranking.rank(multipleNaNs);
205             correctRanks = new double[] { 1, 2, Double.NaN, Double.NaN };
206             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
207                 continue;
208             }
209 
210             ranks = ranking.rank(multipleTies);
211             correctRanks = new double[] { 3, 2, 4, 4, 6, 7, 1 };
212             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
213                 continue;
214             }
215 
216             ranks = ranking.rank(allSame);
217             correctRanks = new double[] { 2, 3, 3, 3 };
218             if (!org.apache.commons.math4.legacy.core.MathArrays.equalsIncludingNaN(correctRanks, ranks)) {
219                 continue;
220             }
221 
222             ++count;
223             //System.out.println("seed = " + i);
224             //break;
225         }
226         System.out.println("success rate = " + count + " / " + num);
227     }
228 
229     @Ignore
230     @Test
231     public void testNaNsFixedTiesRandom() {
232         UniformRandomProvider randomGenerator = RandomSource.SPLIT_MIX_64.create();
233         NaturalRanking ranking = new NaturalRanking(NaNStrategy.FIXED, randomGenerator);
234         double[] ranks = ranking.rank(exampleData);
235         double[] correctRanks = { 5, 3, 6, 7, 3, 8, Double.NaN, 1, 2 };
236         TestUtils.assertEquals(correctRanks, ranks, 0d);
237         ranks = ranking.rank(tiesFirst);
238         correctRanks = new double[] { 1, 2, 4, 3, 5 };
239         TestUtils.assertEquals(correctRanks, ranks, 0d);
240         ranks = ranking.rank(tiesLast);
241         correctRanks = new double[] { 3, 3, 2, 1 };
242         TestUtils.assertEquals(correctRanks, ranks, 0d);
243         ranks = ranking.rank(multipleNaNs);
244         correctRanks = new double[] { 1, 2, Double.NaN, Double.NaN };
245         TestUtils.assertEquals(correctRanks, ranks, 0d);
246         ranks = ranking.rank(multipleTies);
247         correctRanks = new double[] { 3, 2, 4, 4, 6, 7, 1 };
248         TestUtils.assertEquals(correctRanks, ranks, 0d);
249         ranks = ranking.rank(allSame);
250         correctRanks = new double[] { 2, 3, 3, 3 };
251         TestUtils.assertEquals(correctRanks, ranks, 0d);
252     }
253 
254     @Test
255     public void testNaNsAndInfs() {
256         double[] data = { 0, Double.POSITIVE_INFINITY, Double.NaN,
257                 Double.NEGATIVE_INFINITY };
258         NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL);
259         double[] ranks = ranking.rank(data);
260         double[] correctRanks = new double[] { 2, 3.5, 3.5, 1 };
261         TestUtils.assertEquals(correctRanks, ranks, 0d);
262         ranking = new NaturalRanking(NaNStrategy.MINIMAL);
263         ranks = ranking.rank(data);
264         correctRanks = new double[] { 3, 4, 1.5, 1.5 };
265         TestUtils.assertEquals(correctRanks, ranks, 0d);
266     }
267 
268     @Test(expected=NotANumberException.class)
269     public void testNaNsFailed() {
270         double[] data = { 0, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY };
271         NaturalRanking ranking = new NaturalRanking(NaNStrategy.FAILED);
272         ranking.rank(data);
273     }
274 
275     @Test
276     public void testNoNaNsFailed() {
277         double[] data = { 1, 2, 3, 4 };
278         NaturalRanking ranking = new NaturalRanking(NaNStrategy.FAILED);
279         double[] ranks = ranking.rank(data);
280         TestUtils.assertEquals(data, ranks, 0d);
281     }
282 }