From 80cefdbf645b8fddc7fa17b69c609d659c231781 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Fri, 25 Nov 2016 23:21:19 +0100
Subject: [PATCH] Implement C_rnbinom_mu for rnbinom with parameter mu

---
 .../truffle/r/library/stats/RNbinomMu.java    | 30 +++++++++++++
 .../oracle/truffle/r/library/stats/RPois.java | 45 +++++++++----------
 .../base/foreign/ForeignFunctions.java        |  3 ++
 .../library/stats/TestExternal_rnbinom.java   | 37 +++++++++++++++
 mx.fastr/copyrights/overrides                 |  1 +
 5 files changed, 93 insertions(+), 23 deletions(-)
 create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
 create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
new file mode 100644
index 0000000000..bac788a88f
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java
@@ -0,0 +1,30 @@
+/*
+ * 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.library.stats.RandGenerationFunctions.RandFunction2_Double;
+import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider;
+
+public final class RNbinomMu implements RandFunction2_Double {
+    private final RGamma rgamma = new RGamma();
+
+    @Override
+    public double evaluate(double size, double mu, RandomNumberProvider rand) {
+        if (!Double.isFinite(mu) || Double.isNaN(size) || size <= 0 || mu < 0) {
+            return StatsUtil.mlError();
+        }
+        if (!Double.isFinite(size)) {
+            size = Double.MAX_VALUE / 2.;
+        }
+        return (mu == 0) ? 0 : RPois.rpois(rgamma.evaluate(size, mu / size, rand), rand);
+    }
+}
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
index 46566a17ff..ee2e08713a 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java
@@ -35,30 +35,29 @@ public final class RPois {
                     1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880.
     };
 
-    public static double rpois(double mu, RandomNumberProvider rand) {
-
-        /* These are static --- persistent between calls for same mu : */
-        // TODO: state variables
-        int l = 0;
-        int m = 0;
-        double b1;
-        double b2;
-        double c = 0;
-        double c0 = 0;
-        double c1 = 0;
-        double c2 = 0;
-        double c3 = 0;
-        double[] pp = new double[36];
-        double p0 = 0;
-        double p = 0;
-        double q = 0;
-        double s = 0;
-        double d = 0;
-        double omega = 0;
-        double bigL = 0; /* integer "w/o overflow" */
-        double muprev = 0.;
-        double muprev2 = 0.; /* , muold = 0. */
+    /* These are static --- persistent between calls for same mu : */
+    // TODO: state variables
+    static int l = 0;
+    static int m = 0;
+    static double b1;
+    static double b2;
+    static double c = 0;
+    static double c0 = 0;
+    static double c1 = 0;
+    static double c2 = 0;
+    static double c3 = 0;
+    static double[] pp = new double[36];
+    static double p0 = 0;
+    static double p = 0;
+    static double q = 0;
+    static double s = 0;
+    static double d = 0;
+    static double omega = 0;
+    static double bigL = 0; /* integer "w/o overflow" */
+    static double muprev = 0.;
+    static double muprev2 = 0.; /* , muold = 0. */
 
+    public static double rpois(double mu, RandomNumberProvider rand) {
         /* Local Vars [initialize some for -Wall]: */
         double del;
         double difmuk = 0.;
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 cd17d41445..8ea4edee78 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
@@ -58,6 +58,7 @@ 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.RLogis;
+import com.oracle.truffle.r.library.stats.RNbinomMu;
 import com.oracle.truffle.r.library.stats.RNchisq;
 import com.oracle.truffle.r.library.stats.RWeibull;
 import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory;
@@ -387,6 +388,8 @@ public class ForeignFunctions {
                     return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RWeibull());
                 case "rnchisq":
                     return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNchisq());
+                case "rnbinom_mu":
+                    return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new RNbinomMu());
                 case "qgamma":
                     return StatsFunctionsFactory.Function3_2NodeGen.create(new QgammaFunc());
                 case "dbinom":
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
new file mode 100644
index 0000000000..c8385786a2
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_rnbinom.java
@@ -0,0 +1,37 @@
+/*
+ * 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_rnbinom extends TestBase {
+    @Test
+    public void testRbinomWithMu() {
+        assertEval("set.seed(42); rnbinom(5, 1, mu=2)");
+        // TODO: maybe problem with state variables, see RNbinomMu
+        assertEval(Ignored.Unimplemented, "set.seed(42); rnbinom(100, c(-1, 0, 1, 0.8, 10, NA, NaN, 1/0, -1/0), mu=c(-1, 0, 1, 0.8, 3, 10, NA, NaN, 1/0, -1/0))");
+    }
+}
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 3d0c71c008..fb33bd32fe 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -59,6 +59,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java
 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/stats/RNbinomMu.java,gnu_r_ihaka_core.copyright
 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java,gnu_r_ihaka_core.copyright
 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
-- 
GitLab