blob: 4414c26c984163c4c5d129fd756a9c0b8d771633 [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 java.lang.String.format;
import static org.apache.datasketches.QuickSelect.select;
import static org.apache.datasketches.QuickSelect.selectExcludingZeros;
import static org.apache.datasketches.QuickSelect.selectIncludingZeros;
import java.util.Random;
import org.testng.Assert;
import org.testng.annotations.Test;
/**
* @author Lee Rhodes
*/
@SuppressWarnings("javadoc")
public class QuickSelectTest {
private static final String LS = System.getProperty("line.separator");
private static final Random random = new Random(); // pseudo-random number generator
//long[] arrays
@Test
public void checkQuickSelect0Based() {
final int len = 64;
final long[] arr = new long[len];
for (int i = 0; i < len; i++ ) {
arr[i] = i;
}
for (int pivot = 0; pivot < 64; pivot++ ) {
final long trueVal = pivot;
for (int i = 0; i < 1000; i++ ) {
shuffle(arr);
final long retVal = select(arr, 0, len - 1, pivot);
Assert.assertEquals(retVal, trueVal);
}
}
}
@Test
public void checkQuickSelect1BasedExcludingZeros() {
final int len = 64;
final int nonZeros = (7 * len) / 8;
final long[] arr = new long[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
final int pivot = len / 2;
final long trueVal = arr[pivot - 1];
shuffle(arr);
final long retVal = selectExcludingZeros(arr, nonZeros, pivot);
Assert.assertEquals(retVal, trueVal);
}
@Test
public void checkQuickSelect1BasedExcludingZeros2() {
final int len = 64;
final int nonZeros = 16;
final long[] arr = new long[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
shuffle(arr);
final int pivot = len / 2;
final long retVal = selectExcludingZeros(arr, nonZeros, pivot);
Assert.assertEquals(retVal, 0);
}
@Test
public void checkQuickSelect1BasedIncludingZeros() {
final int len = 64;
final int zeros = len / 8;
final long[] arr = new long[len];
for (int i = zeros; i < len; i++ ) {
arr[i] = i + 1;
}
final int pivot = len / 2;
final long trueVal = arr[pivot - 1];
shuffle(arr);
final long retVal = selectIncludingZeros(arr, pivot);
Assert.assertEquals(retVal, trueVal);
}
//double[] arrays
@Test
public void checkQuickSelectDbl0Based() {
final int len = 64;
final double[] arr = new double[len];
for (int i = 0; i < len; i++ ) {
arr[i] = i;
}
for (int pivot = 0; pivot < 64; pivot++ ) {
final double trueVal = pivot;
for (int i = 0; i < 1000; i++ ) {
shuffle(arr);
final double retVal = select(arr, 0, len - 1, pivot);
Assert.assertEquals(retVal, trueVal, 0.0);
}
}
}
@Test
public void checkQuickSelectDbl1BasedExcludingZeros() {
final int len = 64;
final int nonZeros = (7 * len) / 8;
final double[] arr = new double[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
final int pivot = len / 2;
final double trueVal = arr[pivot - 1];
shuffle(arr);
final double retVal = selectExcludingZeros(arr, nonZeros, pivot);
Assert.assertEquals(retVal, trueVal, 0.0);
}
@Test
public void checkQuickSelectDbl1BasedExcludingZeros2() {
final int len = 64;
final int nonZeros = 16;
final double[] arr = new double[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
shuffle(arr);
final int pivot = len / 2;
final double retVal = selectExcludingZeros(arr, nonZeros, pivot);
Assert.assertEquals(retVal, 0, 0.0);
}
@Test
public void checkQuickSelectDbl1BasedIncludingZeros() {
final int len = 64;
final int zeros = len / 8;
final double[] arr = new double[len];
for (int i = zeros; i < len; i++ ) {
arr[i] = i + 1;
}
final int pivot = len / 2;
final double trueVal = arr[pivot - 1];
shuffle(arr);
final double retVal = selectIncludingZeros(arr, pivot);
Assert.assertEquals(retVal, trueVal, 0.0);
}
/**
* Rearrange the elements of an array in random order.
* @param a long array
*/
public static void shuffle(final long[] a) {
final int N = a.length;
for (int i = 0; i < N; i++ ) {
final int r = i + uniform(N - i); // between i and N-1
final long temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Rearrange the elements of an array in random order.
* @param a double array
*/
public static void shuffle(final double[] a) {
final int N = a.length;
for (int i = 0; i < N; i++ ) {
final int r = i + uniform(N - i); // between i and N-1
final double temp = a[i];
a[i] = a[r];
a[r] = temp;
}
}
/**
* Returns an integer uniformly between 0 (inclusive) and n (exclusive) where {@code n > 0}
*
* @param n the upper exclusive bound
* @return random integer
*/
public static int uniform(final int n) {
if (n <= 0) {
throw new SketchesArgumentException("n must be positive");
}
return random.nextInt(n);
}
private static String printArr(final long[] arr) {
final StringBuilder sb = new StringBuilder();
final int len = arr.length;
sb.append(" Base0").append(" Base1").append(" Value").append(LS);
for (int i = 0; i < len; i++ ) {
sb
.append(format("%6d", i)).append(format("%6d", i + 1)).append(format("%6d", arr[i]))
.append(LS);
}
return sb.toString();
}
private static String printArr(final double[] arr) {
final StringBuilder sb = new StringBuilder();
final int len = arr.length;
sb.append(" Base0").append(" Base1").append(" Value").append(LS);
for (int i = 0; i < len; i++ ) {
sb
.append(format("%6d", i)).append(format("%6d", i + 1)).append(format("%9.3f", arr[i]))
.append(LS);
}
return sb.toString();
}
//For console testing
static void test1() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final long[] arr = new long[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2;
println("select(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot: " + pivot);
final long ret = select(arr, 0, len - 1, pivot);
println("Return value of 0-based pivot including zeros:");
println("select(arr, 0, " + (len - 1) + ", " + pivot + ") => " + ret);
println("0-based index of pivot = pivot = " + (pivot));
println("Result Array:" + LS);
println(printArr(arr));
}
//For console testing
static void test2() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final long[] arr = new long[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2; //= 8
println("selectDiscountingZeros(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot= " + pivot);
final long ret = selectExcludingZeros(arr, nonZeros, pivot);
println("Return value of 1-based pivot discounting zeros:");
println("selectDiscountingZeros(arr, " + nonZeros + ", " + pivot + ") => " + ret);
println("0-based index of pivot= pivot+zeros-1 = " + ((pivot + zeros) - 1));
println("Result Array:" + LS);
println(printArr(arr));
}
//For console testing
static void test3() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final long[] arr = new long[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2; //= 8
println("selectIncludingZeros(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot= " + pivot);
final long ret = selectIncludingZeros(arr, pivot);
println("Return value of 1-based pivot including zeros:");
println("selectIncludingZeros(arr, " + pivot + ") => " + ret);
println("0-based index of pivot= pivot-1 = " + (pivot - 1));
println("Result Array:" + LS);
println(printArr(arr));
}
static void testDbl1() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final double[] arr = new double[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2;
println("select(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot: " + pivot);
final double ret = select(arr, 0, len - 1, pivot);
println("Return value of 0-based pivot including zeros:");
println("select(arr, 0, " + (len - 1) + ", " + pivot + ") => " + ret);
println("0-based index of pivot = pivot = " + (pivot));
println("Result Array:" + LS);
println(printArr(arr));
}
//For console testing
static void testDbl2() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final double[] arr = new double[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2; //= 8
println("selectDiscountingZeros(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot= " + pivot);
final double ret = selectExcludingZeros(arr, nonZeros, pivot);
println("Return value of 1-based pivot discounting zeros:");
println("selectDiscountingZeros(arr, " + nonZeros + ", " + pivot + ") => " + ret);
println("0-based index of pivot= pivot+zeros-1 = " + ((pivot + zeros) - 1));
println("Result Array:" + LS);
println(printArr(arr));
}
//For console testing
static void testDbl3() {
final int len = 16;
final int nonZeros = (3 * len) / 4;
final int zeros = len - nonZeros;
final double[] arr = new double[len];
for (int i = 0; i < nonZeros; i++ ) {
arr[i] = i + 1;
}
println("Generated Numbers:");
println(printArr(arr));
shuffle(arr);
println("Randomized Ordering:");
println(printArr(arr));
final int pivot = len / 2; //= 8
println("selectIncludingZeros(...):");
println("ArrSize : " + len);
println("NonZeros: " + nonZeros);
println("Zeros : " + zeros);
println("Choose pivot at 1/2 array size, pivot= " + pivot);
final double ret = selectIncludingZeros(arr, pivot);
println("Return value of 1-based pivot including zeros:");
println("selectIncludingZeros(arr, " + pivot + ") => " + ret);
println("0-based index of pivot= pivot-1 = " + (pivot - 1));
println("Result Array:" + LS);
println(printArr(arr));
}
// public static void main(String[] args) {
// println(LS+"==LONGS 1=========="+LS);
// test1();
// println(LS+"==LONGS 2=========="+LS);
// test2();
// println(LS+"==LONGS 3=========="+LS);
// test3();
// println(LS+"==DOUBLES 1========"+LS);
// testDbl1();
// println(LS+"==DOUBLES 2========"+LS);
// testDbl2();
// println(LS+"==DOUBLES 3========"+LS);
// testDbl3();
//
//
// QuickSelectTest qst = new QuickSelectTest();
// qst.checkQuickSelect0Based();
// qst.checkQuickSelect1BasedExcludingZeros();
// qst.checkQuickSelect1BasedExcludingZeros2();
// qst.checkQuickSelect1BasedIncludingZeros();
// qst.checkQuickSelectDbl0Based();
// qst.checkQuickSelectDbl1BasedExcludingZeros();
// qst.checkQuickSelectDbl1BasedExcludingZeros2();
// qst.checkQuickSelectDbl1BasedIncludingZeros();
//
// }
@Test
public void printlnTest() {
println("PRINTING: " + this.getClass().getName());
}
/**
* @param s value to print
*/
static void println(final String s) {
//System.out.println(s); //disable here
}
/**
* @param d value to print
*/
static void println(final double d) {
//System.out.println(d); //disable here
}
}