diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java new file mode 100644 index 0000000000000000000000000000000000000000..45328c469331798c9b31b771a18ccb2fa49c477d --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Logis.java @@ -0,0 +1,137 @@ +/* + * 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. + */ +/* + * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka + * Copyright (C) 2000 The R Core Team + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2; + +public final class Logis { + private Logis() { + // only static members + } + + public static final class DLogis implements Function3_1 { + @Override + public double evaluate(double x, double location, double scale, boolean giveLog) { + if (Double.isNaN(x) || Double.isNaN(location) || Double.isNaN(scale)) { + return x + location + scale; + } + if (scale <= 0.0) { + return RMath.mlError(); + } + + x = TOMS708.fabs((x - location) / scale); + double e = Math.exp(-x); + double f = 1.0 + e; + return giveLog ? -(x + Math.log(scale * f * f)) : e / (scale * f * f); + } + } + + public static final class QLogis implements Function3_2 { + @Override + public double evaluate(double p, double location, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(p) || Double.isNaN(location) || Double.isNaN(scale)) { + return p + location + scale; + } + + try { + DPQ.rqp01boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP); + } catch (EarlyReturn e) { + return e.result; + } + + if (scale < 0.) { + return RMath.mlError(); + } + if (scale == 0.) { + return location; + } + + /* p := logit(p) = Math.log( p / (1-p) ) : */ + if (logP) { + if (lowerTail) { + p = p - DPQ.rlog1exp(p); + } else { + p = DPQ.rlog1exp(p) - p; + } + } else { + p = Math.log(lowerTail ? (p / (1. - p)) : ((1. - p) / p)); + } + + return location + scale * p; + } + } + + public static final class PLogis implements Function3_2 { + @Override + public double evaluate(double x, double location, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(x) || Double.isNaN(location) || Double.isNaN(scale)) { + return x + location + scale; + } + if (scale <= 0.0) { + return RMath.mlError(); + } + + x = (x - location) / scale; + if (Double.isNaN(x)) { + return RMath.mlError(); + } + + try { + DPQ.rpboundsinf01(x, lowerTail, logP); + } catch (EarlyReturn earlyReturn) { + return earlyReturn.result; + } + + if (logP) { + // Math.log(1 / (1 + Math.exp( +- x ))) = -Math.log(1 + Math.exp( +- x)) + return -log1pexp(lowerTail ? -x : x); + } else { + return 1 / (1 + Math.exp(lowerTail ? -x : x)); + } + } + + private static double log1pexp(double x) { + if (x <= 18.) { + return RMath.log1p(Math.exp(x)); + } + if (x > 33.3) { + return x; + } + // else: 18.0 < x <= 33.3 : + return x + Math.exp(-x); + } + } + + public static final class RLogis extends RandFunction2_Double { + @Override + public double execute(double location, double scale, RandomNumberProvider rand) { + if (Double.isNaN(location) || !Double.isFinite(scale)) { + return RMath.mlError(); + } + + if (scale == 0. || !Double.isFinite(location)) { + return location; + } else { + double u = rand.unifRand(); + return location + scale * Math.log(u / (1. - u)); + } + } + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index 2c2f2c79834c75d9fd5ed6fdf84c491fd066a0ee..001e0440002ff3c513dbe4e066a3ec45cfaa76e5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java @@ -68,6 +68,9 @@ import com.oracle.truffle.r.library.stats.LogNormal; import com.oracle.truffle.r.library.stats.LogNormal.DLNorm; import com.oracle.truffle.r.library.stats.LogNormal.PLNorm; import com.oracle.truffle.r.library.stats.LogNormal.QLNorm; +import com.oracle.truffle.r.library.stats.Logis; +import com.oracle.truffle.r.library.stats.Logis.DLogis; +import com.oracle.truffle.r.library.stats.Logis.RLogis; import com.oracle.truffle.r.library.stats.Pbeta; import com.oracle.truffle.r.library.stats.Pbinom; import com.oracle.truffle.r.library.stats.Pf; @@ -78,7 +81,6 @@ import com.oracle.truffle.r.library.stats.RBeta; import com.oracle.truffle.r.library.stats.RChisq; import com.oracle.truffle.r.library.stats.RGamma; import com.oracle.truffle.r.library.stats.RHyper; -import com.oracle.truffle.r.library.stats.RLogis; import com.oracle.truffle.r.library.stats.RMultinomNodeGen; import com.oracle.truffle.r.library.stats.RNbinomMu; import com.oracle.truffle.r.library.stats.RNchisq; @@ -338,6 +340,12 @@ public class CallAndExternalFunctions { return StatsFunctionsFactory.Function3_2NodeGen.create(new QLNorm()); case "plnorm": return StatsFunctionsFactory.Function3_2NodeGen.create(new PLNorm()); + case "dlogis": + return StatsFunctionsFactory.Function3_1NodeGen.create(new DLogis()); + case "qlogis": + return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.QLogis()); + case "plogis": + return StatsFunctionsFactory.Function3_2NodeGen.create(new Logis.PLogis()); case "rmultinom": return RMultinomNodeGen.create(); case "Approx": diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 0467373d319614885a7468b7ad3c4ddd3c190853..1c597c2f2f1ae8c7bb469cf56adab4d268d55181 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -68,7 +68,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java,g 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/Logis.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 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java,gnu_r_ihaka_core.copyright