• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.math;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import com.google.common.collect.ImmutableSet;
23 import com.google.common.collect.Sets;
24 import java.util.Map;
25 import java.util.Random;
26 import java.util.Set;
27 import junit.framework.TestCase;
28 
29 /**
30  * Tests that the different algorithms benchmarked in {@link QuantilesBenchmark} are actually all
31  * returning more-or-less the same answers.
32  */
33 public class QuantilesAlgorithmTest extends TestCase {
34 
35   private static final Random RNG = new Random(82674067L);
36   private static final int DATASET_SIZE = 1000;
37   private static final double ALLOWED_ERROR = 1.0e-10;
38   private static final QuantilesAlgorithm REFERENCE_ALGORITHM = QuantilesAlgorithm.SORTING;
39   private static final Set<QuantilesAlgorithm> NON_REFERENCE_ALGORITHMS =
40       Sets.difference(
41           ImmutableSet.copyOf(QuantilesAlgorithm.values()), ImmutableSet.of(REFERENCE_ALGORITHM));
42 
43   private double[] dataset;
44 
45   @Override
setUp()46   protected void setUp() {
47     dataset = new double[DATASET_SIZE];
48     for (int i = 0; i < DATASET_SIZE; i++) {
49       dataset[i] = RNG.nextDouble();
50     }
51   }
52 
testSingleQuantile_median()53   public void testSingleQuantile_median() {
54     double referenceValue = REFERENCE_ALGORITHM.singleQuantile(1, 2, dataset.clone());
55     for (QuantilesAlgorithm algorithm : NON_REFERENCE_ALGORITHMS) {
56       assertWithMessage("Mismatch between %s and %s", algorithm, REFERENCE_ALGORITHM)
57           .that(algorithm.singleQuantile(1, 2, dataset.clone()))
58           .isWithin(ALLOWED_ERROR)
59           .of(referenceValue);
60     }
61   }
62 
testSingleQuantile_percentile99()63   public void testSingleQuantile_percentile99() {
64     double referenceValue = REFERENCE_ALGORITHM.singleQuantile(99, 100, dataset.clone());
65     for (QuantilesAlgorithm algorithm : NON_REFERENCE_ALGORITHMS) {
66       assertWithMessage("Mismatch between %s and %s", algorithm, REFERENCE_ALGORITHM)
67           .that(algorithm.singleQuantile(99, 100, dataset.clone()))
68           .isWithin(ALLOWED_ERROR)
69           .of(referenceValue);
70     }
71   }
72 
testMultipleQuantile()73   public void testMultipleQuantile() {
74     ImmutableSet<Integer> indexes = ImmutableSet.of(50, 90, 99);
75     Map<Integer, Double> referenceQuantiles =
76         REFERENCE_ALGORITHM.multipleQuantiles(indexes, 100, dataset.clone());
77     assertThat(referenceQuantiles.keySet()).isEqualTo(indexes);
78     for (QuantilesAlgorithm algorithm : NON_REFERENCE_ALGORITHMS) {
79       Map<Integer, Double> quantiles = algorithm.multipleQuantiles(indexes, 100, dataset.clone());
80       assertWithMessage("Wrong keys from " + algorithm).that(quantiles.keySet()).isEqualTo(indexes);
81       for (int i : indexes) {
82         assertWithMessage("Mismatch between %s and %s at %s", algorithm, REFERENCE_ALGORITHM, i)
83             .that(quantiles.get(i))
84             .isWithin(ALLOWED_ERROR)
85             .of(referenceQuantiles.get(i));
86       }
87     }
88   }
89 }
90