NaturalRanking implements RankingAlgorithm { public double[] rank(double[] data) { IntDoublePair[] ranks = new IntDoublePair[data.length]; for (int i = 0; i < data.length; i++) { ranks[i] = new IntDoublePair(data[i], i); } List<Integer> nanPositions = null; switch (nanStrategy) { case MAXIMAL: recodeNaNs(ranks, Double.POSITIVE_INFINITY); break; case MINIMAL: recodeNaNs(ranks, Double.NEGATIVE_INFINITY); break; case REMOVED: ranks = removeNaNs(ranks); break; case FIXED: nanPositions = getNanPositions(ranks); break; case FAILED: nanPositions = getNanPositions(ranks); if (nanPositions.size() > 0) { throw new NotANumberException(); } break; default: throw new MathInternalError(); } Arrays.sort(ranks); double[] out = new double[ranks.length]; int pos = 1; out[ranks[0].getPosition()] = pos; List<Integer> tiesTrace = new ArrayList<Integer>(); tiesTrace.add(ranks[0].getPosition()); for (int i = 1; i < ranks.length; i++) { if (Double.compare(ranks[i].getValue(), ranks[i - 1].getValue()) > 0) { pos = i + 1; if (tiesTrace.size() > 1) { resolveTie(out, tiesTrace); } tiesTrace = new ArrayList<Integer>(); tiesTrace.add(ranks[i].getPosition()); } else { tiesTrace.add(ranks[i].getPosition()); } out[ranks[i].getPosition()] = pos; } if (tiesTrace.size() > 1) { resolveTie(out, tiesTrace); } if (nanStrategy == NaNStrategy.FIXED) { restoreNaNs(out, nanPositions); } return out; } NaturalRanking();  NaturalRanking(TiesStrategy tiesStrategy);  NaturalRanking(NaNStrategy nanStrategy);  NaturalRanking(NaNStrategy nanStrategy, TiesStrategy tiesStrategy);  NaturalRanking(RandomGenerator randomGenerator);  NaturalRanking(NaNStrategy nanStrategy,
            RandomGenerator randomGenerator); NaNStrategy getNanStrategy(); TiesStrategy getTiesStrategy(); double[] rank(double[] data); static final NaNStrategy DEFAULT_NAN_STRATEGY; static final TiesStrategy DEFAULT_TIES_STRATEGY; }
@Test public void testDefault() { NaturalRanking ranking = new NaturalRanking(); double[] ranks; try { ranks = ranking.rank(exampleData); Assert.fail("expected NotANumberException due to NaNStrategy.FAILED"); } catch (NotANumberException e) { } ranks = ranking.rank(tiesFirst); double[] correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3.5, 3.5, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); try { ranks = ranking.rank(multipleNaNs); Assert.fail("expected NotANumberException due to NaNStrategy.FAILED"); } catch (NotANumberException e) { } ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsMaximalTiesMinimum() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL, TiesStrategy.MINIMUM); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 2, 6, 7, 2, 8, 9, 1, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 1, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 3, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2, 3, 3 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4, 4, 6, 6, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 1, 1, 1, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsRemovedTiesSequential() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.REMOVED, TiesStrategy.SEQUENTIAL); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 2, 6, 7, 3, 8, 1, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 2, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 4, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4, 5, 6, 7, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 1, 2, 3, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsMinimalTiesMaximum() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL, TiesStrategy.MAXIMUM); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 6, 5, 7, 8, 5, 9, 2, 2, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 2, 2, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 4, 4, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 3, 4, 2, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 5, 5, 7, 7, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 4, 4, 4, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsMinimalTiesAverage() { NaturalRanking ranking = new NaturalRanking(NaNStrategy.MINIMAL); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 6, 4, 7, 8, 4, 9, 1.5, 1.5, 4 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1.5, 1.5, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3.5, 3.5, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 3, 4, 1.5, 1.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4.5, 4.5, 6.5, 6.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 2.5, 2.5, 2.5, 2.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsFixedTiesRandom() { RandomGenerator randomGenerator = new JDKRandomGenerator(); randomGenerator.setSeed(1000); NaturalRanking ranking = new NaturalRanking(NaNStrategy.FIXED, randomGenerator); double[] ranks = ranking.rank(exampleData); double[] correctRanks = { 5, 3, 6, 7, 3, 8, Double.NaN, 1, 2 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesFirst); correctRanks = new double[] { 1, 2, 4, 3, 5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(tiesLast); correctRanks = new double[] { 3, 3, 2, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleNaNs); correctRanks = new double[] { 1, 2, Double.NaN, Double.NaN }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(multipleTies); correctRanks = new double[] { 3, 2, 4, 4, 6, 7, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranks = ranking.rank(allSame); correctRanks = new double[] { 2, 3, 3, 3 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test public void testNaNsAndInfs() { double[] data = { 0, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY }; NaturalRanking ranking = new NaturalRanking(NaNStrategy.MAXIMAL); double[] ranks = ranking.rank(data); double[] correctRanks = new double[] { 2, 3.5, 3.5, 1 }; TestUtils.assertEquals(correctRanks, ranks, 0d); ranking = new NaturalRanking(NaNStrategy.MINIMAL); ranks = ranking.rank(data); correctRanks = new double[] { 3, 4, 1.5, 1.5 }; TestUtils.assertEquals(correctRanks, ranks, 0d); }
@Test(expected=NotANumberException.class) public void testNaNsFailed() { double[] data = { 0, Double.POSITIVE_INFINITY, Double.NaN, Double.NEGATIVE_INFINITY }; NaturalRanking ranking = new NaturalRanking(NaNStrategy.FAILED); ranking.rank(data); }
@Test public void testNoNaNsFailed() { double[] data = { 1, 2, 3, 4 }; NaturalRanking ranking = new NaturalRanking(NaNStrategy.FAILED); double[] ranks = ranking.rank(data); TestUtils.assertEquals(data, ranks, 0d); }