blob: 578c39ed0b11eaa68e07dab5663f7494e7be33b2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.datasketches;
import static org.apache.datasketches.BinomialBoundsN.checkArgs;
import static org.apache.datasketches.BinomialBoundsN.getLowerBound;
import static org.apache.datasketches.BinomialBoundsN.getUpperBound;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import org.testng.annotations.Test;
/**
* @author Kevin Lang
*/
@SuppressWarnings("javadoc")
public class BinomialBoundsNTest {
public static double[] runTestAux (long max_numSamplesI, int ci, double min_p) {
long numSamplesI = 0;
double p, lb, ub;
double sum1 = 0.0;
double sum2 = 0.0;
double sum3 = 0.0;
double sum4 = 0.0;
long count = 0;
while (numSamplesI <= max_numSamplesI) { /* was <= */
p = 1.0;
while (p >= min_p) {
lb = BinomialBoundsN.getLowerBound (numSamplesI, p, ci, false);
ub = BinomialBoundsN.getUpperBound (numSamplesI, p, ci, false);
// if (numSamplesI == 300 && p > 0.365 && p < 0.367) { ub += 0.01; } // artificial discrepancy
// the logarithm helps discrepancies to not be swamped out of the total
sum1 += Math.log (lb + 1.0);
sum2 += Math.log (ub + 1.0);
count += 2;
if (p < 1.0) {
lb = BinomialBoundsN.getLowerBound (numSamplesI, 1.0 - p, ci, false);
ub = BinomialBoundsN.getUpperBound (numSamplesI, 1.0 - p, ci, false);
sum3 += Math.log (lb + 1.0);
sum4 += Math.log (ub + 1.0);
count += 2;
}
p *= 0.99;
}
numSamplesI = Math.max (numSamplesI+1, (1001*numSamplesI)/1000);
}
println(String.format("{%.15e, %.15e, %.15e, %.15e, %d}", sum1, sum2, sum3, sum4, count));
double[] arrOut = {sum1, sum2, sum3, sum4, count};
return arrOut;
}
private static final double TOL = 1E-15;
@Test
public static void checkBounds() {
int i = 0;
for (int ci = 1; ci <= 3; ci++, i++) {
double[] arr = runTestAux (20, ci, 1e-3);
for (int j=0; j<5; j++) {
assertTrue(((arr[j] / std[i][j]) -1.0) < TOL);
}
}
for (int ci = 1; ci <= 3; ci++, i++) {
double[] arr = runTestAux (200, ci, 1e-5);
for (int j=0; j<5; j++) {
assertTrue(((arr[j] / std[i][j]) -1.0) < TOL);
}
}
//comment last one out for a shorter test
// for (int ci = 1; ci <= 3; ci++, i++) {
// double[] arr = runTestAux (2000, ci, 1e-7);
// for (int j=0; j<5; j++) {
// assertTrue((arr[j] / std[i][j] -1.0) < TOL);
// }
// }
}
// With all 3 enabled the test should produce in groups of 3 */
private static final double[][] std = {
{7.083330682531043e+04, 8.530373642825481e+04, 3.273647725073409e+04, 3.734024243699785e+04, 57750},
{6.539415269641498e+04, 8.945522372568645e+04, 3.222302546497840e+04, 3.904738469737429e+04, 57750},
{6.006043493107306e+04, 9.318105731423477e+04, 3.186269956585285e+04, 4.096466221922520e+04, 57750},
{2.275584770163813e+06, 2.347586549014998e+06, 1.020399409477305e+06, 1.036729927598294e+06, 920982},
{2.243569126699713e+06, 2.374663344107342e+06, 1.017017233582122e+06, 1.042597845553438e+06, 920982},
{2.210056231903739e+06, 2.400441267999687e+06, 1.014081235946986e+06, 1.049480769755676e+06, 920982},
{4.688240115809608e+07, 4.718067204619278e+07, 2.148362024482338e+07, 2.153118905212302e+07, 12834414},
{4.674205938540214e+07, 4.731333757486791e+07, 2.146902141966406e+07, 2.154916650733873e+07, 12834414},
{4.659896614422579e+07, 4.744404182094614e+07, 2.145525391547799e+07, 2.156815612325058e+07, 12834414}
};
@Test
public static void checkCheckArgs() {
try {
checkArgs(-1L, 1.0, 1);
checkArgs(10L, 0.0, 1);
checkArgs(10L, 1.01, 1);
checkArgs(10L, 1.0, 3);
checkArgs(10L, 1.0, 0);
checkArgs(10L, 1.0, 4);
fail("Expected SketchesArgumentException");
} catch (SketchesArgumentException e) {
//pass
}
}
@Test
public static void checkComputeApproxBino_LB_UB() {
long n = 100;
double theta = (2.0 - 1e-5)/2.0;
double result = getLowerBound(n, theta, 1, false);
assertEquals(result, n, 0.0);
result = getUpperBound(n, theta, 1, false);
assertEquals(result, n+1, 0.0);
result = getLowerBound(n, theta, 1, true);
assertEquals(result, 0.0, 0.0);
result = getUpperBound(n, theta, 1, true);
assertEquals(result, 0.0, 0.0);
}
@Test(expectedExceptions = SketchesArgumentException.class)
public static void checkThetaLimits1() {
BinomialBoundsN.getUpperBound(100, 1.1, 1, false);
}
@Test
public static void boundsExample() {
println("BinomialBoundsN Example:");
int k = 500;
double theta = 0.001;
int stdDev = 2;
double ub = BinomialBoundsN.getUpperBound(k, theta, stdDev, false);
double est = k/theta;
double lb = BinomialBoundsN.getLowerBound(k, theta, stdDev, false);
println("K="+k+", Theta="+theta+", SD="+stdDev);
println("UB: "+ub);
println("Est: "+est);
println("LB: "+lb);
println("");
}
@Test
public void printlnTest() {
println("PRINTING: "+this.getClass().getName());
}
/**
* @param s value to print
*/
static void println(String s) {
//System.out.println(s); //disable here
}
}