From 38fc9123dc5d0d4d0eb9868e96b79907dabd0e93 Mon Sep 17 00:00:00 2001 From: Chip Kent <5250374+chipkent@users.noreply.github.com> Date: Tue, 19 Mar 2024 11:49:36 -0600 Subject: [PATCH] Provide query library functions for computing differences and sort order (#5151) * New query library function to compute the difference in array values. * New query library functions to return the sort order of arrays. --- engine/function/src/templates/Numeric.ftl | 122 +++++++++ engine/function/src/templates/Sort.ftl | 236 +++++++++++++++++- engine/function/src/templates/TestNumeric.ftl | 121 +++++++++ engine/function/src/templates/TestSort.ftl | 75 +++++- .../deephaven/libs/GroovyStaticImports.java | 222 ++++++++++++++++ 5 files changed, 766 insertions(+), 10 deletions(-) diff --git a/engine/function/src/templates/Numeric.ftl b/engine/function/src/templates/Numeric.ftl index 7703309466f..5db8a41b0cf 100644 --- a/engine/function/src/templates/Numeric.ftl +++ b/engine/function/src/templates/Numeric.ftl @@ -1591,6 +1591,73 @@ public class Numeric { return product(new ${pt.vectorDirect}(values)); } + /** + * Returns the differences between elements in the input vector separated by a stride. + * A stride of k returns v(i)=e(i+k)-e(i), where v(i) is the ith computed value, and e(i) is the ith input value. + * A stride of -k returns v(i)=e(i-k)-e(i), where v(i) is the ith computed value, and e(i) is the ith input value. + * The result has the same length as the input vector. + * Differences off the end of the input vector are the null value. + * + * @param stride number of elements separating the elements to be differenced. + * @param values input vector. + * @return a vector containing the differences between elements. + */ + public static ${pt.primitive}[] diff(int stride, ${pt.boxed}[] values) { + return diff(stride, unbox(values)); + } + + /** + * Returns the differences between elements in the input vector separated by a stride. + * A stride of k returns v(i)=e(i+k)-e(i), where v(i) is the ith computed value e(i) is the ith input value. + * A stride of -k returns v(i)=e(i-k)-e(i), where v(i) is the ith computed value e(i) is the ith input value. + * The result has the same length as the input vector. + * Differences off the end of the input vector are the null value. + * + * @param stride number of elements separating the elements to be differenced. + * @param values input vector. + * @return a vector containing the differences between elements. + */ + public static ${pt.primitive}[] diff(int stride, ${pt.primitive}... values) { + return diff(stride, new ${pt.vectorDirect}(values)); + } + + /** + * Returns the differences between elements in the input vector separated by a stride. + * A stride of k returns v(i)=e(i+k)-e(i), where v(i) is the ith computed value e(i) is the ith input value. + * A stride of -k returns v(i)=e(i-k)-e(i), where v(i) is the ith computed value e(i) is the ith input value. + * The result has the same length as the input vector. + * Differences off the end of the input vector are the null value. + * + * @param stride number of elements separating the elements to be differenced. + * @param values input vector. + * @return a vector containing the differences between elements. + */ + public static ${pt.primitive}[] diff(int stride, ${pt.vector} values) { + if (values == null) { + return null; + } + + if (values.isEmpty()) { + return new ${pt.primitive}[0]; + } + + final int n = values.intSize("diff"); + ${pt.primitive}[] result = new ${pt.primitive}[n]; + + for (int i = 0; i < n; i++) { + ${pt.primitive} v1 = values.get(i); + ${pt.primitive} v2 = values.get(i + stride); + + if (isNull(v1) || isNull(v2)) { + result[i] = ${pt.null}; + } else { + result[i] = (${pt.primitive})(v2 - v1); + } + } + + return result; + } + /** * Returns the cumulative minimum. Null values are excluded. * @@ -2791,6 +2858,61 @@ public class Numeric { + + /** + * Compares two specified values. Deephaven null values are less than normal numbers which are less than NaN values. + * + * @param v1 the first value to compare. + * @param v2 the second value to compare. + * @returns the value 0 if v1 is numerically equal to v2; a value of less than 0 if v1 is numerically less than v2; + * and a value greater than 0 if v1 is numerically greater than v2. + * Deephaven null values are less than normal numbers which are less than NaN values. + * Unlike standard Java, Deephaven treats NaN values as ordered. In particular two NaN values will compare + * equal to each other, and a NaN value will compare greater than any other value. + */ + static public int compare(${pt.primitive} v1, ${pt.primitive} v2) { + final boolean isNull1 = isNull(v1); + final boolean isNull2 = isNull(v2); + + if (isNull1 && isNull2) { + return 0; + } else if (isNull1) { + return -1; + } else if (isNull2) { + return 1; + } + + final boolean isNaN1 = isNaN(v1); + final boolean isNaN2 = isNaN(v2); + + // NaN is considered the greatest + if (isNaN1 && isNaN2) { + return 0; + } else if (isNaN1) { + return 1; + } else if (isNaN2) { + return -1; + } + + return ${pt.boxed}.compare(v1, v2); + } + + + /** + * Compares two specified values. Deephaven null values are less than normal numbers which are less than NaN values. + * + * @param v1 the first value to compare. + * @param v2 the second value to compare. + * @returns the value 0 if v1 is numerically equal to v2; a value of less than 0 if v1 is numerically less than v2; + * and a value greater than 0 if v1 is numerically greater than v2. + * Deephaven null values are less than normal numbers which are less than NaN values. + * Unlike standard Java, Deephaven treats NaN values as ordered. In particular two NaN values will compare + * equal to each other, and a NaN value will compare greater than any other value. + */ + static public int compare(${pt.boxed} v1, ${pt.boxed} v2) { + return compare(v1 == null ? ${pt.null} : v1, v2 == null ? ${pt.null} : v2); + } + } diff --git a/engine/function/src/templates/Sort.ftl b/engine/function/src/templates/Sort.ftl index 9e8edc32749..4f6ac9f7ed9 100644 --- a/engine/function/src/templates/Sort.ftl +++ b/engine/function/src/templates/Sort.ftl @@ -10,9 +10,11 @@ import org.apache.commons.lang3.ArrayUtils; import java.util.Arrays; import java.util.Comparator; +import java.util.stream.IntStream; import static io.deephaven.util.QueryConstants.*; import static io.deephaven.function.Basic.isNull; +import static io.deephaven.function.Numeric.compare; /** * Functions for sorting primitive types. @@ -84,6 +86,64 @@ public class Sort { return sortObj(values, new NullNaNAwareComparator<>()); } + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @param comparator value comparator. + * @return sorted indices. + */ + static public > int[] rankObj(final ObjectVector values, final Comparator comparator) { + if (values == null) { + return null; + } + if (values.isEmpty()) { + return new int[0]; + } + + return IntStream.range(0, values.intSize("rank")) + .boxed().sorted((i, j) -> comparator.compare(values.get(i), values.get(j))) + .mapToInt(ele -> ele).toArray(); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @return sorted indices. + */ + static public > int[] rankObj(final ObjectVector values) { + return rankObj(values, new NullNaNAwareComparator<>()); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @param comparator value comparator. + * @return sorted indices. + */ + static public > int[] rankObj(final T[] values, final Comparator comparator) { + if (values == null) { + return null; + } + + return IntStream.range(0, values.length) + .boxed().sorted((i, j) -> comparator.compare(values[i], values[j])) + .mapToInt(ele -> ele).toArray(); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @return sorted indices. + */ + @SafeVarargs + static public > int[] rankObj(final T... values) { + return rankObj(values, new NullNaNAwareComparator<>()); + } + /** * Returns sorted values from largest to smallest. * @@ -141,6 +201,63 @@ public class Sort { return sortDescendingObj(values, new NullNaNAwareComparator<>()); } + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @param comparator value comparator. + * @return sorted indices. + */ + static public > int[] rankDescendingObj(final ObjectVector values, final Comparator comparator) { + if (values == null) { + return null; + } + + if (values.isEmpty()) { + return new int[0]; + } + + return IntStream.range(0, values.intSize("rank")) + .boxed().sorted((i, j) -> comparator.compare(values.get(j), values.get(i))) + .mapToInt(ele -> ele).toArray(); + } + + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @return sorted indices. + */ + static public > int[] rankDescendingObj(final ObjectVector values) { + return rankDescendingObj(values, new NullNaNAwareComparator<>()); + } + + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @param comparator value comparator. + * @return sorted indices. + */ + static public > int[] rankDescendingObj(final T[] values, final Comparator comparator) { + if (values == null) { + return null; + } + + return rankDescendingObj(new ObjectVectorDirect<>(values), comparator); + } + + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @return sorted indices. + */ + @SafeVarargs + static public > int[] rankDescendingObj(final T... values) { + return rankDescendingObj(values, new NullNaNAwareComparator<>()); + } + <#list primitiveTypes as pt> <#if pt.valueType.isNumber > @@ -162,9 +279,9 @@ public class Sort { return values.toArray(); } - final ${pt.primitive}[] vs = values.copyToArray(); - Arrays.sort(vs); - return vs; + final ${pt.boxed}[] vb = ArrayUtils.toObject(values.toArray()); + Arrays.sort(vb, Numeric::compare); + return ArrayUtils.toPrimitive(vb); } /** @@ -196,13 +313,66 @@ public class Sort { return new ${pt.primitive}[]{}; } + final ${pt.boxed}[] vb = values.clone(); + Arrays.sort(vb, Numeric::compare); + return ArrayUtils.toPrimitive(vb); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rank(final ${pt.vector} values) { + if (values == null) { + return null; + } + + if (values.isEmpty()) { + return new int[0]; + } + + return IntStream.range(0, values.intSize("rank")) + .boxed().sorted((i, j) -> compare(values.get(i), values.get(j))) + .mapToInt(ele -> ele).toArray(); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rank(final ${pt.primitive}... values) { + if (values == null) { + return null; + } + + return rank(new ${pt.vectorDirect}(values)); + } + + /** + * Returns the indices of values sorted from smallest to largest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rank(final ${pt.boxed}[] values) { + if (values == null) { + return null; + } + + if (values.length == 0) { + return new int[0]; + } + final ${pt.primitive}[] vs = new ${pt.primitive}[values.length]; for (int i = 0; i < values.length; i++) { vs[i] = isNull(values[i]) ? ${pt.null} : values[i]; } - Arrays.sort(vs); - return vs; + return rank(new ${pt.vectorDirect}(vs)); } /** @@ -220,10 +390,8 @@ public class Sort { return values.toArray(); } - final ${pt.primitive}[] vs = values.copyToArray(); - Arrays.sort(vs); + final ${pt.primitive}[] vs = sort(values); ArrayUtils.reverse(vs); - return vs; } @@ -257,6 +425,58 @@ public class Sort { return result; } + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rankDescending(final ${pt.vector} values) { + if (values == null) { + return null; + } + + if (values.isEmpty()) { + return new int[0]; + } + + return IntStream.range(0, values.intSize("rank")) + .boxed().sorted((i, j) -> compare(values.get(j), values.get(i))) + .mapToInt(ele -> ele).toArray(); + } + + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rankDescending(final ${pt.primitive}... values) { + if (values == null) { + return null; + } + + return rankDescending(new ${pt.vectorDirect}(values)); + } + + /** + * Returns the indices of values sorted from largest to smallest. + * + * @param values values. + * @return sorted indices. + */ + public static int[] rankDescending(final ${pt.boxed}[] values) { + if (values == null) { + return null; + } + + final ${pt.primitive}[] vs = new ${pt.primitive}[values.length]; + for (int i = 0; i < values.length; i++) { + vs[i] = isNull(values[i]) ? ${pt.null} : values[i]; + } + + return rankDescending(new ${pt.vectorDirect}(vs)); + } diff --git a/engine/function/src/templates/TestNumeric.ftl b/engine/function/src/templates/TestNumeric.ftl index 8e9e573d1c4..6918a9bbd77 100644 --- a/engine/function/src/templates/TestNumeric.ftl +++ b/engine/function/src/templates/TestNumeric.ftl @@ -680,6 +680,23 @@ public class TestNumeric extends BaseArrayTestCase { // } // } + public void test${pt.boxed}Diff() { + assertEquals(new ${pt.primitive}[]{1, 2, 4, 8, ${pt.null}}, diff(1, new ${pt.primitive}[]{1, 2, 4, 8, 16})); + assertEquals(new ${pt.primitive}[]{3, 6, 12, ${pt.null}, ${pt.null}}, diff(2, new ${pt.primitive}[]{1, 2, 4, 8, 16})); + assertEquals(new ${pt.primitive}[]{${pt.null}, -1, -2, -4, -8}, diff(-1, new ${pt.primitive}[]{1, 2, 4, 8, 16})); + assertEquals(new ${pt.primitive}[]{${pt.null}, ${pt.null}, -3, -6, -12}, diff(-2, new ${pt.primitive}[]{1, 2, 4, 8, 16})); + + assertEquals(new ${pt.primitive}[]{1, 2, 4, 8, ${pt.null}}, diff(1, new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})2, (${pt.primitive})4, (${pt.primitive})8, (${pt.primitive})16})); + assertEquals(new ${pt.primitive}[]{3, 6, 12, ${pt.null}, ${pt.null}}, diff(2, new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})2, (${pt.primitive})4, (${pt.primitive})8, (${pt.primitive})16})); + assertEquals(new ${pt.primitive}[]{${pt.null}, -1, -2, -4, -8}, diff(-1, new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})2, (${pt.primitive})4, (${pt.primitive})8, (${pt.primitive})16})); + assertEquals(new ${pt.primitive}[]{${pt.null}, ${pt.null}, -3, -6, -12}, diff(-2, new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})2, (${pt.primitive})4, (${pt.primitive})8, (${pt.primitive})16})); + + assertEquals(new ${pt.primitive}[]{1, 2, 4, 8, ${pt.null}}, diff(1, new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 4, 8, 16}))); + assertEquals(new ${pt.primitive}[]{3, 6, 12, ${pt.null}, ${pt.null}}, diff(2, new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 4, 8, 16}))); + assertEquals(new ${pt.primitive}[]{${pt.null}, -1, -2, -4, -8}, diff(-1, new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 4, 8, 16}))); + assertEquals(new ${pt.primitive}[]{${pt.null}, ${pt.null}, -3, -6, -12}, diff(-2, new ${pt.vectorDirect}(new ${pt.primitive}[]{1, 2, 4, 8, 16}))); + } + public void test${pt.boxed}CumMinArray() { assertEquals(new ${pt.primitive}[]{1, 1, 1, 1, 1}, cummin(new ${pt.primitive}[]{1, 2, 3, 4, 5})); assertEquals(new ${pt.primitive}[]{5, 4, 3, 2, 1}, cummin(new ${pt.primitive}[]{5, 4, 3, 2, 1})); @@ -1284,6 +1301,68 @@ public class TestNumeric extends BaseArrayTestCase { assertEquals(new ${pt.primitive}[]{(${pt.primitive}) 3, (${pt.primitive}) 7, (${pt.primitive}) 11}, replaceIfNonFinite(new ${pt.primitive}[]{(${pt.primitive}) 3, ${pt.null}, (${pt.primitive}) 11}, (${pt.primitive}) 7)); } + public void test${pt.boxed}Compare() { + final ${pt.primitive} v1 = (${pt.primitive})1.4; + final ${pt.primitive} v2 = (${pt.primitive})2.3; + final ${pt.primitive} v3 = ${pt.null}; + final ${pt.primitive} v4 = ${pt.null}; + final ${pt.primitive} v5 = ${pt.boxed}.NaN; + final ${pt.primitive} v6 = ${pt.boxed}.NaN; + + assertEquals(0, compare(v1, v1)); + assertEquals(0, compare(v2, v2)); + assertEquals(0, compare(v3, v3)); + assertEquals(0, compare(v4, v4)); + assertEquals(0, compare(v5, v5)); + assertEquals(0, compare(v6, v6)); + + assertEquals(0, compare(v3, v4)); + assertEquals(0, compare(v4, v3)); + + assertEquals(0, compare(v5, v6)); + assertEquals(0, compare(v6, v5)); + + assertEquals(-1, compare(v1, v2)); + assertEquals(1, compare(v2, v1)); + + assertEquals(1, compare(v1, v3)); + assertEquals(-1, compare(v3, v1)); + + assertEquals(-1, compare(v1, v5)); + assertEquals(1, compare(v5, v1)); + } + + public void test${pt.boxed}CompareBoxed() { + final ${pt.boxed} v1 = (${pt.primitive})1.4; + final ${pt.boxed} v2 = (${pt.primitive})2.3; + final ${pt.boxed} v3 = null; + final ${pt.boxed} v4 = null; + final ${pt.boxed} v5 = ${pt.boxed}.NaN; + final ${pt.boxed} v6 = ${pt.boxed}.NaN; + + assertEquals(0, compare(v1, v1)); + assertEquals(0, compare(v2, v2)); + assertEquals(0, compare(v3, v3)); + assertEquals(0, compare(v4, v4)); + assertEquals(0, compare(v5, v5)); + assertEquals(0, compare(v6, v6)); + + assertEquals(0, compare(v3, v4)); + assertEquals(0, compare(v4, v3)); + + assertEquals(0, compare(v5, v6)); + assertEquals(0, compare(v6, v5)); + + assertEquals(-1, compare(v1, v2)); + assertEquals(1, compare(v2, v1)); + + assertEquals(1, compare(v1, v3)); + assertEquals(-1, compare(v3, v1)); + + assertEquals(-1, compare(v1, v5)); + assertEquals(1, compare(v5, v1)); + } + <#else> public void test${pt.boxed}IsNan(){ @@ -1322,6 +1401,48 @@ public class TestNumeric extends BaseArrayTestCase { assertTrue(containsNonFinite(new ${pt.boxed}[]{(${pt.primitive})0, (${pt.primitive})0, ${pt.null}})); } + public void test${pt.boxed}Compare() { + final ${pt.primitive} v1 = (${pt.primitive})1; + final ${pt.primitive} v2 = (${pt.primitive})2; + final ${pt.primitive} v3 = ${pt.null}; + final ${pt.primitive} v4 = ${pt.null}; + + assertEquals(0, compare(v1, v1)); + assertEquals(0, compare(v2, v2)); + assertEquals(0, compare(v3, v3)); + assertEquals(0, compare(v4, v4)); + + assertEquals(0, compare(v3, v4)); + assertEquals(0, compare(v4, v3)); + + assertEquals(-1, compare(v1, v2)); + assertEquals(1, compare(v2, v1)); + + assertEquals(1, compare(v1, v3)); + assertEquals(-1, compare(v3, v1)); + } + + public void test${pt.boxed}CompareBoxed() { + final ${pt.boxed} v1 = (${pt.primitive})1; + final ${pt.boxed} v2 = (${pt.primitive})2; + final ${pt.boxed} v3 = null; + final ${pt.boxed} v4 = null; + + assertEquals(0, compare(v1, v1)); + assertEquals(0, compare(v2, v2)); + assertEquals(0, compare(v3, v3)); + assertEquals(0, compare(v4, v4)); + + assertEquals(0, compare(v3, v4)); + assertEquals(0, compare(v4, v3)); + + assertEquals(-1, compare(v1, v2)); + assertEquals(1, compare(v2, v1)); + + assertEquals(1, compare(v1, v3)); + assertEquals(-1, compare(v3, v1)); + } + diff --git a/engine/function/src/templates/TestSort.ftl b/engine/function/src/templates/TestSort.ftl index 980b41c6035..ab3e3dd2066 100644 --- a/engine/function/src/templates/TestSort.ftl +++ b/engine/function/src/templates/TestSort.ftl @@ -117,6 +117,25 @@ public class TestSort extends BaseArrayTestCase { assertEquals(new ${pt.primitive}[]{}, sort(new ${pt.boxed}[]{})); } + public void test${pt.boxed}Rank() { + final ${pt.primitive}[] ${pt.primitive}s = new ${pt.primitive}[]{1, -5, -2, -2, 96, 0, 12, ${pt.null}, ${pt.null}}; + final ${pt.boxed}[] ${pt.boxed}s = new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})-5, (${pt.primitive})-2, (${pt.primitive})-2, (${pt.primitive})96, (${pt.primitive})0, (${pt.primitive})12, (${pt.primitive})${pt.null}, (${pt.primitive})${pt.null}}; + + final int[] sort = rank(new ${pt.vectorDirect}(${pt.primitive}s)); + final int[] expected = new int[]{7, 8, 1, 2, 3, 5, 0, 6, 4}; + assertEquals(expected, sort); + + assertEquals(expected, rank(${pt.primitive}s)); + assertEquals(expected, rank(${pt.boxed}s)); + + assertNull(rank((${pt.vector})null)); + assertNull(rank((${pt.primitive}[])null)); + assertNull(rank((${pt.boxed}[])null)); + assertEquals(new int[]{}, rank(new ${pt.vectorDirect}())); + assertEquals(new int[]{}, rank(new ${pt.primitive}[]{})); + assertEquals(new int[]{}, rank(new ${pt.boxed}[]{})); + } + public void test${pt.boxed}SortDescending() { final ${pt.primitive}[] ${pt.primitive}s = new ${pt.primitive}[]{1, -5, -2, -2, 96, 0, 12, ${pt.null}, ${pt.null}}; final ${pt.boxed}[] ${pt.boxed}s = new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})-5, (${pt.primitive})-2, (${pt.primitive})-2, (${pt.primitive})96, (${pt.primitive})0, (${pt.primitive})12, (${pt.primitive})${pt.null}, (${pt.primitive})${pt.null}}; @@ -136,7 +155,26 @@ public class TestSort extends BaseArrayTestCase { assertEquals(new ${pt.primitive}[]{}, sortDescending(new ${pt.boxed}[]{})); } - public void test${pt.boxed}SortsExceptions() { + public void test${pt.boxed}rankDescending() { + final ${pt.primitive}[] ${pt.primitive}s = new ${pt.primitive}[]{1, -5, -2, -2, 96, 0, 12, ${pt.null}, ${pt.null}}; + final ${pt.boxed}[] ${pt.boxed}s = new ${pt.boxed}[]{(${pt.primitive})1, (${pt.primitive})-5, (${pt.primitive})-2, (${pt.primitive})-2, (${pt.primitive})96, (${pt.primitive})0, (${pt.primitive})12, (${pt.primitive})${pt.null}, (${pt.primitive})${pt.null}}; + + final int[] sort = rankDescending(new ${pt.vectorDirect}(${pt.primitive}s)); + final int[] expected = new int[]{4, 6, 0, 5, 2, 3, 1, 7, 8}; + assertEquals(expected, sort); + + assertEquals(expected, rankDescending(${pt.primitive}s)); + assertEquals(expected, rankDescending(${pt.boxed}s)); + + assertNull(rankDescending((${pt.vector})null)); + assertNull(rankDescending((${pt.primitive}[])null)); + assertNull(rankDescending((${pt.boxed}[])null)); + assertEquals(new int[]{}, rankDescending(new ${pt.vectorDirect}())); + assertEquals(new int[]{}, rankDescending(new ${pt.primitive}[]{})); + assertEquals(new int[]{}, rankDescending(new ${pt.boxed}[]{})); + } + + public void test${pt.boxed}SortExceptions() { ${pt.vector} db${pt.boxed}Array = null; ${pt.primitive}[] sort = sort(db${pt.boxed}Array); assertNull(sort); @@ -153,6 +191,23 @@ public class TestSort extends BaseArrayTestCase { assertTrue(ArrayUtils.isEmpty(sortArray)); } + public void test${pt.boxed}RankExceptions() { + ${pt.vector} db${pt.boxed}Array = null; + int[] sort = rank(db${pt.boxed}Array); + assertNull(sort); + + ${pt.primitive}[] ${pt.primitive}s = null; + int[] sortArray = rank(${pt.primitive}s); + assertNull(sortArray); + + ${pt.primitive}s = new ${pt.primitive}[]{}; + sort = rank(new ${pt.vectorDirect}(${pt.primitive}s)); + assertEquals(new int[0], sort); + + sortArray = rank(${pt.primitive}s); + assertTrue(ArrayUtils.isEmpty(sortArray)); + } + public void test${pt.boxed}SortDescendingExceptions() { ${pt.vector} db${pt.boxed}Array = null; ${pt.primitive}[] sort = sortDescending(db${pt.boxed}Array); @@ -170,7 +225,23 @@ public class TestSort extends BaseArrayTestCase { assertTrue(ArrayUtils.isEmpty(sortArray)); } - + public void test${pt.boxed}rankDescendingExceptions() { + ${pt.vector} db${pt.boxed}Array = null; + int[] sort = rankDescending(db${pt.boxed}Array); + assertNull(sort); + + ${pt.primitive}[] ${pt.primitive}s = null; + int[] sortArray = rankDescending(${pt.primitive}s); + assertNull(sortArray); + + ${pt.primitive}s = new ${pt.primitive}[]{}; + sort = rankDescending(new ${pt.vectorDirect}(${pt.primitive}s)); + assertEquals(new int[0], sort); + + sortArray = rankDescending(${pt.primitive}s); + assertTrue(ArrayUtils.isEmpty(sortArray)); + } + } \ No newline at end of file diff --git a/engine/table/src/main/java/io/deephaven/libs/GroovyStaticImports.java b/engine/table/src/main/java/io/deephaven/libs/GroovyStaticImports.java index e881872850c..9ad4146b6f5 100644 --- a/engine/table/src/main/java/io/deephaven/libs/GroovyStaticImports.java +++ b/engine/table/src/main/java/io/deephaven/libs/GroovyStaticImports.java @@ -598,6 +598,42 @@ public class GroovyStaticImports { /** @see io.deephaven.function.Numeric#clamp(short,short,short) */ public static short clamp( short value, short min, short max ) {return Numeric.clamp( value, min, max );} + /** @see io.deephaven.function.Numeric#compare(byte,byte) */ + public static int compare( byte v1, byte v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Byte,java.lang.Byte) */ + public static int compare( java.lang.Byte v1, java.lang.Byte v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Double,java.lang.Double) */ + public static int compare( java.lang.Double v1, java.lang.Double v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Float,java.lang.Float) */ + public static int compare( java.lang.Float v1, java.lang.Float v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Integer,java.lang.Integer) */ + public static int compare( java.lang.Integer v1, java.lang.Integer v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Long,java.lang.Long) */ + public static int compare( java.lang.Long v1, java.lang.Long v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(java.lang.Short,java.lang.Short) */ + public static int compare( java.lang.Short v1, java.lang.Short v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(double,double) */ + public static int compare( double v1, double v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(float,float) */ + public static int compare( float v1, float v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(int,int) */ + public static int compare( int v1, int v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(long,long) */ + public static int compare( long v1, long v2 ) {return Numeric.compare( v1, v2 );} + + /** @see io.deephaven.function.Numeric#compare(short,short) */ + public static int compare( short v1, short v2 ) {return Numeric.compare( v1, v2 );} + /** @see io.deephaven.function.Basic#concat(java.lang.Object[][]) */ public static T[] concat( T[]... values ) {return Basic.concat( values );} @@ -2086,6 +2122,60 @@ public class GroovyStaticImports { /** @see io.deephaven.function.Numeric#cumsum(io.deephaven.vector.ShortVector) */ public static short[] cumsum( io.deephaven.vector.ShortVector values ) {return Numeric.cumsum( values );} + /** @see io.deephaven.function.Numeric#diff(int,byte[]) */ + public static byte[] diff( int stride, byte... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,double[]) */ + public static double[] diff( int stride, double... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,float[]) */ + public static float[] diff( int stride, float... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,int[]) */ + public static int[] diff( int stride, int... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,long[]) */ + public static long[] diff( int stride, long... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Byte[]) */ + public static byte[] diff( int stride, java.lang.Byte[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Double[]) */ + public static double[] diff( int stride, java.lang.Double[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Float[]) */ + public static float[] diff( int stride, java.lang.Float[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Integer[]) */ + public static int[] diff( int stride, java.lang.Integer[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Long[]) */ + public static long[] diff( int stride, java.lang.Long[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,java.lang.Short[]) */ + public static short[] diff( int stride, java.lang.Short[] values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,short[]) */ + public static short[] diff( int stride, short... values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.ByteVector) */ + public static byte[] diff( int stride, io.deephaven.vector.ByteVector values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.DoubleVector) */ + public static double[] diff( int stride, io.deephaven.vector.DoubleVector values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.FloatVector) */ + public static float[] diff( int stride, io.deephaven.vector.FloatVector values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.IntVector) */ + public static int[] diff( int stride, io.deephaven.vector.IntVector values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.LongVector) */ + public static long[] diff( int stride, io.deephaven.vector.LongVector values ) {return Numeric.diff( stride, values );} + + /** @see io.deephaven.function.Numeric#diff(int,io.deephaven.vector.ShortVector) */ + public static short[] diff( int stride, io.deephaven.vector.ShortVector values ) {return Numeric.diff( stride, values );} + /** @see io.deephaven.function.Basic#distinct(byte[]) */ public static byte[] distinct( byte... values ) {return Basic.distinct( values );} @@ -3439,6 +3529,138 @@ public class GroovyStaticImports { /** @see io.deephaven.function.Random#randomLong(long,long,int) */ public static long[] randomLong( long min, long max, int size ) {return Random.randomLong( min, max, size );} + /** @see io.deephaven.function.Sort#rank(byte[]) */ + public static int[] rank( byte... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(double[]) */ + public static int[] rank( double... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(float[]) */ + public static int[] rank( float... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(int[]) */ + public static int[] rank( int... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(long[]) */ + public static int[] rank( long... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Byte[]) */ + public static int[] rank( java.lang.Byte[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Double[]) */ + public static int[] rank( java.lang.Double[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Float[]) */ + public static int[] rank( java.lang.Float[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Integer[]) */ + public static int[] rank( java.lang.Integer[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Long[]) */ + public static int[] rank( java.lang.Long[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(java.lang.Short[]) */ + public static int[] rank( java.lang.Short[] values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(short[]) */ + public static int[] rank( short... values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.ByteVector) */ + public static int[] rank( io.deephaven.vector.ByteVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.DoubleVector) */ + public static int[] rank( io.deephaven.vector.DoubleVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.FloatVector) */ + public static int[] rank( io.deephaven.vector.FloatVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.IntVector) */ + public static int[] rank( io.deephaven.vector.IntVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.LongVector) */ + public static int[] rank( io.deephaven.vector.LongVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rank(io.deephaven.vector.ShortVector) */ + public static int[] rank( io.deephaven.vector.ShortVector values ) {return Sort.rank( values );} + + /** @see io.deephaven.function.Sort#rankDescending(byte[]) */ + public static int[] rankDescending( byte... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(double[]) */ + public static int[] rankDescending( double... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(float[]) */ + public static int[] rankDescending( float... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(int[]) */ + public static int[] rankDescending( int... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(long[]) */ + public static int[] rankDescending( long... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Byte[]) */ + public static int[] rankDescending( java.lang.Byte[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Double[]) */ + public static int[] rankDescending( java.lang.Double[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Float[]) */ + public static int[] rankDescending( java.lang.Float[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Integer[]) */ + public static int[] rankDescending( java.lang.Integer[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Long[]) */ + public static int[] rankDescending( java.lang.Long[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(java.lang.Short[]) */ + public static int[] rankDescending( java.lang.Short[] values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(short[]) */ + public static int[] rankDescending( short... values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.ByteVector) */ + public static int[] rankDescending( io.deephaven.vector.ByteVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.DoubleVector) */ + public static int[] rankDescending( io.deephaven.vector.DoubleVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.FloatVector) */ + public static int[] rankDescending( io.deephaven.vector.FloatVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.IntVector) */ + public static int[] rankDescending( io.deephaven.vector.IntVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.LongVector) */ + public static int[] rankDescending( io.deephaven.vector.LongVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescending(io.deephaven.vector.ShortVector) */ + public static int[] rankDescending( io.deephaven.vector.ShortVector values ) {return Sort.rankDescending( values );} + + /** @see io.deephaven.function.Sort#rankDescendingObj(java.lang.Comparable[]) */ + public static > int[] rankDescendingObj( T... values ) {return Sort.rankDescendingObj( values );} + + /** @see io.deephaven.function.Sort#rankDescendingObj(io.deephaven.vector.ObjectVector) */ + public static > int[] rankDescendingObj( io.deephaven.vector.ObjectVector values ) {return Sort.rankDescendingObj( values );} + + /** @see io.deephaven.function.Sort#rankDescendingObj(java.lang.Comparable[],java.util.Comparator) */ + public static > int[] rankDescendingObj( T[] values, java.util.Comparator comparator ) {return Sort.rankDescendingObj( values, comparator );} + + /** @see io.deephaven.function.Sort#rankDescendingObj(io.deephaven.vector.ObjectVector,java.util.Comparator) */ + public static > int[] rankDescendingObj( io.deephaven.vector.ObjectVector values, java.util.Comparator comparator ) {return Sort.rankDescendingObj( values, comparator );} + + /** @see io.deephaven.function.Sort#rankObj(java.lang.Comparable[]) */ + public static > int[] rankObj( T... values ) {return Sort.rankObj( values );} + + /** @see io.deephaven.function.Sort#rankObj(io.deephaven.vector.ObjectVector) */ + public static > int[] rankObj( io.deephaven.vector.ObjectVector values ) {return Sort.rankObj( values );} + + /** @see io.deephaven.function.Sort#rankObj(java.lang.Comparable[],java.util.Comparator) */ + public static > int[] rankObj( T[] values, java.util.Comparator comparator ) {return Sort.rankObj( values, comparator );} + + /** @see io.deephaven.function.Sort#rankObj(io.deephaven.vector.ObjectVector,java.util.Comparator) */ + public static > int[] rankObj( io.deephaven.vector.ObjectVector values, java.util.Comparator comparator ) {return Sort.rankObj( values, comparator );} + /** @see io.deephaven.function.BinSearch#rawBinSearchIndex(java.lang.Comparable[],java.lang.Comparable,io.deephaven.function.BinSearchAlgo) */ public static > int rawBinSearchIndex( T[] values, T key, io.deephaven.function.BinSearchAlgo choiceWhenEquals ) {return BinSearch.rawBinSearchIndex( values, key, choiceWhenEquals );}