You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by le...@apache.org on 2024/01/08 01:24:45 UTC
(datasketches-characterization) branch master updated: Bringing Kll test profiles up to date.
This is an automated email from the ASF dual-hosted git repository.
leerho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/datasketches-characterization.git
The following commit(s) were added to refs/heads/master by this push:
new 2028e49 Bringing Kll test profiles up to date.
2028e49 is described below
commit 2028e492749af14d35a0ff436a10f60aae79cf6f
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Sun Jan 7 17:24:35 2024 -0800
Bringing Kll test profiles up to date.
---
src/main/java/org/apache/datasketches/Align.java | 739 +++++++++++++++++++++
.../java/org/apache/datasketches/DoubleBits.java | 377 +++++++++++
.../apache/datasketches/DoubleIntIntTriple.java | 86 +++
.../java/org/apache/datasketches/DoublePair.java | 4 +
.../org/apache/datasketches/FloatIntIntTriple.java | 85 +++
src/main/java/org/apache/datasketches/Job.java | 8 +-
.../org/apache/datasketches/SpecialRandom.java | 85 +++
.../characterization/AccuracyStats.java | 6 +-
.../datasketches/characterization/Shuffle.java | 36 +-
...llDoublesSketchRankGaussianAccuracyProfile.java | 87 ++-
.../kll/KllSketchAccuracyProfile.java | 372 -----------
.../kll/KllWorstCaseSketchAccuracyProfile.java | 280 ++++++++
.../uniquecount/BaseAccuracyProfile.java | 2 +-
.../KllDoublesSketchRankGaussianAccuracyJob.conf | 20 +-
...Job.conf => KllWorstCaseSketchAccuracyJob.conf} | 12 +-
15 files changed, 1768 insertions(+), 431 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/Align.java b/src/main/java/org/apache/datasketches/Align.java
new file mode 100755
index 0000000..86d7fa6
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/Align.java
@@ -0,0 +1,739 @@
+/*
+ * 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;
+
+/**
+ * Provides simple alignment and fill functions for strings, boolean,integer
+ * primitives and double in fixed-width character fields.
+ * @author Lee Rhodes
+ */
+public class Align {
+ private static final String NULL = "null";
+
+ //LEFT
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final String arg, final int colwidth) {
+ return left(arg, colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final String arg, final int colwidth, final char pad) {
+ if (colwidth < 1) { return ""; }
+ final String s = (arg == null) ? NULL : arg;
+ final int slen = s.length();
+ final char[] buf = new char[colwidth];
+ int pads = colwidth - slen;
+ if (pads > 0) {
+ s.getChars(0, slen, buf, 0);
+ for (int i = colwidth; i-- > slen;) {
+ buf[i] = pad;
+ }
+ }
+ else {
+ pads = -pads;
+ s.getChars(0, colwidth, buf, 0);
+ }
+ return new String(buf);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final long arg, final int colwidth) {
+ return left(Long.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final long arg, final int colwidth, final char pad) {
+ return left(Long.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final int arg, final int colwidth) {
+ return left(Integer.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final int arg, final int colwidth, final char pad) {
+ return left(Integer.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final short arg, final int colwidth) {
+ return left(Short.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final short arg, final int colwidth, final char pad) {
+ return left(Short.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final byte arg, final int colwidth) {
+ return left(Byte.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final byte arg, final int colwidth, final char pad) {
+ return left(Byte.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final boolean arg, final int colwidth) {
+ return left(Boolean.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final boolean arg, final int colwidth, final char pad) {
+ return left(Boolean.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with space characters, if needed. If arg (as a String) is longer than the
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @return left justified arg
+ */
+ public static String left(final double arg, final int colwidth) {
+ return left(Double.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Left justifies arg (as a String) within colwidth filling in the right
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the right.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * left justified.
+ * @param pad The pad character to fill any positions to the right of the
+ * given argument, if needed.
+ * @return left justified arg
+ */
+ public static String left(final double arg, final int colwidth, final char pad) {
+ return left(Double.toString(arg), colwidth, pad);
+ }
+
+ //RIGHT
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final String arg, final int colwidth) {
+ return right(arg, colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final String arg, final int colwidth, final char pad) {
+ if (colwidth < 1) { return ""; }
+ final String s = (arg == null) ? NULL : arg;
+ final int slen = s.length();
+ final char[] buf = new char[colwidth];
+ int pads = colwidth - slen;
+ if (pads > 0) {
+ s.getChars(0, slen, buf, pads);
+ for (int i = pads; i-- > 0;) {
+ buf[i] = pad;
+ }
+ }
+ else { //string is longer than colwidth
+ pads = -pads;
+ s.getChars(pads, slen, buf, 0);
+ }
+ return new String(buf);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final long arg, final int colwidth) {
+ return right(Long.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final long arg, final int colwidth, final char pad) {
+ return right(Long.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final int arg, final int colwidth) {
+ return right(Integer.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final int arg, final int colwidth, final char pad) {
+ return right(Integer.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final short arg, final int colwidth) {
+ return right(Short.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final short arg, final int colwidth, final char pad) {
+ return right(Short.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final byte arg, final int colwidth) {
+ return right(Byte.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final byte arg, final int colwidth, final char pad) {
+ return right(Byte.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final boolean arg, final int colwidth) {
+ return right(Boolean.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final boolean arg, final int colwidth, final char pad) {
+ return right(Boolean.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with space characters, if needed. If arg (as a String) is longer than
+ * the colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @return right justified arg
+ */
+ public static String right(final double arg, final int colwidth) {
+ return right(Double.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Right justifies arg (as a String) within colwidth filling in the left
+ * with the pad character, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on the left.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given argument is
+ * right justified.
+ * @param pad The pad character to fill any positions to the left of the
+ * given argument, if needed.
+ * @return right justified arg
+ */
+ public static String right(final double arg, final int colwidth, final char pad) {
+ return right(Double.toString(arg), colwidth, pad);
+ }
+
+ //CENTER
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final String arg, final int colwidth) {
+ return center(arg, colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final String arg, final int colwidth, final char pad) {
+ if (colwidth < 1) { return ""; }
+ final String s = (arg == null) ? NULL : arg;
+ final int slen = s.length();
+ final char[] buf = new char[colwidth];
+ int pads = colwidth - slen;
+ if (pads > 0) {
+ for (int i = colwidth; i-- > 0;) { buf[i] = pad; }
+ s.getChars(0, slen, buf, pads / 2);
+ }
+ else {
+ pads = (-pads) / 2;
+ s.getChars(pads, pads + colwidth, buf, 0);
+ }
+ return new String(buf);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final long arg, final int colwidth) {
+ return center(Long.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final long arg, final int colwidth, final char pad) {
+ return center(Long.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final int arg, final int colwidth) {
+ return center(Integer.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final int arg, final int colwidth, final char pad) {
+ return center(Integer.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final short arg, final int colwidth) {
+ return center(Short.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final short arg, final int colwidth, final char pad) {
+ return center(Short.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final byte arg, final int colwidth) {
+ return center(Byte.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final byte arg, final int colwidth, final char pad) {
+ return center(Byte.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final boolean arg, final int colwidth) {
+ return center(Boolean.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final boolean arg, final int colwidth, final char pad) {
+ return center(Boolean.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with
+ * space characters, if needed. If arg (as a String) is longer than
+ * colwidth, it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @return centered arg
+ */
+ public static String center(final double arg, final int colwidth) {
+ return center(Double.toString(arg), colwidth, ' ');
+ }
+
+ /**
+ * Centers arg (as a String) within colwidth filling in the sides with the
+ * pad character, if needed. If arg (as a String) is longer than colwidth,
+ * it truncates on both sides.
+ *
+ * @param arg The given argument.
+ * @param colwidth The width of the space into which the given
+ * argument (as a String) is centered.
+ * @param pad The pad character to fill any positions to the sides of the
+ * given argument (as a String), if needed.
+ * @return centered arg
+ */
+ public static String center(final double arg, final int colwidth, final char pad) {
+ return center(Double.toString(arg), colwidth, pad);
+ }
+
+ /**
+ * Example and test.
+ * @param args input parameters
+ */
+ public static void main(final String[] args) {
+ final String s = "This is a string";
+ final String left = "->|";
+ final String right = "|<-";
+ final String out = left + center(s,14) + right;
+ println(out);
+ }
+
+ private final static boolean enablePrinting = true;
+
+ /**
+ * @param format the format
+ * @param args the args
+ */
+ @SuppressWarnings("unused")
+ private static final void printf(final String format, final Object ... args) {
+ if (enablePrinting) { System.out.printf(format, args); }
+ }
+
+ /**
+ * @param o the Object to println
+ */
+ private static final void println(final Object o) {
+ if (enablePrinting) { println(o.toString()); }
+ }
+
+}
diff --git a/src/main/java/org/apache/datasketches/DoubleBits.java b/src/main/java/org/apache/datasketches/DoubleBits.java
new file mode 100755
index 0000000..2f7fc0c
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/DoubleBits.java
@@ -0,0 +1,377 @@
+/*
+ * 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 org.testng.annotations.Test;
+
+/**
+ * If you are developing any functions that operate directly on the IEEE 754
+ * double-precision 64-bit fields you will need this class.
+ * @author Lee Rhodes
+ */
+public final class DoubleBits {
+ public static final long SIGN = 1L << 63; //only the MSB (sign) set
+ public static final long DEXP1 = 1L << 52; //an exponent value of 1
+ public static final long DEXP2 = 2L << 52; //an exponent value of 2
+ public static final long DMANMASK = DEXP1 - 1L; //mantissa mask (52 1's)
+ public static final long DEXP1023 = 1023L << 52; //exp = 1023 (10 1's)
+ public static final long DEXP1025 = 1025L << 52; //exp = 1025
+ public static final long DEXP1026 = 1026L << 52; //exp = 1026
+ public static final long DEXPMASK = 2047L << 52;//exp = 2047 (11 1's), mask.
+
+ private DoubleBits() {
+ //Empty Constructor
+ }
+
+ /**
+ * Returns true if the IEEE 754 sign bit is set even if the value represents a NaN or zero.
+ * @param d the given double
+ * @return the sign bit.
+ */
+ public static boolean isNegative(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return ((bits & SIGN) != 0L);
+ }
+
+ /**
+ * Returns true if the value is a +/- denormalized number but not +/- zero.
+ * @param d the given double
+ * @return true if the value is a +/- denormalized number but not +/- zero.
+ */
+ public static boolean isDenormal(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return (d != 0.0) && ((bits & DEXPMASK) == 0L) ;
+ }
+
+ /**
+ * Returns true if the value is +/- Infinity
+ * @param d the given double
+ * @return true if the value is +/- Infinity
+ */
+ public static boolean isInfinity(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return ((bits & ~SIGN) == DEXPMASK);
+ }
+
+ /**
+ * Returns true if the value is not a NaN or Infinity
+ * @param d the given double
+ * @return true if the value is not a NaN or Infinity
+ */
+ public static boolean isValid(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return ((bits & DEXPMASK) != DEXPMASK);
+ }
+
+ /**
+ * Returns true if the value is a valid argument for the log function.
+ * In other words, it cannot be +/- NaN, zero, or Infinity, but it may
+ * be a denormal number.
+ * @param d the given double
+ * @return true if the value is a valid argument for the log function
+ */
+ public static boolean isValidLogArgument(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return ((bits + DEXP1) > DEXP1);
+ }
+
+ /**
+ * Returns true if the value is a denormal or not a valid argument for the log function.
+ * @param d the given double
+ * @return true if the value is a denormal or not a valid argument for the log function.
+ */
+ public static boolean isDenormalOrNotValidLogArgument(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return ((bits + DEXP1) < DEXP2);
+ }
+
+ /**
+ * Returns the signum function of the argument; zero if the argument
+ * is zero, 1.0 if the argument is greater than zero, -1.0 if the
+ * argument is less than zero. If the argument is +/- NaN or zero,
+ * the result is the same as the argument.<br/>
+ *
+ * <p>Note that this is a faster, simpler replacement for the needlessly
+ * complicated implementation in sun.misc.FpUtils.</p>
+ *
+ * @param d the given double
+ * @return the signum function of the argument
+ */
+ public static double signum(final double d) {
+ return ((d != d) || (d == 0.0)) ? d : (d < 0.0) ? -1.0 : 1.0;
+ }
+
+ /**
+ * Returns the 11 bit exponent of a double flush right as an int.
+ * @param d the given double
+ * @return the exponent bits.
+ */
+ public static int exponentToIntBits(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return (int)((bits & DEXPMASK) >>> 52);
+ }
+
+ /**
+ * Returns the 52 bits of the mantissa as a long.
+ * @param d the given double
+ * @return the mantissa bits.
+ */
+ public static long mantissaToLongBits(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return bits & DMANMASK;
+ }
+
+ /**
+ * Returns the mathematical Base 2 exponent as an int. The offset
+ * has been removed.
+ * @param d the given double
+ * @return the mathematical Base 2 exponent
+ */
+ public static int base2Exponent(final double d) {
+ final int e = exponentToIntBits(d);
+ return (e == 0) ? -1022 : e - 1023;
+ }
+
+ /**
+ * Given the double value d, replace the exponent bits
+ * with the raw exponent value provided in exp. If you are converting from
+ * a mathematical Base 2 exponent, the offset of 1023 must be added first.
+ * @param d the given double
+ * @param exp the given exponent as raw bits
+ * @return the double value d with replaced exponent bits
+ */
+ public static double setRawExponentBits(final double d, final int exp) {
+ long bits = Double.doubleToRawLongBits(d);
+ bits &= ~DEXPMASK; //remove old exponent bits
+ bits |= (exp & 0x7FFL) << 52;//insert the new exponent
+ return Double.longBitsToDouble(bits);
+ }
+
+ /**
+ * Given the double value d, replace the mantissa bits
+ * with the given mantissa.
+ * @param d the given double
+ * @param man the given mantissa
+ * @return the double value d with replaced mantissa bits
+ */
+ public static double setMantissaBits(final double d, final long man) {
+ long bits = Double.doubleToRawLongBits(d);
+ bits &= ~DMANMASK; //remove old mantissa bits
+ bits |= (DMANMASK & man); //insert the new mantissa
+ return Double.longBitsToDouble(bits);
+ }
+
+ /**
+ * Returns the given double with the sign bit set as specified by the given boolean.
+ * @param d the given double
+ * @param negative desired value
+ * @return the given double with the sign bit set as specified by the given boolean.
+ */
+ public static double setSignBit(final double d, final boolean negative) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return negative
+ ? Double.longBitsToDouble(bits | SIGN)
+ : Double.longBitsToDouble(bits & ~SIGN);
+ }
+
+ /**
+ * Given a double, this returns a decimal value representing the effective
+ * fractional value of the double's mantissa, which is independent of the
+ * value of the exponent with only one exception. If the exponent field 'e'
+ * of a double is in the range [1, 2046] the value of a double can be
+ * expressed mathematically as 1.fraction X 2^(e-1023). If the exponent
+ * value e == 0, the value is expressed as 0.fraction X 2^(-1022), which is
+ * called a denormal number. Denormal numbers are only required for
+ * magnitudes less than 2.2250738585072014E-308. Very small indeed and much
+ * smaller than normal rounding errors.
+ *
+ * @param d the given double
+ * @return a value representing the fractional value of the
+ * double's mantissa. It will be in the format 1.fraction or
+ * 0.fraction depending on the exponent as explained above.
+ */
+ public static double mantissaFraction(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ final long exp = bits & DEXPMASK;
+ final long sign = bits & SIGN; //required in case d is a NaN or zero
+ //remove exp & sign, insert exponent for 1.0
+ final long man = (bits & DMANMASK) | DEXP1023;
+ double d2 = Double.longBitsToDouble(man); //back to double as 1.xxxxx
+ d2 = (exp == 0L) ? d2 - 1.0 : d2;
+ return (sign != 0L) ? -d2 : d2;
+ }
+
+ /**
+ * Returns the given double as a string of the form
+ * <pre>
+ * SP.FFFFF...FFFBTEEEE
+ * Where
+ * S = the sign of the magnitude only if negative, no space if positive
+ * P = mantissa prefix of 1 or 0
+ * F = decimal fraction
+ * B = indicates binary power of 2 representation
+ * T = the sign of the exponent only if negative
+ * E = the exponent of 2
+ * </pre>
+ * @param d the given double
+ * @return the given double as a string
+ */
+ public static String doubleToBase2String(final double d) {
+ final boolean sign = isNegative(d);
+ if (d == 0.0) { return sign ? "-0.0B0" : "0.0B0"; }
+ return Double.toString(mantissaFraction(d)) + "B" + base2Exponent(d);
+ }
+
+ /**
+ * Returns a formatted string representing the fields of an
+ * IEEE 754 64-bit double-precision floating point value.
+ * The output string is in the form:
+ * <pre>
+ * S EEEEEEEEEEE MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+ * </pre>
+ * where S represents the sign bit, E represents bits of the Exponent field,
+ * and M represents bits of the Mantissa field of the double value.
+ * @param d the given double
+ * @return the formatted string of the fields of a <i>double</i>.
+ */
+ public static String doubleToBitString(final double d) {
+ final long bits = Double.doubleToRawLongBits(d);
+ return longBitsToDoubleBitString(bits);
+ }
+
+ /**
+ * Returns a formatted string representing the fields of an
+ * IEEE 754 64-bit double-precision floating point value presented as a
+ * <i>long</i>. The output string is in the form:
+ * <pre>
+ * S EEEEEEEEEEE MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+ * </pre>
+ * where S represents the sign bit, E represents bits of the Exponent field,
+ * and M represents bits of the Mantissa field of the double value.
+ * @param bits the <i>double</i> value in the form of a <i>long</i> to be
+ * examined.
+ * @return the formatted string of the fields of a <i>double</i>.
+ */
+ public static String longBitsToDoubleBitString(final long bits) {
+ final int intSign = ((bits & SIGN) != 0L) ? 1 : 0;
+ final int e = (int)((bits & DEXPMASK) >>> 52);
+ final String estr = Align.right(Integer.toBinaryString(e), 11, '0');
+ final long m = bits & DMANMASK;
+ final String mstr = Align.right(Long.toBinaryString(m), 52, '0');
+ return intSign + " " + estr + " " + mstr;
+ }
+
+ /**
+ * Helper method to determine whether a specified string is a
+ * parsable numeric value or not.
+ *
+ * @param string the input string to analyze.
+ *
+ * @return true if the value is numeric (integer, float, double); false if
+ * not.
+ */
+ public static boolean isNumeric(final String string) {
+
+ boolean isNum = false;
+
+ try {
+
+ Double.parseDouble(string);
+ isNum = true;
+
+ } catch (final NumberFormatException exc ) {
+ // We have a non numeric value.
+ }
+
+ return isNum;
+ }
+
+ private static void checkDoubleBits(final double d, final String txt) {
+ println("Test :" + txt);
+ println("Value : " + d);
+ println("Bits : " + doubleToBitString(d));
+ println("Base2 : " + doubleToBase2String(d));
+ println("Negative : " + isNegative(d));
+ println("Denormal : " + isDenormal(d));
+ println("Infinity : " + isInfinity(d));
+ println("Valid : " + isValid(d));
+ println("Valid Log: " + isValidLogArgument(d));
+ println("Signum : " + signum(d));
+ println("");
+ }
+
+ @Test
+ public static void doubleBitsTest() {
+ checkDoubleBits(4.9E-324,"+Denormal");
+ checkDoubleBits(-4.9E-324,"-Denormal");
+ checkDoubleBits(0.0,"+Zero");
+ checkDoubleBits(-0.0,"-Zero");
+ checkDoubleBits(1.0,"+1.0");
+ checkDoubleBits(-1.0,"-1.0");
+ checkDoubleBits(Double.MAX_VALUE,"MAX_VALUE");
+ checkDoubleBits(Double.MIN_VALUE,"MIN_VALUE");
+ checkDoubleBits(Double.POSITIVE_INFINITY,"+INFINITY");
+ checkDoubleBits(Double.NEGATIVE_INFINITY,"-INFINITY");
+ checkDoubleBits(Double.NaN,"+QNaN"); //Quiet NaN
+ checkDoubleBits(setSignBit(Double.NaN, true),"-QNaN"); //-Quiet NaN
+ }
+
+ /**
+ * The maximum integral value that a double can resolve exactly is 8PebiBytes
+ * or (1L << 53).
+ */
+ @Test
+ public static void checkMaxIntegralPrcisionOfDouble() {
+ final double EIGHT_PEBI = (1L << 53);
+ println(doubleToBitString(EIGHT_PEBI + 1L) + ", " + Double.toString(EIGHT_PEBI + 1L)); //over the limit
+ println(doubleToBitString(EIGHT_PEBI) + ", " + Double.toString(EIGHT_PEBI));
+ println(doubleToBitString(EIGHT_PEBI - 1L) + ", " + Double.toString(EIGHT_PEBI - 1L));
+ }
+
+ /**
+ * The maximum integral value that a float can resolve exactly is 16MebiBytes
+ * or (1 << 24).
+ */
+ @Test
+ public static void checkMaxIntegralPrcisionOfFloat() {
+ final float SIXTEEN_MEBI = (1 << 24);
+ println(Float.toString(SIXTEEN_MEBI + 1)); //over the limit
+ println(Float.toString(SIXTEEN_MEBI));
+ println(Float.toString(SIXTEEN_MEBI - 1));
+ }
+
+ private final static boolean enablePrinting = true;
+
+ /**
+ * @param format the format
+ * @param args the args
+ */
+ @SuppressWarnings("unused")
+ private static final void printf(final String format, final Object ... args) {
+ if (enablePrinting) { System.out.printf(format, args); }
+ }
+
+ /**
+ * @param o the Object to println
+ */
+ private static final void println(final Object o) {
+ if (enablePrinting) { System.out.println(o.toString()); }
+ }
+}
diff --git a/src/main/java/org/apache/datasketches/DoubleIntIntTriple.java b/src/main/java/org/apache/datasketches/DoubleIntIntTriple.java
new file mode 100644
index 0000000..a99b9e3
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/DoubleIntIntTriple.java
@@ -0,0 +1,86 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * A triple (double value, int index, int rank) with sorting.
+ */
+public class DoubleIntIntTriple {
+ public double value;
+ public int index;
+ public int rank;
+ private static final CompareValue compValue = new CompareValue();
+ private static final CompareIndex compIndex = new CompareIndex();
+ private static final CompareRank compRank = new CompareRank();
+
+ public static final DoubleIntIntTriple[] sortByValue(final DoubleIntIntTriple[] array) {
+ Arrays.sort(array, compValue);
+ return array;
+ }
+
+ public static final DoubleIntIntTriple[] sortByIndex(final DoubleIntIntTriple[] array) {
+ Arrays.sort(array, compIndex);
+ return array;
+ }
+
+ public static final DoubleIntIntTriple[] sortByRank(final DoubleIntIntTriple[] array) {
+ Arrays.sort(array, compRank);
+ return array;
+ }
+
+ public static final double[] getValueArray(final DoubleIntIntTriple[] array) {
+ final int len = array.length;
+ final double[] out = new double[len];
+ for (int i = 0; i < len; i++) { out[i] = array[i].value; }
+ return out;
+ }
+
+ public static final int[] getRankArray(final DoubleIntIntTriple[] array) {
+ final int len = array.length;
+ final int[] out = new int[len];
+ for (int i = 0; i < len; i++) { out[i] = array[i].rank; }
+ return out;
+ }
+
+ private static final class CompareValue implements Comparator<DoubleIntIntTriple> {
+ @Override
+ public int compare(final DoubleIntIntTriple t1, final DoubleIntIntTriple t2) {
+ return Double.compare(t1.value, t2.value); // handles NaN, +/- 0, etc.
+ }
+ }
+
+ private static final class CompareIndex implements Comparator<DoubleIntIntTriple> {
+ @Override
+ public int compare(final DoubleIntIntTriple t1, final DoubleIntIntTriple t2) {
+ return Integer.compare(t1.index, t2.index);
+ }
+ }
+
+ private static final class CompareRank implements Comparator<DoubleIntIntTriple> {
+ @Override
+ public int compare(final DoubleIntIntTriple t1, final DoubleIntIntTriple t2) {
+ return Integer.compare(t1.rank, t2.rank);
+ }
+ }
+
+}
diff --git a/src/main/java/org/apache/datasketches/DoublePair.java b/src/main/java/org/apache/datasketches/DoublePair.java
index 3b14a67..b18d7f6 100644
--- a/src/main/java/org/apache/datasketches/DoublePair.java
+++ b/src/main/java/org/apache/datasketches/DoublePair.java
@@ -21,6 +21,9 @@ package org.apache.datasketches;
import java.util.Comparator;
+/**
+ * A pair (double x, double y) with a comparator on x.
+ */
public class DoublePair implements Comparator<DoublePair> {
public double x;
public double y;
@@ -34,4 +37,5 @@ public class DoublePair implements Comparator<DoublePair> {
public int compare(final DoublePair p1, final DoublePair p2) {
return Double.compare(p1.x, p2.x); // handles NaN, +/- 0, etc.
}
+
}
diff --git a/src/main/java/org/apache/datasketches/FloatIntIntTriple.java b/src/main/java/org/apache/datasketches/FloatIntIntTriple.java
new file mode 100644
index 0000000..ec8d7c2
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/FloatIntIntTriple.java
@@ -0,0 +1,85 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * A triple (float value, int index, int rank) with sorting.
+ */
+public class FloatIntIntTriple {
+ public float value;
+ public int index;
+ public int rank;
+ private static final CompareValue compValue = new CompareValue();
+ private static final CompareIndex compIndex = new CompareIndex();
+ private static final CompareRank compRank = new CompareRank();
+
+ public static final FloatIntIntTriple[] sortByValue(final FloatIntIntTriple[] array) {
+ Arrays.sort(array, compValue);
+ return array;
+ }
+
+ public static final FloatIntIntTriple[] sortByIndex(final FloatIntIntTriple[] array) {
+ Arrays.sort(array, compIndex);
+ return array;
+ }
+
+ public static final FloatIntIntTriple[] sortByRank(final FloatIntIntTriple[] array) {
+ Arrays.sort(array, compRank);
+ return array;
+ }
+
+ public static final float[] getValueArray(final FloatIntIntTriple[] array) {
+ final int len = array.length;
+ final float[] out = new float[len];
+ for (int i = 0; i < len; i++) { out[i] = array[i].value; }
+ return out;
+ }
+
+ public static final int[] getRankArray(final FloatIntIntTriple[] array) {
+ final int len = array.length;
+ final int[] out = new int[len];
+ for (int i = 0; i < len; i++) { out[i] = array[i].rank; }
+ return out;
+ }
+
+ private static final class CompareValue implements Comparator<FloatIntIntTriple> {
+ @Override
+ public int compare(final FloatIntIntTriple t1, final FloatIntIntTriple t2) {
+ return Float.compare(t1.value, t2.value); // handles NaN, +/- 0, etc.
+ }
+ }
+
+ private static final class CompareIndex implements Comparator<FloatIntIntTriple> {
+ @Override
+ public int compare(final FloatIntIntTriple t1, final FloatIntIntTriple t2) {
+ return Integer.compare(t1.index, t2.index);
+ }
+ }
+
+ private static final class CompareRank implements Comparator<FloatIntIntTriple> {
+ @Override
+ public int compare(final FloatIntIntTriple t1, final FloatIntIntTriple t2) {
+ return Integer.compare(t1.rank, t2.rank);
+ }
+ }
+}
diff --git a/src/main/java/org/apache/datasketches/Job.java b/src/main/java/org/apache/datasketches/Job.java
index 0f28ef2..f170d42 100644
--- a/src/main/java/org/apache/datasketches/Job.java
+++ b/src/main/java/org/apache/datasketches/Job.java
@@ -81,13 +81,8 @@ public class Job {
throw new IllegalStateException("Could not configure PrintWriters.");
}
//OUTPUT ORDER
-
println("START JOB " + profileName );
println("Date Time: " + readableSimpleDateFmt.format(date));
- println("");
- println("PROPERTIES:");
- println(prop.extractKvPairs(LS));
- flush(); //flush print buffer
/***RUN THE PROFILE ****************/
startTime_mS = System.currentTimeMillis();
@@ -98,6 +93,9 @@ public class Job {
/***********************************/
println("");
+ println("PROPERTIES:");
+ println(prop.extractKvPairs(LS));
+
println("Total Job Time: " + milliSecToString(testTime_mS));
println("END JOB " + profileName + LS + LS);
flush();
diff --git a/src/main/java/org/apache/datasketches/SpecialRandom.java b/src/main/java/org/apache/datasketches/SpecialRandom.java
new file mode 100644
index 0000000..f00a852
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/SpecialRandom.java
@@ -0,0 +1,85 @@
+/*
+ * 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;
+
+/**
+ * This SpecialRandom generator extends the java.util.Random to include some important missing methods.
+ */
+public class SpecialRandom extends java.util.Random {
+ /** use serialVersionUID from JDK 1.1 for interoperability */
+ static final long serialVersionUID = 3905348978240129619L;
+
+ /**
+ * Constructs a new special random generator.
+ */
+ public SpecialRandom() {
+ super();
+ }
+
+ /**
+ * Provides a seed to make this generator deterministic.
+ * @param seed the given seed.
+ */
+ public SpecialRandom(final long seed) {
+ super(seed);
+ }
+
+ /**
+ * This makes visible an important hidden class from Random. It provides the next pseudorandom integer value
+ * consisting of the number given bits as low order bits.
+ * @param bits the number of random low-order bits from the range [1, 32] (inclusive, inclusive)
+ * @return the next pseudorandom value consisting of <i>bits</i> low-order bits.
+ */
+ @Override
+ public int next(final int bits) {
+ return super.next(bits);
+ }
+
+ /**
+ * This provides the next pseudorandom long value consisting of the number of given bits as low order bits.
+ * @param bits the number of random low-order bits from the range [1, 64] (inclusive, inclusive)
+ * @return the next pseudorandom value consisting of <i>bits</i> low-order bits.
+ */
+ public long nextLong(final int bits) {
+ if (bits <= 32) { return next(bits); }
+ return ((long)(next(bits - 32)) << 32) + next(32);
+ }
+
+ /**
+ * Returns an approximate uniform random distribution of long values between 0 (inclusive) and bound (exclusive);
+ * @param bound a value from the range [2, bound).
+ * @return an approximate uniform random long from the range [2, bound).
+ */
+ public long nextLong(final long bound) {
+ if (bound <= 1L) { throw new IllegalArgumentException("bound must be greater than 1"); }
+ final long m = bound - 1L;
+ long r;
+ if ((bound & m) == 0) { //bound is power of 2
+ final int nlz = Long.numberOfLeadingZeros(bound);
+ final int bits = 64 - nlz - 1;
+ r = nextLong(bits);
+ } else {
+ r = nextLong(63);
+ for (long u = r; u - (r = u % bound) + m < 0; u = nextLong(63)) { }
+ }
+ return r;
+ }
+
+}
diff --git a/src/main/java/org/apache/datasketches/characterization/AccuracyStats.java b/src/main/java/org/apache/datasketches/characterization/AccuracyStats.java
index 331d545..0a7a3d3 100644
--- a/src/main/java/org/apache/datasketches/characterization/AccuracyStats.java
+++ b/src/main/java/org/apache/datasketches/characterization/AccuracyStats.java
@@ -40,7 +40,7 @@ public class AccuracyStats {
public double sumSqErr = 0;
public double rmsre = 0; //used later for plotting, set externally
public double trueValue; //set by constructor, used only for error analysis
- public long uniques; //set by constructor, used as a coordinate
+ public long uniques; //set by constructor, used as a coordinate for intersection
public int bytes = 0;
/**
@@ -123,8 +123,8 @@ public class AccuracyStats {
/**
* Build the AccuracyStats Array based on fractional powers of 10
- * @param log10Min log_base2 of the minimum number of uniques used
- * @param log10Max log_base2 of the maximum number of uniques used
+ * @param log10Min log_base10 of the minimum number of uniques used
+ * @param log10Max log_base10 of the maximum number of uniques used
* @param ppb the number of points per base (10)
* @param lgQK the lgK for the Quantiles sketch
* @return an AccuracyStats array
diff --git a/src/main/java/org/apache/datasketches/characterization/Shuffle.java b/src/main/java/org/apache/datasketches/characterization/Shuffle.java
index 340b02e..62596dc 100644
--- a/src/main/java/org/apache/datasketches/characterization/Shuffle.java
+++ b/src/main/java/org/apache/datasketches/characterization/Shuffle.java
@@ -30,13 +30,15 @@ public final class Shuffle {
/**
* Shuffle the given input float array
* @param array input array
+ * @return the given array, shuffled.
*/
- public static void shuffle(final float[] array) {
+ public static float[] shuffle(final float[] array) {
final int arrLen = array.length;
for (int i = 0; i < arrLen; i++) {
final int r = rand.nextInt(i + 1);
swap(array, i, r);
}
+ return array;
}
private static void swap(final float[] array, final int i1, final int i2) {
@@ -48,13 +50,15 @@ public final class Shuffle {
/**
* Shuffle the given input double array
* @param array input array
+ * @return the given array, shuffled.
*/
- public static void shuffle(final double[] array) {
+ public static double[] shuffle(final double[] array) {
final int arrLen = array.length;
for (int i = 0; i < arrLen; i++) {
final int r = rand.nextInt(i + 1);
swap(array, i, r);
}
+ return array;
}
private static void swap(final double[] array, final int i1, final int i2) {
@@ -66,13 +70,15 @@ public final class Shuffle {
/**
* Shuffle the given input long array
* @param array input array
+ * @return the given array, shuffled.
*/
- public static void shuffle(final long[] array) {
+ public static long[] shuffle(final long[] array) {
final int arrLen = array.length;
for (int i = 0; i < arrLen; i++) {
final int r = rand.nextInt(i + 1);
swap(array, i, r);
}
+ return array;
}
private static void swap(final long[] array, final int i1, final int i2) {
@@ -84,13 +90,15 @@ public final class Shuffle {
/**
* Shuffle the given input int array
* @param array input array
+ * @return the given array, shuffled.
*/
- public static void shuffle(final int[] array) {
+ public static int[] shuffle(final int[] array) {
final int arrLen = array.length;
for (int i = 0; i < arrLen; i++) {
final int r = rand.nextInt(i + 1);
swap(array, i, r);
}
+ return array;
}
private static void swap(final int[] array, final int i1, final int i2) {
@@ -99,4 +107,24 @@ public final class Shuffle {
array[i2] = value;
}
+ /**
+ * Shuffle the given input Object array
+ * @param array input array
+ * @return the given array, shuffled.
+ */
+ public static Object[] shuffle(final Object[] array) {
+ final int arrLen = array.length;
+ for (int i = 0; i < arrLen; i++) {
+ final int r = rand.nextInt(i + 1);
+ swap(array, i, r);
+ }
+ return array;
+ }
+
+ private static void swap(final Object[] array, final int i1, final int i2) {
+ final Object value = array[i1];
+ array[i1] = array[i2];
+ array[i2] = value;
+ }
+
}
diff --git a/src/main/java/org/apache/datasketches/characterization/kll/KllDoublesSketchRankGaussianAccuracyProfile.java b/src/main/java/org/apache/datasketches/characterization/kll/KllDoublesSketchRankGaussianAccuracyProfile.java
index 6623a1d..280d452 100644
--- a/src/main/java/org/apache/datasketches/characterization/kll/KllDoublesSketchRankGaussianAccuracyProfile.java
+++ b/src/main/java/org/apache/datasketches/characterization/kll/KllDoublesSketchRankGaussianAccuracyProfile.java
@@ -22,11 +22,14 @@ package org.apache.datasketches.characterization.kll;
import static java.lang.Math.round;
import static org.apache.datasketches.GaussianRanks.GAUSSIANS_3SD;
import static org.apache.datasketches.common.Util.pwr2SeriesNext;
+import static org.apache.datasketches.quantilescommon.QuantileSearchCriteria.EXCLUSIVE;
+import static org.apache.datasketches.quantilescommon.QuantileSearchCriteria.INCLUSIVE;
import static org.apache.datasketches.quantilescommon.QuantilesUtil.evenlySpacedDoubles;
import org.apache.datasketches.Job;
import org.apache.datasketches.JobProfile;
import org.apache.datasketches.MonotonicPoints;
+import org.apache.datasketches.Properties;
import org.apache.datasketches.characterization.Shuffle;
import org.apache.datasketches.kll.KllDoublesSketch;
import org.apache.datasketches.memory.DefaultMemoryRequestServer;
@@ -34,6 +37,7 @@ import org.apache.datasketches.memory.WritableMemory;
import org.apache.datasketches.quantiles.DoublesSketch;
import org.apache.datasketches.quantiles.DoublesSketchBuilder;
import org.apache.datasketches.quantiles.UpdateDoublesSketch;
+import org.apache.datasketches.quantilescommon.QuantileSearchCriteria;
/**
* @author Lee Rhodes
@@ -41,6 +45,7 @@ import org.apache.datasketches.quantiles.UpdateDoublesSketch;
public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
private static final DefaultMemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
private Job job;
+ private Properties props;
//FROM PROPERTIES
//For computing the different stream lengths
@@ -57,6 +62,9 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
//Target sketch configuration & error analysis
private int k;
+ private QuantileSearchCriteria criteria;
+ private boolean useBulk;
+ private boolean direct;
//DERIVED globals
private KllDoublesSketch sk;
@@ -67,9 +75,9 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
//Specific to a streamLength
private double[] stream;
- private double[] trueValues;
+ private double[] trueNaturalRanks;
private int trueValueCorrection;
- private double[] corrTrueValues;
+ private double[] corrNaturalRanks;
private final String[] columnLabels =
{"nPP", "Value", "Rank", "-3SD","-2SD", "-1SD", "Med", "+1SD", "+2SD", "+3SD"};
@@ -83,6 +91,7 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
@Override
public void start(final Job job) {
this.job = job;
+ this.props = job.getProperties();
extractProperties();
configureCommon();
doJob();
@@ -97,25 +106,27 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
private void extractProperties() {
//stream length
- lgMin = Integer.parseInt(job.getProperties().mustGet("LgMin"));
- lgMax = Integer.parseInt(job.getProperties().mustGet("LgMax"));
- lgDelta = Integer.parseInt(job.getProperties().mustGet("LgDelta"));
- ppo = Integer.parseInt(job.getProperties().mustGet("PPO"));
+ lgMin = Integer.parseInt(props.mustGet("LgMin"));
+ lgMax = Integer.parseInt(props.mustGet("LgMax"));
+ lgDelta = Integer.parseInt(props.mustGet("LgDelta"));
+ ppo = Integer.parseInt(props.mustGet("PPO"));
//numTrials & error quantiles sketch config
- numTrials = 1 << Integer.parseInt(job.getProperties().mustGet("LgTrials"));
- errorSkLgK = Integer.parseInt(job.getProperties().mustGet("ErrSkLgK"));
+ numTrials = 1 << Integer.parseInt(props.mustGet("LgTrials"));
+ errorSkLgK = Integer.parseInt(props.mustGet("ErrSkLgK"));
//plotting & x-axis config
- numPlotPoints = Integer.parseInt(job.getProperties().mustGet("NumPlotPoints"));
+ numPlotPoints = Integer.parseInt(props.mustGet("NumPlotPoints"));
//Target sketch config
- k = Integer.parseInt(job.getProperties().mustGet("K"));
-
+ k = Integer.parseInt(props.mustGet("K"));
+ criteria = props.mustGet("criteria").equalsIgnoreCase("INCLUSIVE") ? INCLUSIVE : EXCLUSIVE;
+ useBulk = Boolean.parseBoolean(props.mustGet("useBulk"));
+ direct = Boolean.parseBoolean(props.mustGet("direct"));
}
void configureCommon() {
configureSketch();
- trueValues = new double[numPlotPoints];
- corrTrueValues = new double[numPlotPoints];
- trueValueCorrection = 1; //KLL is always LT
+ trueNaturalRanks = new double[numPlotPoints];
+ corrNaturalRanks = new double[numPlotPoints];
+ trueValueCorrection = (criteria == EXCLUSIVE) ? 1 : 0;
errQSkArr = new UpdateDoublesSketch[numPlotPoints];
//configure the error quantiles array
final DoublesSketchBuilder builder = DoublesSketch.builder().setK(1 << errorSkLgK);
@@ -129,10 +140,12 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
}
void configureSketch() {
- final WritableMemory wmem = WritableMemory.allocate(10000);
- sk = KllDoublesSketch.newDirectInstance(k, wmem, memReqSvr);
- //sk = KllDoublesSketch.newHeapInstance(k);
- //sk = new KllDoublesSketch(k);
+ if (direct) {
+ final WritableMemory wmem = WritableMemory.allocate(10000);
+ sk = KllDoublesSketch.newDirectInstance(k, wmem, memReqSvr);
+ } else {
+ sk = KllDoublesSketch.newHeapInstance(k);
+ }
}
private void doJob() {
@@ -168,37 +181,37 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
job.printfData(sFmt, (Object[])columnLabels);
//build the stream
- //the values themselves reflect their integer ranks starting with 1 (except for LT)
stream = new double[streamLength];
for (int sl = 1; sl <= streamLength; sl++) { stream[sl - 1] = sl; } //1 to SL
//compute the true values used at the plot points
final double start = 1.0;
final double end = streamLength;
- final double[] dblValues = evenlySpacedDoubles(start, end, numPlotPoints);
+ //approxDblNatRanks are designed to be their natural ranks starting with 1
+ final double[] approxDblNatRanks = evenlySpacedDoubles(start, end, numPlotPoints);
for (int pp = 0; pp < numPlotPoints; pp++) {
- trueValues[pp] = round(dblValues[pp]);
- corrTrueValues[pp] = trueValues[pp] - trueValueCorrection;
+ trueNaturalRanks[pp] = round(approxDblNatRanks[pp]); //force nearest integer
+ corrNaturalRanks[pp] = trueNaturalRanks[pp] - trueValueCorrection; //minus: exclusive = 1, inclusive = 0
}
//Do numTrials for all plot points
for (int t = 0; t < numTrials; t++) {
sk.reset();
- doTrial(sk, stream, trueValues, corrTrueValues, errQSkArr);
+ doTrial(sk, stream, trueNaturalRanks, corrNaturalRanks, errQSkArr);
}
//at this point each of the errQSkArr sketches has a distribution of error from numTrials
for (int pp = 0 ; pp < numPlotPoints; pp++) {
- final double v = trueValues[pp];
- final double tr = v / streamLength; //the true rank
+ final double trueNatRank = trueNaturalRanks[pp];
+ final double trueNormalizedRank = trueNatRank / streamLength; //create the true normalized rank
//for each of the numErrDistRanks distributions extract the sd quantiles
final double[] errQ = errQSkArr[pp].getQuantiles(gRanks); //get error values at the Gaussian ranks
//Plot the row. We ignore quantiles collected at 0 and 1.0.
final double relPP = (double)(pp + 1) / numPlotPoints;
- job.printfData(fFmt, relPP, v, tr,
+ job.printfData(fFmt, relPP, trueNatRank, trueNormalizedRank,
errQ[0], errQ[1], errQ[2], errQ[3], errQ[4], errQ[5], errQ[6]);
errQSkArr[pp].reset(); //reset the errQSkArr for next streamLength
}
@@ -211,25 +224,31 @@ public class KllDoublesSketchRankGaussianAccuracyProfile implements JobProfile {
* We capture the estimated ranks for all plotPoints and then update the errQSkArr with those
* error values.
* @param stream the source stream
- * @param trueValues the true integer ranks at each of the plot points
+ * @param trueNatRanks input quantiles to getRanks and also true natural ranks at each of the plot points
* @param errQSkArr the quantile error sketches for each plot point to be updated
*/
- static void doTrial(final KllDoublesSketch sk, final double[] stream, final double[] trueValues,
- final double[] corrTrueValues, final UpdateDoublesSketch[] errQSkArr) {
+ void doTrial(final KllDoublesSketch sk, final double[] stream, final double[] trueNatRanks,
+ final double[] corrNatRanks, final UpdateDoublesSketch[] errQSkArr) {
Shuffle.shuffle(stream);
final int sl = stream.length;
for (int i = 0; i < sl; i++) {
sk.update(stream[i]);
}
- final int numPP = trueValues.length;
+ final int numPP = trueNatRanks.length;
//get estimated ranks from sketch for all plot points
- final double[] estRanks = new double[numPP];
- for (int pp = 0; pp < numPP; pp++) {
- estRanks[pp] = sk.getRank(trueValues[pp]);
+ final double[] estRanks;// = new double[numPP];
+ if (useBulk) {
+ estRanks = sk.getRanks(trueNatRanks, criteria);
+ } else {
+ estRanks = new double[numPP];
+ for (int pp = 0; pp < numPP; pp++) {
+ estRanks[pp] = sk.getRank(trueNatRanks[pp], criteria);
+ }
}
+
//compute errors for each plotPoint
for (int pp = 0; pp < numPP; pp++) {
- final double errorAtPlotPoint = estRanks[pp] - corrTrueValues[pp] / sl;
+ final double errorAtPlotPoint = estRanks[pp] - corrNatRanks[pp] / sl;
errQSkArr[pp].update(errorAtPlotPoint); //update each of the errQArr sketches
}
}
diff --git a/src/main/java/org/apache/datasketches/characterization/kll/KllSketchAccuracyProfile.java b/src/main/java/org/apache/datasketches/characterization/kll/KllSketchAccuracyProfile.java
deleted file mode 100644
index 1d55893..0000000
--- a/src/main/java/org/apache/datasketches/characterization/kll/KllSketchAccuracyProfile.java
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * 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.characterization.kll;
-
-import static org.apache.datasketches.characterization.Shuffle.shuffle;
-import static org.apache.datasketches.kll.KllSketch.getNormalizedRankError;
-
-import java.util.Arrays;
-import java.util.Random;
-
-import org.apache.datasketches.characterization.quantiles.BaseQuantilesAccuracyProfile;
-import org.apache.datasketches.kll.KllDoublesSketch;
-import org.apache.datasketches.kll.KllFloatsSketch;
-import org.apache.datasketches.memory.DefaultMemoryRequestServer;
-import org.apache.datasketches.memory.WritableMemory;
-
-/**
- * This captures the maximum rank error over T trials.
- * The stream is shuffled prior to each trial.
- * This handles either floats or doubles.
- * The input distribution can be either uniform random or contiguous integral values.
- * The input is shuffled for each trial.
- *
- * @author Lee Rhodes
- *
- */
-public class KllSketchAccuracyProfile extends BaseQuantilesAccuracyProfile {
- public static Random random = new Random();
- private static final DefaultMemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
- private int k;
- private int streamLength;
- private float[] inputFloatValues;
- private float[] floatQueryValues;
- private double[] inputDoubleValues;
- private double[] doubleQueryValues;
- private int[] trueRanks;
- private boolean useBulk;
- private String dataType;
- private boolean direct = false; //heap is default
- private boolean useDouble = false; //useFloat is default
- private String distributionType;
- private boolean uniformRandom = false; //contiguous is default;
- private double epsilon;
- //add other types
-
- KllDoublesSketch dskUT = null;
- KllFloatsSketch fskUT = null;
-
- @Override //BaseQuantilesAccuracyProfile
- public void configure() {
- k = Integer.parseInt(props.mustGet("K"));
- epsilon = getNormalizedRankError(k, false);
- useBulk = Boolean.parseBoolean(props.mustGet("useBulk"));
- direct = Boolean.parseBoolean(props.mustGet("direct"));
- dataType = props.mustGet("dataType");
- if (dataType.equalsIgnoreCase("double")) { useDouble = true; }
- distributionType = props.mustGet("distributionType");
- if (distributionType.equalsIgnoreCase("uniformRandom")) { uniformRandom = true; }
- configureSketchUnderTest();
- }
-
- private void configureSketchUnderTest() {
- if (useDouble) {
- if (direct) {
- final WritableMemory dstMem = WritableMemory.allocate(10000);
- dskUT = KllDoublesSketch.newDirectInstance(k, dstMem, memReqSvr);
- } else { //heap
- dskUT = KllDoublesSketch.newHeapInstance(k);
- }
- } else { //useFloat
- if (direct) {
- final WritableMemory dstMem = WritableMemory.allocate(10000);
- fskUT = KllFloatsSketch.newDirectInstance(k, dstMem, memReqSvr);
- } else { //heap
- fskUT = KllFloatsSketch.newHeapInstance(k);
- }
- }
- }
-
- @Override //BaseQuantilesAccuracyProfile
- // called once per streamLength.
- //prepare input data that will be permuted and associated arrays
- public void prepareTrialSet(final int streamLength) {
- this.streamLength = streamLength;
-
- if (useDouble) {
- inputDoubleValues = new double[streamLength];
- doubleQueryValues = new double[streamLength];
- final int[] sortedArr = uniformRandom
- ? fillUniformRandomDoubles(inputDoubleValues)
- : fillContiguousDoubles(inputDoubleValues);
- trueRanks = getTrueRanksDoubles(sortedArr, doubleQueryValues);
- if (uniformRandom) { compressDoubleQueryValues(); }
- }
- else { //useFloats
- inputFloatValues = new float[streamLength];
- floatQueryValues = new float[streamLength];
- final int[] sortedArr = uniformRandom
- ? fillUniformRandomFloats(inputFloatValues)
- : fillContiguousFloats(inputFloatValues);
- trueRanks = getTrueRanksFloats(sortedArr, floatQueryValues);
- if (uniformRandom) { compressFloatQueryValuesAndTrueRanks(); }
- }
- }
-
- @Override
- public double getEpsilon() {
- return epsilon;
- }
-
- /**
- * For each trial:
- * <ul>
- * <li>Feed the sketch under test (skUT) a shuffled stream of length SL of "true" values.</li>
- * <li>Query the skUT for the estimated rank of each true value and capture the maximum
- * error of all the estimated ranks</li>
- * <li>Return this maximum error of this trial.</li>
- * </ul>
- */
- @Override //BaseQuantilesAccuracyProfile
- public double doTrial() {
- double worstNegRankError = 0;
- double worstPosRankError = 0;
-
- if (useDouble) {
- shuffle(inputDoubleValues);
- // reset then update sketch
- dskUT.reset();
- for (int i = 0; i < streamLength; i++) {
- dskUT.update(inputDoubleValues[i]);
- }
-
- // query sketch and gather results
- worstNegRankError = 0;
- worstPosRankError = 0;
- final int queryLen = trueRanks.length;
- if (useBulk) {
- final double[] estRanks = dskUT.getCDF(doubleQueryValues);
- for (int i = 0; i < queryLen; i++) {
- final double trueRank = (double) trueRanks[i] / streamLength;
- final double deltaRankErr = estRanks[i] - trueRank;
- if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
- else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
- }
- } else {
- for (int i = 0; i < queryLen; i++) {
- final double trueRank = (double) trueRanks[i] / streamLength;
- final double deltaRankErr = dskUT.getRank(i) - trueRank;
- if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
- else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
- }
- }
- }
-
- else { //use Float
- shuffle(inputFloatValues);
- // reset then update sketch
- fskUT.reset();
- for (int i = 0; i < inputFloatValues.length; i++) {
- fskUT.update(inputFloatValues[i]);
- }
-
- // query sketch and gather results
- worstNegRankError = 0;
- worstPosRankError = 0;
- final int qLen = trueRanks.length;
- if (useBulk) {
- final double[] estRanks = fskUT.getCDF(floatQueryValues);
- for (int i = 0; i < qLen; i++) {
- final double trueRank = (double) trueRanks[i] / streamLength;
- final double deltaRankErr = estRanks[i] - trueRank;
- if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
- else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
- }
- } else {
- for (int i = 0; i < qLen; i++) {
- final double trueRank = (double) trueRanks[i] / streamLength;
- final double deltaRankErr = fskUT.getRank(i) - trueRank;
- if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
- else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
- }
- }
- }
- return (worstPosRankError > -worstNegRankError) ? worstPosRankError : worstNegRankError;
- }
-
- //************************************************
-
- /**
- * Create a set of <i>n</i> uniform random integral values in the range [0, n).
- * They will not be sorted. There may be duplicates and, therefore, missing values.
- * @param inputDoubleValues empty double[] of size <i>n</i>.
- * @return sorted int[] of source integers
- */
- static final int[] fillUniformRandomDoubles(final double[] inputDoubleValues) {
- final int n = inputDoubleValues.length;
- final int[] valueSourceArr = new int[n];
- for (int i = 0; i < n; i++) {
- final int v = random.nextInt(n);
- valueSourceArr[i] = v;
- inputDoubleValues[i] = v;
- }
- final int[] sortedArr = valueSourceArr.clone();
- Arrays.sort(sortedArr);
- return sortedArr;
- }
-
- /**
- * Create a set of <i>n</i> contiguous integral values in the range [0, n)..
- * They may be sorted, but don't need to be. There are no duplicates and no gaps.
- * @param inputDoubleValues empty double[] of size <i>n</i>.
- * @return sorted int[] of source integers
- */
- static final int[] fillContiguousDoubles(final double[] inputDoubleValues) {
- final int n = inputDoubleValues.length;
- final int[] valueSourceArr = new int[n];
- for (int i = 0; i < n; i++) {
- valueSourceArr[i] = i;
- inputDoubleValues[i] = i;
- }
- final int[] sortedArr = valueSourceArr.clone();
- return sortedArr;
- }
-
- /**
- * @param sortedArr of source integers of size <i>n</i>.
- * @param doubleQueryValues empty double[] of size <i>n</i>.
- * @return int[] of true ranks aligned to doubleQueryValues
- */
- static final int[] getTrueRanksDoubles(final int[] sortedArr, final double[] doubleQueryValues) {
- final int n = doubleQueryValues.length;
- final int[] trueRanks = new int[n];
- int r;
- trueRanks[0] = r = 0;
- doubleQueryValues[0] = sortedArr[0];
- for (int i = 1; i < n; i++) {
- final int v;
- doubleQueryValues[i] = v = sortedArr[i];
- trueRanks[i] = (v == sortedArr[i - 1]) ? r : (r = i);
- }
- return trueRanks;
- }
-
- final void compressDoubleQueryValues() {
- //find num duplicates
- final int n = trueRanks.length;
- int dups = 0;
- final int[] tmpTrueRanks;
- final double[] tmpDoubleQueryValues;
- for (int i = 1; i < n; i++) {
- if (trueRanks[i] == trueRanks[i - 1]) { dups++; }
- }
- if (dups == 0) { return; }
- final int cLen = n - dups;
- tmpTrueRanks = new int[cLen];
- tmpDoubleQueryValues = new double[cLen];
- int j = 0;
- tmpTrueRanks[0] = trueRanks[0];
- tmpDoubleQueryValues[0] = doubleQueryValues[0];
- for (int i = 1; i < n; i++) {
- if (trueRanks[i] == trueRanks[i - 1]) { continue; }
- j++;
- tmpTrueRanks[j] = trueRanks[i];
- tmpDoubleQueryValues[j] = doubleQueryValues[i];
- }
- assert j + 1 == cLen : "(j + 1): " + (j + 1) + ", clen: " + cLen;
- trueRanks = tmpTrueRanks;
- doubleQueryValues = tmpDoubleQueryValues;
- }
-
- //************************************************
-
- /**
- * Create a set of <i>n</i> uniform random integral values in the range [0, n).
- * They will not be sorted. There may be duplicates and, therefore, missing values.
- * @param inputFloatValues empty float[] of size <i>n</i>.
- * @return sorted int[] of source integers
- */
- static final int[] fillUniformRandomFloats(final float[] inputFloatValues) {
- final int n = inputFloatValues.length;
- final int[] valueSourceArr = new int[n];
- for (int i = 0; i < n; i++) {
- final int v = random.nextInt(n);
- valueSourceArr[i] = v;
- inputFloatValues[i] = v;
- }
- final int[] sortedArr = valueSourceArr.clone();
- Arrays.sort(sortedArr);
- return sortedArr;
- }
-
- /**
- * Create a set of <i>n</i> contiguous integral values in the range [0, n).
- * They may be sorted, but don't need to be. There are no duplicates and no gaps.
- * @param inputFloatValues empty float[] of size <i>n</i>.
- * @return sorted int[] of source integers
- */
- static final int[] fillContiguousFloats(final float[] inputFloatValues) {
- final int n = inputFloatValues.length;
- final int[] valueSourceArr = new int[n];
- for (int i = 0; i < n; i++) {
- valueSourceArr[i] = i;
- inputFloatValues[i] = i;
- }
- final int[] sortedArr = valueSourceArr.clone();
- return sortedArr;
- }
-
- /**
- * @param sortedArr int[] of source integers of size <i>n</i>.
- * @param floatQueryValues empty float[] of size <i>n</i>.
- * @return int[] of true ranks aligned to floatQueryValues
- */
- static final int[] getTrueRanksFloats(final int[] sortedArr, final float[] floatQueryValues) {
- final int n = floatQueryValues.length;
- final int[] trueRanks = new int[n];
- int r;
- trueRanks[0] = r = 0;
- floatQueryValues[0] = sortedArr[0];
- for (int i = 1; i < n; i++) {
- final int v;
- floatQueryValues[i] = v = sortedArr[i];
- trueRanks[i] = (v == sortedArr[i - 1]) ? r : (r = i);
- }
- return trueRanks;
- }
-
- final void compressFloatQueryValuesAndTrueRanks() {
- //find num duplicates
- final int n = trueRanks.length;
- int dups = 0;
- final int[] tmpTrueRanks;
- final float[] tmpFloatQueryValues;
- for (int i = 1; i < n; i++) {
- if (trueRanks[i] == trueRanks[i - 1]) { dups++; }
- }
- if (dups == 0) { return; }
- final int cLen = n - dups;
- tmpTrueRanks = new int[cLen];
- tmpFloatQueryValues = new float[cLen];
- int j = 0;
- tmpTrueRanks[0] = trueRanks[0];
- tmpFloatQueryValues[0] = floatQueryValues[0];
- for (int i = 1; i < n; i++) {
- if (trueRanks[i] == trueRanks[i - 1]) { continue; }
- j++;
- tmpTrueRanks[j] = trueRanks[i];
- tmpFloatQueryValues[j] = floatQueryValues[i];
- }
- assert j + 1 == cLen : "(j + 1): " + (j + 1) + ", clen: " + cLen;
- trueRanks = tmpTrueRanks;
- floatQueryValues = tmpFloatQueryValues;
- }
-
-}
diff --git a/src/main/java/org/apache/datasketches/characterization/kll/KllWorstCaseSketchAccuracyProfile.java b/src/main/java/org/apache/datasketches/characterization/kll/KllWorstCaseSketchAccuracyProfile.java
new file mode 100644
index 0000000..99fe7f4
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/characterization/kll/KllWorstCaseSketchAccuracyProfile.java
@@ -0,0 +1,280 @@
+/*
+ * 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.characterization.kll;
+
+import static org.apache.datasketches.characterization.Shuffle.shuffle;
+import static org.apache.datasketches.kll.KllSketch.getNormalizedRankError;
+import static org.apache.datasketches.quantilescommon.QuantileSearchCriteria.EXCLUSIVE;
+import static org.apache.datasketches.quantilescommon.QuantileSearchCriteria.INCLUSIVE;
+
+import org.apache.datasketches.DoubleIntIntTriple;
+import org.apache.datasketches.FloatIntIntTriple;
+import org.apache.datasketches.SpecialRandom;
+import org.apache.datasketches.characterization.quantiles.BaseQuantilesAccuracyProfile;
+import org.apache.datasketches.kll.KllDoublesSketch;
+import org.apache.datasketches.kll.KllFloatsSketch;
+import org.apache.datasketches.kll.KllSketch;
+import org.apache.datasketches.kll.KllSketch.SketchType;
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.apache.datasketches.quantilescommon.QuantileSearchCriteria;
+
+/**
+ * This captures the maximum rank error over T trials.
+ * This handles either floats or doubles.
+ * The input distribution is integral values [1..n] (as either floats or doubles) that are shuffled for each trial.
+ * The input is shuffled for each trial.
+ *
+ * @author Lee Rhodes
+ *
+ */
+public class KllWorstCaseSketchAccuracyProfile extends BaseQuantilesAccuracyProfile {
+ private static final long EIGHT_PEBIBYTE = 1L << 53; //max integral value that a double can resolve
+ private static final int SIXTEEN_MEBIBYTE = 1 << 24; //max integral value that a float can resolve
+ private static SpecialRandom random = new SpecialRandom();
+ private static final DefaultMemoryRequestServer memReqSvr = new DefaultMemoryRequestServer();
+ private int k;
+ private int streamLength;
+ private FloatIntIntTriple[] inputFloatValues;
+ private float[] floatQueryValues;
+ private int[] floatRankValues;
+ private DoubleIntIntTriple[] inputDoubleValues;
+ private double[] doubleQueryValues;
+ private int[] doubleRankValues;
+ private boolean useBulk;
+
+ private boolean direct = false; //heap is default
+
+ private String distributionType;
+ private boolean contiguous = true; //contiguous is default;
+ private double epsilon;
+ private QuantileSearchCriteria criteria;
+ private SketchType sketchType;
+ //add other types
+
+ KllDoublesSketch dskUT = null;
+ KllFloatsSketch fskUT = null;
+
+ @Override //BaseQuantilesAccuracyProfile
+ public void configure() {
+ k = Integer.parseInt(props.mustGet("K"));
+ epsilon = getNormalizedRankError(k, false);
+ useBulk = Boolean.parseBoolean(props.mustGet("useBulk"));
+ direct = Boolean.parseBoolean(props.mustGet("direct"));
+ final String dataType = props.mustGet("dataType");
+ if ( dataType.equalsIgnoreCase("double")) { sketchType = SketchType.DOUBLES_SKETCH; }
+ else if (dataType.equalsIgnoreCase("float")) { sketchType = SketchType.FLOATS_SKETCH; }
+ else { sketchType = SketchType.ITEMS_SKETCH; }
+ distributionType = props.mustGet("distributionType");
+ contiguous = (distributionType.equalsIgnoreCase("contiguous")) ? true : false;
+ criteria = props.mustGet("criteria").equalsIgnoreCase("INCLUSIVE") ? INCLUSIVE : EXCLUSIVE;
+ configureSketchUnderTest();
+ }
+
+ private void configureSketchUnderTest() {
+ final int memBytes = KllSketch.getMaxSerializedSizeBytes(k, streamLength, sketchType, true);
+ if (sketchType == SketchType.DOUBLES_SKETCH) {
+ if (direct) {
+ final WritableMemory dstMem = WritableMemory.allocate(memBytes);
+ dskUT = KllDoublesSketch.newDirectInstance(k, dstMem, memReqSvr);
+ } else { //heap
+ dskUT = KllDoublesSketch.newHeapInstance(k);
+ }
+ } else { //useFloat
+ if (direct) {
+ final WritableMemory dstMem = WritableMemory.allocate(memBytes);
+ fskUT = KllFloatsSketch.newDirectInstance(k, dstMem, memReqSvr);
+ } else { //heap
+ fskUT = KllFloatsSketch.newHeapInstance(k);
+ }
+ } // else item
+ }
+
+ @Override //BaseQuantilesAccuracyProfile
+ // called once per streamLength.
+ //prepare input data that will be permuted and associated arrays
+ public void prepareTrialSet(final int streamLength) {
+ this.streamLength = streamLength;
+
+ if (sketchType == SketchType.DOUBLES_SKETCH) {
+ inputDoubleValues = fillDoubleArrays(streamLength, contiguous);
+ }
+ else { //useFloats
+ inputFloatValues = fillFloatArrays(streamLength, contiguous);
+ }
+ }
+
+ @Override
+ public double getEpsilon() {
+ return epsilon;
+ }
+
+ /**
+ * For each trial:
+ * <ul>
+ * <li>Feed the sketch under test (skUT) a shuffled stream of length SL of "true" values.</li>
+ * <li>Query the skUT for the estimated rank of each true value and capture the maximum
+ * error of all the estimated ranks</li>
+ * <li>Return this maximum error of this trial.</li>
+ * </ul>
+ */
+ @Override //BaseQuantilesAccuracyProfile
+ public double doTrial() {
+ double worstNegRankError = 0;
+ double worstPosRankError = 0;
+
+ //DOUBLES SKETCH
+ if (sketchType == SketchType.DOUBLES_SKETCH) {
+ shuffle(inputDoubleValues);
+ doubleQueryValues = DoubleIntIntTriple.getValueArray(inputDoubleValues);
+ doubleRankValues = DoubleIntIntTriple.getRankArray(inputDoubleValues);
+ // reset then update sketch
+ dskUT.reset();
+ for (int i = 0; i < streamLength; i++) {
+ dskUT.update(inputDoubleValues[i].value);
+ }
+
+ // query sketch and gather results
+ worstNegRankError = 0;
+ worstPosRankError = 0;
+ final int queryLen = inputDoubleValues.length;
+ final int one = (criteria == EXCLUSIVE) ? 1 : 0;
+ if (useBulk) {
+ final double[] estRanks = dskUT.getRanks(doubleQueryValues);
+ for (int i = 0; i < queryLen; i++) {
+ final double trueNormRank = (double) (doubleRankValues[i] - one) / streamLength;
+ final double deltaRankErr = estRanks[i] - trueNormRank;
+ if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
+ else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
+ }
+ } else {
+ for (int i = 0; i < queryLen; i++) {
+ final double estRank = dskUT.getRank(doubleRankValues[i]);
+ final double trueNormRank = (double) (doubleRankValues[i] - one) / streamLength;
+ final double deltaRankErr = estRank - trueNormRank;
+ if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
+ else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
+ }
+ }
+ }
+ //FLOATS SKETCH
+ else {
+ shuffle(inputFloatValues);
+ floatQueryValues = FloatIntIntTriple.getValueArray(inputFloatValues);
+ floatRankValues = FloatIntIntTriple.getRankArray(inputFloatValues);
+ // reset then update sketch
+ fskUT.reset();
+ for (int i = 0; i < inputFloatValues.length; i++) {
+ fskUT.update(inputFloatValues[i].value);
+ }
+
+ // query sketch and gather results
+ worstNegRankError = 0;
+ worstPosRankError = 0;
+ final int queryLen = inputFloatValues.length;
+ final int one = (criteria == EXCLUSIVE) ? 1 : 0;
+ if (useBulk) {
+ final double[] estRanks = fskUT.getRanks(floatQueryValues);
+ for (int i = 0; i < queryLen; i++) {
+ final double normRank = (double) (floatRankValues[i] - one) / streamLength;
+ final double deltaRankErr = estRanks[i] - normRank;
+ if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
+ else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
+ }
+ } else {
+ for (int i = 0; i < queryLen; i++) {
+ final double estRank = fskUT.getRank(floatRankValues[i]);
+ final double normRank = (double) (floatRankValues[i] - one) / streamLength;
+ final double deltaRankErr = estRank - normRank;
+ if (deltaRankErr < 0) { worstNegRankError = Math.min(worstNegRankError, deltaRankErr); }
+ else { worstPosRankError = Math.max(worstPosRankError, deltaRankErr); }
+ }
+ }
+ }
+ return (worstPosRankError > -worstNegRankError) ? worstPosRankError : worstNegRankError;
+ }
+
+ //************************************************
+
+ /**
+ * Create a DoubleIntIntTriple of <i>n</i> integral double values with associated index and rank
+ * @param n the given size of the returned filled array.
+ * @param contiguous if true, the values will be from the range [1, n].
+ * Otherwise, the values will be uniform random values from the range [1, 2^53] when sorted by index.
+ * @return DoubleIntIntTriple array.
+ */
+ static final DoubleIntIntTriple[] fillDoubleArrays(final int n, final boolean contiguous) {
+ final DoubleIntIntTriple[] array = new DoubleIntIntTriple[n];
+
+ if (contiguous) {
+ for (int i = 0, r = 1; i < n; i++, r++) {
+ final DoubleIntIntTriple item = array[i] = new DoubleIntIntTriple();
+ item.index = i;
+ item.value = r;
+ item.rank = r;
+ }
+ } else { //random
+ for (int i = 0; i < n; i++) {
+ final DoubleIntIntTriple item = array[i] = new DoubleIntIntTriple();
+ item.index = i;
+ item.value = random.nextLong(EIGHT_PEBIBYTE) + 1L;
+ }
+ DoubleIntIntTriple.sortByValue(array);
+ for (int i = 0, r = 1; i < n; i++, r++) {
+ array[i].rank = r;
+ }
+ DoubleIntIntTriple.sortByIndex(array);
+ }
+ return array;
+ }
+
+ /**
+ * Create a FloatIntIntTriple of <i>n</i> integral float values with associated index and rank
+ * @param n the given size of the returned filled array.
+ * @param contiguous if true, the values will be from the range [1, n].
+ * Otherwise, the values will be uniform random values from the range [1, 2^24] when the array is sorted by index.
+ * @return FloatIntIntTriple array sorted by index.
+ */
+ static final FloatIntIntTriple[] fillFloatArrays(final int n, final boolean contiguous) {
+ final FloatIntIntTriple[] array = new FloatIntIntTriple[n];
+
+ if (contiguous) {
+ for (int i = 0, r = 1; i < n; i++, r++) {
+ final FloatIntIntTriple item = array[i] = new FloatIntIntTriple();
+ item.index = i;
+ item.value = r;
+ item.rank = r;
+ }
+ } else { //random
+ for (int i = 0; i < n; i++) {
+ final FloatIntIntTriple item = array[i] = new FloatIntIntTriple();
+ item.index = i;
+ item.value = random.nextInt(SIXTEEN_MEBIBYTE) + 1;
+ }
+ FloatIntIntTriple.sortByValue(array);
+ for (int i = 0, r = 1; i < n; i++, r++) {
+ array[i].rank = r;
+ }
+ FloatIntIntTriple.sortByIndex(array);
+ }
+ return array;
+ }
+
+}
diff --git a/src/main/java/org/apache/datasketches/characterization/uniquecount/BaseAccuracyProfile.java b/src/main/java/org/apache/datasketches/characterization/uniquecount/BaseAccuracyProfile.java
index ed9cca5..7cb62fe 100644
--- a/src/main/java/org/apache/datasketches/characterization/uniquecount/BaseAccuracyProfile.java
+++ b/src/main/java/org/apache/datasketches/characterization/uniquecount/BaseAccuracyProfile.java
@@ -282,7 +282,7 @@ public abstract class BaseAccuracyProfile implements JobProfile {
}
/**
- * This removes possible duplicate values in the given splitpoints array.
+ * This removes possible duplicate values in the given splitPoints array.
* @param splitPoints the given splitPoints
* @return the reduced array of splitPoints
*/
diff --git a/src/main/resources/kll/KllDoublesSketchRankGaussianAccuracyJob.conf b/src/main/resources/kll/KllDoublesSketchRankGaussianAccuracyJob.conf
index 30fba1d..84c397b 100644
--- a/src/main/resources/kll/KllDoublesSketchRankGaussianAccuracyJob.conf
+++ b/src/main/resources/kll/KllDoublesSketchRankGaussianAccuracyJob.conf
@@ -15,27 +15,33 @@
# specific language governing permissions and limitations
# under the License.
-JobProfile=org.apache.datasketches.characterization.quantiles.KllDoublesSketchRankGaussianAccuracyProfile
+JobProfile=org.apache.datasketches.characterization.kll.KllDoublesSketchRankGaussianAccuracyProfile
-# Trials config (indep of sketch)
+# Trials config (independent of sketch)
## Stream lengths
LgMin=11 # The starting stream length
-LgMax=11 # How high the stream length goes
+LgMax=11 # The ending stream length
LgDelta=3 # If > 0, this is the lg Increment
PPO=8 # The horizontal x-resolution of trials points
-LgTrials=14 # lgTrials at every stream length
+LgTrials=18 # lgTrials at every stream length
ErrSkLgK=12 # parameter for the rank error distribution sketch
+## Distribution type
+distribution=monotonic #monotonic vs flat
+
+
# Plotting
NumPlotPoints=100 # number of plot points along the x-axis
# Specific sketch config
K=100 # sketch size and accuracy parameter
-
+criteria=INCLUSIVE #INCLUSIVE or EXCLUSIVE
+useBulk=false # query ranks using getRanks(arr) instead of separate getRank() for each value
+direct=false # vs heap
# Date-Time Profile
-TimeZone=PDT
-TimeZoneOffset=-25200000 # offset in millisec: PST (UTC-8) = -28_800_000 PDT (UTC-7) = -25_200_000
+TimeZone=PST
+TimeZoneOffset=-28800000 # offset in millisec: PST (UTC-8) = -28800000 PDT (UTC-7) = -25200000
FileNameDateFormat=yyyyMMdd'_'HHmmssz
ReadableDateFormat=yyyy/MM/dd HH:mm:ss
\ No newline at end of file
diff --git a/src/main/resources/kll/KllSketchAccuracyJob.conf b/src/main/resources/kll/KllWorstCaseSketchAccuracyJob.conf
similarity index 73%
rename from src/main/resources/kll/KllSketchAccuracyJob.conf
rename to src/main/resources/kll/KllWorstCaseSketchAccuracyJob.conf
index 7724ab7..87c2136 100644
--- a/src/main/resources/kll/KllSketchAccuracyJob.conf
+++ b/src/main/resources/kll/KllWorstCaseSketchAccuracyJob.conf
@@ -15,21 +15,23 @@
# specific language governing permissions and limitations
# under the License.
-JobProfile=org.apache.datasketches.characterization.kll.KllSketchAccuracyProfile
+JobProfile=org.apache.datasketches.characterization.kll.KllWorstCaseSketchAccuracyProfile
# Used by BaseQuantilesAccuracyProfile.doTrials()
lgMin=0 # The starting stream length
lgMax=20 # How high the stream length goes
PPO=8 # The horizontal x-resolution of trials points
-trials=5000 # Trials at every stream length
+trials=10000 # Trials at every stream length
errLgK=14 # parameter for the rank error distribution sketch
+criteria=INCLUSIVE # or EXCLUSIVE
# Used by KllSketchAccuracyProfile.configure(Properties)
K=200 # sketch size and accuracy parameter
-useBulk=true # query ranks using getCDF() instead of separate getRank() for each value
+useBulk=false # query ranks using getRanks(arr) instead of separate getRank() for each value
direct=false # vs heap
-dataType=float # vs double
-distributionType=uniformRandom #uniformRandom vs contiguous
+dataType=float # float vs double vs item
+distributionType=contiguous #contiguous [1..n] vs uniform random on domain [1..Z]
+# Where if double, Z = 8 * 2^53, if float Z = 16 * 2^24
#not used
errPct=99 # percentile of the rank error distribution to report
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org