From 93f745dc26660a1af44b2f31e65be75beb45c715 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Wed, 23 Nov 2016 15:15:05 +0100 Subject: [PATCH] Implement rgamma + unified tests for all rxxx functions --- .../oracle/truffle/r/library/stats/RBeta.java | 21 +- .../truffle/r/library/stats/RCauchy.java | 6 +- .../truffle/r/library/stats/RGamma.java | 207 ++++++++++++++++++ .../stats/RandGenerationFunctions.java | 50 ++++- .../truffle/r/library/stats/Rbinom.java | 16 +- .../oracle/truffle/r/library/stats/Rnorm.java | 19 +- .../oracle/truffle/r/library/stats/Runif.java | 9 +- .../oracle/truffle/r/library/stats/SExp.java | 81 +++++++ .../oracle/truffle/r/library/stats/SNorm.java | 40 ++++ .../truffle/r/library/stats/TOMS708.java | 2 +- .../base/foreign/ForeignFunctions.java | 3 + .../oracle/truffle/r/runtime/rng/RRNG.java | 2 +- .../truffle/r/test/ExpectedTestOutput.test | 176 +++++++++------ .../library/stats/TestExternal_rbeta.java | 35 --- .../library/stats/TestExternal_rcauchy.java | 36 --- .../library/stats/TestExternal_rnorm.java | 39 ---- .../library/stats/TestExternal_runif.java | 35 --- .../stats/TestRandGenerationFunctions.java | 60 +++++ mx.fastr/copyrights/overrides | 3 + 19 files changed, 581 insertions(+), 259 deletions(-) create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java delete mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java delete mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java delete mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java delete mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java index e95c7189cd..9ba8e64a12 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java @@ -18,22 +18,22 @@ import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2; import static com.oracle.truffle.r.library.stats.StatsUtil.fmin2; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; -import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; public final class RBeta implements RandFunction2_Double { private static final double expmax = (DBL_MAX_EXP * M_LN2); /* = log(DBL_MAX) */ @Override - public double evaluate(double aa, double bb, RandomNumberGenerator rand) { + public double evaluate(double aa, double bb, RandomNumberProvider rand) { if (Double.isNaN(aa) || Double.isNaN(bb) || aa < 0. || bb < 0.) { - StatsUtil.mlError(); + return StatsUtil.mlError(); } if (!Double.isFinite(aa) && !Double.isFinite(bb)) { // a = b = Inf : all mass at 1/2 return 0.5; } if (aa == 0. && bb == 0.) { // point mass 1/2 at each of {0,1} : - return (rand.genrandDouble() < 0.5) ? 0. : 1.; + return (rand.unifRand() < 0.5) ? 0. : 1.; } // now, at least one of a, b is finite and positive if (!Double.isFinite(aa) || bb == 0.) { @@ -54,14 +54,15 @@ public final class RBeta implements RandFunction2_Double { double w = 0; double y; double z; - double olda = -1.0; - double oldb = -1.0; + // TODO: state variables double beta = 0; double gamma = 1; double delta; double k1 = 0; double k2 = 0; + double olda = -1.0; + double oldb = -1.0; /* Test if we need new "initializing" */ boolean qsame = (olda == aa) && (oldb == bb); @@ -84,8 +85,8 @@ public final class RBeta implements RandFunction2_Double { } /* FIXME: "do { } while()", but not trivially because of "continue"s: */ for (;;) { - u1 = rand.genrandDouble(); - u2 = rand.genrandDouble(); + u1 = rand.unifRand(); + u2 = rand.unifRand(); if (u1 < 0.5) { y = u1 * u2; z = u1 * y; @@ -120,8 +121,8 @@ public final class RBeta implements RandFunction2_Double { gamma = a + 1.0 / beta; } do { - u1 = rand.genrandDouble(); - u2 = rand.genrandDouble(); + u1 = rand.unifRand(); + u2 = rand.unifRand(); v = beta * Math.log(u1 / (1.0 - u1)); w = wFromU1Bet(a, v, w); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java index 5cd94ab533..accf46e7c2 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java @@ -14,18 +14,18 @@ package com.oracle.truffle.r.library.stats; import static com.oracle.truffle.r.library.stats.MathConstants.M_PI; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; -import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; public final class RCauchy implements RandFunction2_Double { @Override - public double evaluate(double location, double scale, RandomNumberGenerator rand) { + public double evaluate(double location, double scale, RandomNumberProvider rand) { if (Double.isNaN(location) || !Double.isFinite(scale) || scale < 0) { return StatsUtil.mlError(); } if (scale == 0. || !Double.isFinite(location)) { return location; } else { - return location + scale * Math.tan(M_PI * rand.genrandDouble()); + return location + scale * Math.tan(M_PI * rand.unifRand()); } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java new file mode 100644 index 0000000000..0e8581b503 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java @@ -0,0 +1,207 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 1998--2008, The R Core Team + * Copyright (c) 2016, 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.TOMS708.fabs; + +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; + +public class RGamma implements RandFunction2_Double { + private static final double sqrt32 = 5.656854; + private static final double exp_m1 = 0.36787944117144232159; /* exp(-1) = 1/e */ + + /* + * Coefficients q[k] - for q0 = sum(q[k]*a^(-k)) Coefficients a[k] - for q = + * q0+(t*t/2)*sum(a[k]*v^k) Coefficients e[k] - for exp(q)-1 = sum(e[k]*q^k) + */ + private static final double q1 = 0.04166669; + private static final double q2 = 0.02083148; + private static final double q3 = 0.00801191; + private static final double q4 = 0.00144121; + private static final double q5 = -7.388e-5; + private static final double q6 = 2.4511e-4; + private static final double q7 = 2.424e-4; + + private static final double a1 = 0.3333333; + private static final double a2 = -0.250003; + private static final double a3 = 0.2000062; + private static final double a4 = -0.1662921; + private static final double a5 = 0.1423657; + private static final double a6 = -0.1367177; + private static final double a7 = 0.1233795; + + @Override + public double evaluate(double a, double scale, RandomNumberProvider rand) { + + // TODO: state variables + double aa = 0.; + double aaa = 0.; + double s = 0; + double s2 = 0; + double d = 0; /* no. 1 (step 1) */ + double q0 = 0; + double b = 0; + double si = 0; + double c = 0; /* no. 2 (step 4) */ + + double e; + double p; + double q; + double r; + double t; + double u; + double v; + double w; + double x; + double retVal; + + if (Double.isNaN(a) || Double.isNaN(scale)) { + return StatsUtil.mlError(); + } + if (a <= 0.0 || scale <= 0.0) { + if (scale == 0. || a == 0.) { + return 0.; + } + return StatsUtil.mlError(); + } + if (!Double.isFinite(a) || !Double.isFinite(scale)) { + return Double.POSITIVE_INFINITY; + } + + if (a < 1.) { /* GS algorithm for parameters a < 1 */ + e = 1.0 + exp_m1 * a; + while (true) { + p = e * rand.unifRand(); + if (p >= 1.0) { + x = -Math.log((e - p) / a); + if (rand.expRand() >= (1.0 - a) * Math.log(x)) { + break; + } + } else { + x = Math.exp(Math.log(p) / a); + if (rand.expRand() >= x) { + break; + } + } + } + return scale * x; + } + + /* --- a >= 1 : GD algorithm --- */ + + /* Step 1: Recalculations of s2, s, d if a has changed */ + if (a != aa) { + aa = a; + s2 = a - 0.5; + s = Math.sqrt(s2); + d = sqrt32 - s * 12.0; + } + /* + * Step 2: t = standard normal deviate, x = (s,1/2) -normal deviate. + */ + + /* immediate acceptance (i) */ + t = rand.normRand(); + x = s + 0.5 * t; + retVal = x * x; + if (t >= 0.0) { + return scale * retVal; + } + + /* Step 3: u = 0,1 - uniform sample. squeeze acceptance (s) */ + u = rand.unifRand(); + if (d * u <= Math.pow(t, 3)) { + return scale * retVal; + } + + /* Step 4: recalculations of q0, b, si, c if necessary */ + + if (a != aaa) { + aaa = a; + r = 1.0 / a; + q0 = ((((((q7 * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r; + + /* Approximation depending on size of parameter a */ + /* The constants in the expressions for b, si and c */ + /* were established by numerical experiments */ + + if (a <= 3.686) { + b = 0.463 + s + 0.178 * s2; + si = 1.235; + c = 0.195 / s - 0.079 + 0.16 * s; + } else if (a <= 13.022) { + b = 1.654 + 0.0076 * s2; + si = 1.68 / s + 0.275; + c = 0.062 / s + 0.024; + } else { + b = 1.77; + si = 0.75; + c = 0.1515 / s; + } + } + /* Step 5: no quotient test if x not positive */ + + if (x > 0.0) { + /* Step 6: calculation of v and quotient q */ + v = t / (s + s); + if (fabs(v) <= 0.25) { + q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; + } else { + q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.log(1.0 + v); + } + + /* Step 7: quotient acceptance (q) */ + if (Math.log(1.0 - u) <= q) { + return scale * retVal; + } + } + + while (true) { + /* + * Step 8: e = standard exponential deviate u = 0,1 -uniform deviate t = (b,si)-double + * exponential (laplace) sample + */ + e = rand.expRand(); + u = rand.unifRand(); + u = u + u - 1.0; + if (u < 0.0) { + t = b - si * e; + } else { + t = b + si * e; + } + /* Step 9: rejection if t < tau(1) = -0.71874483771719 */ + if (t >= -0.71874483771719) { + /* Step 10: calculation of v and quotient q */ + v = t / (s + s); + if (fabs(v) <= 0.25) { + q = q0 + 0.5 * t * t * + ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; + } else { + q = q0 - s * t + 0.25 * t * t + (s2 + s2) * Math.log(1.0 + v); + } + /* Step 11: hat acceptance (h) */ + /* (if q not positive go to step 8) */ + if (q > 0.0) { + w = StatsUtil.expm1(q); + /* ^^^^^ original code had approximation with rel.err < 2e-7 */ + /* if t is rejected sample again at step 8 */ + if (c * fabs(u) <= w * Math.exp(e - 0.5 * t * t)) { + break; + } + } + } + } /* repeat .. until `t' is accepted */ + x = s + 0.5 * t; + return scale * x * x; + } +} 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 f0381ccb39..733f8f8b97 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 @@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.rng.RRNG; +import com.oracle.truffle.r.runtime.rng.RRNG.NormKind; import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; public final class RandGenerationFunctions { @@ -48,23 +49,45 @@ public final class RandGenerationFunctions { // static class } + public static final class RandomNumberProvider { + private final RandomNumberGenerator generator; + private final NormKind normKind; + + public RandomNumberProvider(RandomNumberGenerator generator, NormKind normKind) { + this.generator = generator; + this.normKind = normKind; + } + + public double unifRand() { + return generator.genrandDouble(); + } + + public double normRand() { + return SNorm.normRand(generator, normKind); + } + + public double expRand() { + return SExp.expRand(generator); + } + } + // inspired by the DEFRAND{X}_REAL and DEFRAND{X}_INT macros in GnuR public interface RandFunction3_Int { - int evaluate(double a, double b, double c, RandomNumberGenerator rand); + int evaluate(double a, double b, double c, RandomNumberProvider rand); } public interface RandFunction2_Int extends RandFunction3_Int { @Override - default int evaluate(double a, double b, double c, RandomNumberGenerator rand) { + default int evaluate(double a, double b, double c, RandomNumberProvider rand) { return evaluate(a, b, rand); } - int evaluate(double a, double b, RandomNumberGenerator rand); + int evaluate(double a, double b, RandomNumberProvider rand); } public interface RandFunction2_Double { - double evaluate(double a, double b, RandomNumberGenerator rand); + double evaluate(double a, double b, RandomNumberProvider rand); } static final class RandGenerationProfiles { @@ -73,15 +96,20 @@ public final class RandGenerationFunctions { final VectorLengthProfile resultVectorLengthProfile = VectorLengthProfile.create(); final LoopConditionProfile loopConditionProfile = LoopConditionProfile.createCountingProfile(); final ValueProfile randClassProfile = ValueProfile.createClassProfile(); + final ValueProfile normKindProfile = ValueProfile.createEqualityProfile(); public static RandGenerationProfiles create() { return new RandGenerationProfiles(); } + + public RandomNumberProvider createRandProvider() { + return new RandomNumberProvider(randClassProfile.profile(RRNG.currentGenerator()), normKindProfile.profile(RRNG.currentNormKind())); + } } private static RAbstractIntVector evaluate3Int(Node node, RandFunction3_Int function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RAbstractDoubleVector c, RandGenerationProfiles profiles) { - int length = profiles.resultVectorLengthProfile.profile(lengthIn); + int length = lengthIn; int aLength = a.getLength(); int bLength = b.getLength(); int cLength = c.getLength(); @@ -93,11 +121,12 @@ public final class RandGenerationFunctions { return RDataFactory.createIntVector(nansResult, false); } + length = profiles.resultVectorLengthProfile.profile(length); RNode.reportWork(node, length); boolean nans = false; int[] result = new int[length]; RRNG.getRNGState(); - RandomNumberGenerator rand = profiles.randClassProfile.profile(RRNG.currentGenerator()); + RandomNumberProvider rand = profiles.createRandProvider(); for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) { double aValue = a.getDataAt(i % aLength); double bValue = b.getDataAt(i % bLength); @@ -117,21 +146,22 @@ public final class RandGenerationFunctions { } private static RAbstractDoubleVector evaluate2Double(Node node, RandFunction2_Double function, int lengthIn, RAbstractDoubleVector a, RAbstractDoubleVector b, RandGenerationProfiles profiles) { - int length = profiles.resultVectorLengthProfile.profile(lengthIn); + int length = lengthIn; int aLength = a.getLength(); int bLength = b.getLength(); if (aLength == 0 || bLength == 0) { profiles.nanResult.enter(); - RError.warning(SHOW_CALLER, RError.Message.NAN_PRODUCED); + RError.warning(SHOW_CALLER, RError.Message.NA_PRODUCED); return createVectorOf(length, RRuntime.DOUBLE_NA); } + length = profiles.resultVectorLengthProfile.profile(length); RNode.reportWork(node, length); boolean nans = false; double[] result; result = new double[length]; RRNG.getRNGState(); - RandomNumberGenerator rand = profiles.randClassProfile.profile(RRNG.currentGenerator()); + RandomNumberProvider rand = profiles.createRandProvider(); for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) { double aValue = a.getDataAt(i % aLength); double bValue = b.getDataAt(i % bLength); @@ -168,7 +198,7 @@ public final class RandGenerationFunctions { @Cached("createNonPreserving()") CastIntegerNode castNode, @Cached("create()") BranchProfile seenNA) { int result = ((RAbstractIntVector) castNode.execute(vector)).getDataAt(0); - if (RRuntime.isNA(result)) { + if (RRuntime.isNA(result) || result < 0) { seenNA.enter(); throw RError.error(SHOW_CALLER, INVALID_UNNAMED_ARGUMENTS); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java index 5fe4514576..c63e7e44f3 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java @@ -13,8 +13,8 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Int; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; // transcribed from rbinom.c @@ -22,12 +22,8 @@ public final class Rbinom implements RandFunction2_Int { private final Qbinom qbinom = new Qbinom(); - private static double unifRand(RandomNumberGenerator rand) { - return rand.genrandDouble(); - } - @Override - public int evaluate(double nin, double pp, RandomNumberGenerator rand) { + public int evaluate(double nin, double pp, RandomNumberProvider rand) { double psave = -1.0; int nsave = -1; @@ -54,7 +50,7 @@ public final class Rbinom implements RandFunction2_Int { /* * evade integer overflow, and r == INT_MAX gave only even values */ - return (int) qbinom.evaluate(unifRand(rand), r, pp, /* lower_tail */false, /* log_p */false); + return (int) qbinom.evaluate(rand.unifRand(), r, pp, /* lower_tail */false, /* log_p */false); } /* else */ int n = (int) r; @@ -135,8 +131,8 @@ public final class Rbinom implements RandFunction2_Int { /*-------------------------- np = n*p >= 30 : ------------------- */ while (true) { - u = unifRand(rand) * p4; - v = unifRand(rand); + u = rand.unifRand() * p4; + v = rand.unifRand(); /* triangular region */ if (u <= p1) { ix = (int) (xm - p1 * v + u); @@ -223,7 +219,7 @@ public final class Rbinom implements RandFunction2_Int { while (true) { ix = 0; f = qn; - u = unifRand(rand); + u = rand.unifRand(); while (true) { if (u < f) { // goto finis; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java index 5fd5a25246..24f2aed7d5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java @@ -12,17 +12,18 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; -import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; public final class Rnorm implements RandFunction2_Double { - - private static final double BIG = 134217728; - @Override - public double evaluate(double mu, double sigma, RandomNumberGenerator rand) { - // TODO: GnuR invokes norm_rand to get "rand" - double u1 = (int) (BIG * rand.genrandDouble()) + rand.genrandDouble(); - double random = Random2.qnorm5(u1 / BIG, 0.0, 1.0, true, false); - return random * sigma + mu; + public double evaluate(double mu, double sigma, RandomNumberProvider rand) { + if (Double.isNaN(mu) || !Double.isFinite(sigma) || sigma < 0.) { + return StatsUtil.mlError(); + } + if (sigma == 0. || !Double.isFinite(mu)) { + return mu; /* includes mu = +/- Inf with finite sigma */ + } else { + return mu + sigma * rand.normRand(); + } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java index 39cf514eec..57a877536f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java @@ -23,15 +23,18 @@ package com.oracle.truffle.r.library.stats; 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.RRuntime; -import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; public final class Runif implements RandFunction2_Double { @Override - public double evaluate(double min, double max, RandomNumberGenerator rand) { + public double evaluate(double min, double max, RandomNumberProvider rand) { if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) { return StatsUtil.mlError(); } - return min + rand.genrandDouble() * (max - min); + if (min == max) { + return min; + } + return min + rand.unifRand() * (max - min); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java new file mode 100644 index 0000000000..924bbf783c --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java @@ -0,0 +1,81 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 1998--2008, The R Core Team + * Copyright (c) 2016, 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; + +/** + * Generation of random value from standard exponential distribution. Corresponds to {@code sexp.c} + * in GnuR. + */ +public final class SExp { + private SExp() { + // only static members + } + + /* q[k-1] = sum(log(2)^k / k!) k=1,..,n, */ + /* The highest n (here 16) is determined by q[n-1] = 1.0 */ + /* within standard precision */ + @CompilationFinal(dimensions = 1) private static final double[] q = { + 0.6931471805599453, + 0.9333736875190459, + 0.9888777961838675, + 0.9984959252914960, + 0.9998292811061389, + 0.9999833164100727, + 0.9999985691438767, + 0.9999998906925558, + 0.9999999924734159, + 0.9999999995283275, + 0.9999999999728814, + 0.9999999999985598, + 0.9999999999999289, + 0.9999999999999968, + 0.9999999999999999, + 1.0000000000000000 + }; + + public static double expRand(RandomNumberGenerator generator) { + double a = 0.; + // precaution if u = 0 is ever returned + double u = generator.genrandDouble(); + while (u <= 0. || u >= 1.) { + u = generator.genrandDouble(); + } + + for (;;) { + u += u; + if (u > 1.) { + break; + } + a += q[0]; + } + u -= 1.; + + if (u <= q[0]) { + return a + u; + } + + int i = 0; + double ustar = generator.genrandDouble(); + double umin = ustar; + do { + ustar = generator.genrandDouble(); + if (umin > ustar) { + umin = ustar; + } + i++; + } while (u > q[i]); + return a + umin * q[0]; + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java new file mode 100644 index 0000000000..0f6737a375 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java @@ -0,0 +1,40 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 1998--2008, The R Core Team + * Copyright (c) 2016, 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.rng.RRNG.NormKind; +import com.oracle.truffle.r.runtime.rng.RandomNumberGenerator; + +/** + * Generation of random value from standard normal distribution N(0,1). Corresponds to + * {@code snorm.c} in GnuR. + */ +public final class SNorm { + private SNorm() { + // only static members + } + + // TODO: implement other normKinds + + private static final double BIG = 134217728; /* 2^27 */ + + public static double normRand(RandomNumberGenerator rand, NormKind normKind) { + if (normKind != NormKind.INVERSION) { + throw RError.nyi(null, "unifNorm(): no other NormKind than the default INVERSION is implemented"); + } + /* unif_rand() alone is not of high enough precision */ + double u1 = rand.genrandDouble(); + u1 = (int) (BIG * u1) + rand.genrandDouble(); + return Random2.qnorm5(u1 / BIG, 0.0, 1.0, true, false); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java index d1ddd7ab79..a61e44b422 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java @@ -67,7 +67,7 @@ public class TOMS708 { return Math.exp(v); } - private static double fabs(double v) { + public static double fabs(double v) { return Math.abs(v); } 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 78711bb74f..388be65497 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 @@ -56,6 +56,7 @@ import com.oracle.truffle.r.library.stats.Qbinom; import com.oracle.truffle.r.library.stats.Qnorm; import com.oracle.truffle.r.library.stats.RBeta; import com.oracle.truffle.r.library.stats.RCauchy; +import com.oracle.truffle.r.library.stats.RGamma; import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory; import com.oracle.truffle.r.library.stats.Rbinom; import com.oracle.truffle.r.library.stats.Rnorm; @@ -370,6 +371,8 @@ public class ForeignFunctions { return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new Runif()); case "rbeta": return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RBeta()); + case "rgamma": + return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RGamma()); case "rcauchy": return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RCauchy()); case "qgamma": diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java index 3310329048..28b845bc33 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java @@ -197,7 +197,7 @@ public class RRNG { return getContextState().currentGenerator; } - private static NormKind currentNormKind() { + public static NormKind currentNormKind() { return getContextState().currentNormKind; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 3043028d70..a2de816f0c 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -111074,16 +111074,6 @@ Error: 'x' is NULL Warning message: In qgamma(10, 1) : NaNs produced -##com.oracle.truffle.r.test.library.stats.TestExternal_rbeta.testRbeta# -#set.seed(42); rbeta(10, 10, 10) - [1] 0.4282247 0.5459560 0.5805863 0.5512005 0.4866080 0.6987626 0.4880555 - [8] 0.7691043 0.4920874 0.6702352 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rbeta.testRbeta# -#set.seed(42); rbeta(10, c(0.1, 2:10), c(0.1, 0.5, 0.9, 3:5)) - [1] 0.002930982 0.969019187 0.872817723 0.593769928 0.260911852 0.561458988 - [7] 1.000000000 0.929063923 0.991793861 0.914489454 - ##com.oracle.truffle.r.test.library.stats.TestExternal_rbinom.testRbinom# #set.seed(42); rbinom('10', 10, 0.5) [1] 7 7 4 7 6 5 6 3 6 6 @@ -111110,63 +111100,6 @@ In rbinom("aa", 10, 0.5) : NAs introduced by coercion #set.seed(42); rbinom(c(1,2), 11:12, c(0.1, 0.5, 0.9)) [1] 3 9 -##com.oracle.truffle.r.test.library.stats.TestExternal_rcauchy.testRcauchy# -#set.seed(42); rcauchy(10, 10, -1) - [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -Warning message: -In rcauchy(10, 10, -1) : NAs produced - -##com.oracle.truffle.r.test.library.stats.TestExternal_rcauchy.testRcauchy# -#set.seed(42); rcauchy(10, 10, 10) - [1] 7.2577591 7.9970061 22.5740275 4.1049817 -10.9520771 - [6] -156.4897232 -0.8802923 14.5025696 -8.6041975 -3.3131055 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rcauchy.testRcauchy# -#set.seed(42); rcauchy(10, NaN, 10) - [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -Warning message: -In rcauchy(10, NaN, 10) : NAs produced - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm# -#set.seed(42); rnorm('10', 10, 5) - [1] 16.854792 7.176509 11.815642 13.164313 12.021342 9.469377 17.557610 - [8] 9.526705 20.092119 9.686430 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm#Output.IgnoreWarningContext# -#set.seed(42); rnorm('aa', 10, 0.5) -Error in rnorm("aa", 10, 0.5) : invalid arguments -In addition: Warning message: -In rnorm("aa", 10, 0.5) : NAs introduced by coercion - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm# -#set.seed(42); rnorm(10, 10, 10) - [1] 23.709584 4.353018 13.631284 16.328626 14.042683 8.938755 25.115220 - [8] 9.053410 30.184237 9.372859 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm# -#set.seed(42); rnorm(10, 2:10, c(0.1, 0.5, 0.9)) - [1] 2.137096 2.717651 4.326816 5.063286 6.202134 6.904488 8.151152 - [8] 8.952670 11.816581 1.993729 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm# -#set.seed(42); rnorm(1:10, 2:10, c(0.1, 0.5, 0.9)) - [1] 2.137096 2.717651 4.326816 5.063286 6.202134 6.904488 8.151152 - [8] 8.952670 11.816581 1.993729 - -##com.oracle.truffle.r.test.library.stats.TestExternal_rnorm.testRnorm# -#set.seed(42); rnorm(c(1,2), 11:12, c(0.1, 0.5, 0.9)) -[1] 11.13710 11.71765 - -##com.oracle.truffle.r.test.library.stats.TestExternal_runif.testRunif# -#set.seed(1); runif(5); -[1] 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819 - -##com.oracle.truffle.r.test.library.stats.TestExternal_runif.testRunif# -#set.seed(1); runif(5, 10, 2.5); -[1] NaN NaN NaN NaN NaN -Warning message: -In runif(5, 10, 2.5) : NAs produced - ##com.oracle.truffle.r.test.library.stats.TestFitting.testLm#Output.IgnoreWhitespace# #y <- c(26.55, 37.21, 57.28, 90.82, 20.16, 89.838, 94.46, 20.5, 17.6, 68.7, 38.41, 76.9, 49.7, 71, 99.19, 16); x <- c(26.55, 37.21, 57.28, 90.82, 20.16, 89.838, 94.46, 20.5, 17.6, 68.7, 38.41, 76.9, 49.7, 71, 99.19, 16); res <- lm(y~x); print(res$coefficients);print(res$fitted.values);print(res$xlevels);print(res$residuals);print(res$assign);print(res$effects);print(res$qr$qr);print(res$rank);print(res$model); (Intercept) x @@ -113519,6 +113452,115 @@ $variables list(y, z) +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rbeta(10, 10, 10) + [1] 0.4202441 0.5231868 0.3929161 0.7104015 0.5416782 0.3949132 0.5618393 + [8] 0.5943116 0.5732049 0.4613867 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rbeta(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) + [1] NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN NaN +Warning message: +In rbeta(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rbeta(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) + [1] NaN 0.00000000 1.00000000 0.82338531 0.17213601 NaN + [7] 1.00000000 NaN 0.00000000 0.06525112 NaN 1.00000000 +[13] 0.99955874 0.92371833 NaN NaN 1.00000000 0.99409008 +[19] 0.93534230 0.58348863 +Warning message: +In rbeta(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rgamma(10, 10, 10) + [1] 0.7667251 1.4040808 1.3826660 1.0820993 0.5346417 1.1061754 1.1911950 + [8] 1.1357558 0.8582045 0.7196892 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rgamma(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) + [1] NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN NaN +Warning message: +In rgamma(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rgamma(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) + [1] NaN 0.00000000 0.01881730 1.92594160 0.45110798 NaN + [7] Inf NaN 0.00000000 0.05989429 NaN Inf +[13] 62.08824595 6.89167118 NaN 0.00000000 Inf 22.88066299 +[19] 2.26717120 0.72159817 +Warning message: +In rgamma(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rnorm(10, 10, 10) + [1] 3.735462 11.836433 1.643714 25.952808 13.295078 1.795316 14.874291 + [8] 17.383247 15.757814 6.946116 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rnorm(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) + [1] NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN NaN +Warning message: +In rnorm(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); rnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) + [1] NaN 0.0000000 0.1373546 2.1652790 0.4931142 NaN + [7] 5.0000000 -0.8404719 0.2965570 -2.2614052 NaN 3.0000000 +[13] 4.0487429 5.6644922 0.7273441 NaN 0.2000000 1.9694612 +[19] 4.3606031 5.1695297 +Warning message: +In rnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); runif(10, 10, 10) + [1] 10 10 10 10 10 10 10 10 10 10 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); runif(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) + [1] NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN NaN +Warning message: +In runif(12, c(NA, 0, NaN), c(NaN, NaN, NA, 0)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2# +#set.seed(1); runif(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) + [1] -1.0000000 0.0000000 NaN NaN 3.0000000 NaN + [7] NaN -0.7079405 0.3349115 1.8039894 NaN NaN +[13] NaN NaN 2.6328312 NaN NaN NaN +[19] NaN NaN +Warning message: +In runif(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure# +#length(runif('3')) +[1] 3 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure# +#length(runif(c('a', 'b', 'b', 'd'))) +[1] 4 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure# +#length(runif(c(1,2,3))) +[1] 3 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure#Output.IgnoreWarningContext# +#runif('hello') +Error in runif("hello") : invalid arguments +In addition: Warning message: +In runif("hello") : NAs introduced by coercion + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure# +#runif(2, 2, numeric()) +[1] NA NA +Warning message: +In runif(2, 2, numeric()) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2Infrastructure# +#runif(2, numeric(), 2) +[1] NA NA +Warning message: +In runif(2, numeric(), 2) : NAs produced + ##com.oracle.truffle.r.test.library.stats.TestStats.testCor# #{ as.integer(cor(c(1,2,3),c(1,2,5))*10000000) } [1] 9607689 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java deleted file mode 100644 index f4ab519fd4..0000000000 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rbeta.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.test.library.stats; - -import org.junit.Test; - -import com.oracle.truffle.r.test.TestBase; - -public class TestExternal_rbeta extends TestBase { - @Test - public void testRbeta() { - assertEval("set.seed(42); rbeta(10, 10, 10)"); - assertEval("set.seed(42); rbeta(10, c(0.1, 2:10), c(0.1, 0.5, 0.9, 3:5))"); - } -} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java deleted file mode 100644 index f909eb9268..0000000000 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rcauchy.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.test.library.stats; - -import org.junit.Test; - -import com.oracle.truffle.r.test.TestBase; - -public class TestExternal_rcauchy extends TestBase { - @Test - public void testRcauchy() { - assertEval("set.seed(42); rcauchy(10, 10, 10)"); - assertEval("set.seed(42); rcauchy(10, 10, -1)"); - assertEval("set.seed(42); rcauchy(10, NaN, 10)"); - } -} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java deleted file mode 100644 index 1bd9882bfc..0000000000 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnorm.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.test.library.stats; - -import org.junit.Test; - -import com.oracle.truffle.r.test.TestBase; - -public class TestExternal_rnorm extends TestBase { - @Test - public void testRnorm() { - assertEval("set.seed(42); rnorm(10, 10, 10)"); - assertEval("set.seed(42); rnorm('10', 10, 5)"); - assertEval(Output.IgnoreWarningContext, "set.seed(42); rnorm('aa', 10, 0.5)"); - assertEval("set.seed(42); rnorm(10, 2:10, c(0.1, 0.5, 0.9))"); - assertEval("set.seed(42); rnorm(1:10, 2:10, c(0.1, 0.5, 0.9))"); - assertEval("set.seed(42); rnorm(c(1,2), 11:12, c(0.1, 0.5, 0.9))"); - } -} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java deleted file mode 100644 index ad117436f0..0000000000 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_runif.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.test.library.stats; - -import org.junit.Test; - -import com.oracle.truffle.r.test.TestBase; - -public class TestExternal_runif extends TestBase { - @Test - public void testRunif() { - assertEval("set.seed(1); runif(5);"); - assertEval("set.seed(1); runif(5, 10, 2.5);"); - } -} 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 new file mode 100644 index 0000000000..14efb14532 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.test.library.stats; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +/** + * Tests the rxxx functions against common set of arguments. Each such function may have additional + * 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"}; + 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)", + "30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)" + }; + + @Test + public void testFunctions2() { + assertEval(Output.IgnoreWarningContext, template("set.seed(1); %0(%1)", FUNCTION2_NAMES, FUNCTION2_PARAMS)); + } + + @Test + public void testFunctions2Infrastructure() { + // calculating the size of the result: + assertEval("length(runif(c(1,2,3)))"); + assertEval("length(runif(c('a', 'b', 'b', 'd')))"); + assertEval("length(runif('3'))"); + // wrong size argument + assertEval(Output.IgnoreWarningContext, "runif('hello')"); + // empty parameters + assertEval("runif(2, numeric(), 2)"); + assertEval("runif(2, 2, numeric())"); + // wrong parameters + assertEval("runif(-1, 1, 2)"); + } +} diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index d76934e450..3fb3dd1a33 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -55,6 +55,9 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctio com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java,gnu_r_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.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 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/CountFields.java,gnu_r.copyright -- GitLab