From 7b3a8b082dcf569e888f629bcf9c1a0865f05fde Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 25 Nov 2016 23:33:03 +0100 Subject: [PATCH] Implement rwilcox --- .../stats/RandGenerationFunctions.java | 2 +- .../truffle/r/library/stats/Wilcox.java | 68 +++++++++++++++++++ .../base/foreign/ForeignFunctions.java | 3 + .../com/oracle/truffle/r/runtime/RError.java | 1 + .../stats/TestRandGenerationFunctions.java | 2 +- mx.fastr/copyrights/overrides | 1 + 6 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java index 733f8f8b97..6ad6a060ba 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java @@ -166,7 +166,7 @@ public final class RandGenerationFunctions { double aValue = a.getDataAt(i % aLength); double bValue = b.getDataAt(i % bLength); double value = function.evaluate(aValue, bValue, rand); - if (Double.isNaN(value)) { + if (Double.isNaN(value) || Double.isNaN(value)) { profiles.nan.enter(); nans = true; } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java new file mode 100644 index 0000000000..04aec9c58b --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java @@ -0,0 +1,68 @@ +/* + * This material is distributed under the GNU General Public License + * Version 2. You may review the terms of this license at + * http://www.gnu.org/licenses/gpl-2.0.html + * + * Copyright (c) 1999--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ + +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.runtime.RError.Message.CALLOC_COULD_NOT_ALLOCATE_INF; + +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; + +public final class Wilcox { + + public static final class RWilcox implements RandFunction2_Double { + @Override + public double evaluate(double m, double n, RandomNumberProvider rand) { + int i; + int j; + int k; + double r; + + /* NaNs propagated correctly */ + if (Double.isNaN(m) || Double.isNaN(n)) { + return (m + n); + } + if (!Double.isFinite(m) || !Double.isFinite(n)) { + // GnuR does not check this and tries to allocate the memory, we do check this, but + // fail with the same error message for compatibility reasons. + throw RError.error(RError.SHOW_CALLER, CALLOC_COULD_NOT_ALLOCATE_INF); + } + + m = Math.round(m); + n = Math.round(n); + if ((m < 0) || (n < 0)) { + // TODO: for some reason the macro in GNUR here returns NA instead of NaN... + // return StatsUtil.mlError(); + return RRuntime.DOUBLE_NA; + } + + if ((m == 0) || (n == 0)) { + return (0); + } + + r = 0.0; + k = (int) (m + n); + + int[] x = new int[k]; + for (i = 0; i < k; i++) { + x[i] = i; + } + for (i = 0; i < n; i++) { + j = (int) Math.floor(k * rand.unifRand()); + r += x[j]; + x[j] = x[--k]; + } + return (r - n * (n - 1) / 2); + } + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java index 8ea4edee78..eb498d9e37 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java @@ -70,6 +70,7 @@ import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeG import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen; import com.oracle.truffle.r.library.stats.StatsFunctionsFactory; import com.oracle.truffle.r.library.stats.StatsUtil; +import com.oracle.truffle.r.library.stats.Wilcox.RWilcox; import com.oracle.truffle.r.library.tools.C_ParseRdNodeGen; import com.oracle.truffle.r.library.tools.DirChmodNodeGen; import com.oracle.truffle.r.library.tools.Rmd5NodeGen; @@ -390,6 +391,8 @@ public class ForeignFunctions { return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNchisq()); case "rnbinom_mu": return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNbinomMu()); + case "rwilcox": + return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RWilcox()); case "qgamma": return StatsFunctionsFactory.Function3_2NodeGen.create(new QgammaFunc()); case "dbinom": diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index 38c7c2c87d..b3187916a6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -457,6 +457,7 @@ public final class RError extends RuntimeException { UNUSED_ARGUMENT("unused argument (%s)"), UNUSED_ARGUMENTS("unused arguments (%s)"), INFINITE_MISSING_VALUES("infinite or missing values in '%s'"), + CALLOC_COULD_NOT_ALLOCATE_INF("'Calloc' could not allocate memory (18446744071562067968 of 4 bytes)"), NON_SQUARE_MATRIX("non-square matrix in '%s'"), LAPACK_ERROR("error code %d from Lapack routine '%s'"), VALUE_OUT_OF_RANGE("value out of range in '%s'"), diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java index 37f836aed5..02e304d187 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java @@ -31,7 +31,7 @@ import com.oracle.truffle.r.test.TestBase; * tests for its specific corner cases if those are not covered here. */ public class TestRandGenerationFunctions extends TestBase { - private static final String[] FUNCTION2_NAMES = {"rnorm", "runif", "rgamma", "rbeta", "rcauchy", "rf", "rlogis", "rweibull", "rchisq"}; + private static final String[] FUNCTION2_NAMES = {"rnorm", "runif", "rgamma", "rbeta", "rcauchy", "rf", "rlogis", "rweibull", "rchisq", "rwilcox"}; private static final String[] FUNCTION2_PARAMS = { "10, 10, 10", "20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)", diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index fb33bd32fe..13c0f05a46 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -64,6 +64,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java, com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java,gnu_r.core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/ToolsText.java,gnu_r.copyright -- GitLab