diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java index a0b16fc81a7eb6224829d71d2c92de37e4e4e6b7..9623d02f48df1a4a32f7c56ef68e14e8dc8a2d21 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java @@ -36,10 +36,10 @@ import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_StatsFactory.ExecuteWorkNo import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLL; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; +import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; public class TruffleLLVM_Stats implements StatsRFFI { @@ -161,6 +161,13 @@ public class TruffleLLVM_Stats implements StatsRFFI { } } + private static class TruffleLLVM_LminflNode extends Node implements LminflNode { + @Override + public void execute(double[] x, int ldx, int n, int k, int docoef, double[] qraux, double[] resid, double[] hat, double[] coef, double[] sigma, double tol) { + throw RInternalError.unimplemented("lfmin for LLVM backend, lfmin is used in influence external."); + } + } + @Override public FactorNode createFactorNode() { return new Truffle_FactorNode(); @@ -170,4 +177,9 @@ public class TruffleLLVM_Stats implements StatsRFFI { public WorkNode createWorkNode() { return new Truffle_WorkNode(); } + + @Override + public LminflNode createLminflNode() { + return new TruffleLLVM_LminflNode(); + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java index 4461a0b77c65c16cb18ce72ef1951b46f2fe28ca..9a6e29a594f232ee0ddce8e3708a034c080c3e00 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java @@ -125,6 +125,11 @@ public final class Managed_RFFIFactory extends RFFIFactory { public WorkNode createWorkNode() { throw unsupported("work"); } + + @Override + public LminflNode createLminflNode() { + throw unsupported("lminfl"); + } }, new ToolsRFFI() { @Override public ParseRdNode createParseRdNode() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java index c9d3ac77c18113fd4f29473e198ad7fc4873a119..86a8ce5bf347346ffc3aaf48f0908e5a5a058d50 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java @@ -51,6 +51,18 @@ public class TruffleNFI_Stats implements StatsRFFI { } } + private static class TruffleNFI_LminflNode extends TruffleNFI_DownCallNode implements LminflNode { + @Override + protected NativeFunction getFunction() { + return NativeFunction.lminfl; + } + + @Override + public void execute(double[] x, int ldx, int n, int k, int docoef, double[] qraux, double[] resid, double[] hat, double[] coef, double[] sigma, double tol) { + call(x, ldx, n, k, docoef, qraux, resid, hat, coef, sigma, tol); + } + } + @Override public FactorNode createFactorNode() { return new TruffleNFI_FactorNode(); @@ -60,4 +72,9 @@ public class TruffleNFI_Stats implements StatsRFFI { public WorkNode createWorkNode() { return new TruffleNFI_WorkNode(); } + + @Override + public LminflNode createLminflNode() { + return new TruffleNFI_LminflNode(); + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Influence.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Influence.java new file mode 100644 index 0000000000000000000000000000000000000000..cad4aa2cc1cfbe81ec7e15a2f5394090d18a1b79 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Influence.java @@ -0,0 +1,121 @@ +/* + * 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) 2012, The R Core Team + * Copyright (c) 2017, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.UnaryCopyAttributesNode; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.casts.fluent.CastNodeBuilder; +import com.oracle.truffle.r.nodes.helpers.AccessListField; +import com.oracle.truffle.r.nodes.unary.CastNode; +import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDataFactory.VectorFactory; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData; +import com.oracle.truffle.r.runtime.ffi.StatsRFFI.LminflNode; + +public abstract class Influence extends RExternalBuiltinNode.Arg4 { + + static { + Casts casts = new Casts(Influence.class); + casts.arg(0).mustBe(RList.class); + casts.arg(1).asLogicalVector().findFirst().map(toBoolean()); + casts.arg(2).mustBe(doubleValue()).asDoubleVector(); + casts.arg(3).asDoubleVector().findFirst(); + } + + public static Influence create() { + return InfluenceNodeGen.create(); + } + + @CompilationFinal private RStringVector namesWithCoef; + @CompilationFinal private RStringVector names; + @Child private LminflNode lminflNode = LminflNode.create(); + + @Specialization + RList doInfluence(RList mqr, boolean doCoef, RAbstractDoubleVector resid, double tol, + @Cached("create()") GetDimAttributeNode getDimAttribute, + @Cached("create()") GetReadonlyData.Double getReadonlyData, + @Cached("create()") AccessListField accessQrField, + @Cached("create()") AccessListField accessQrauxField, + @Cached("create()") AccessListField accessRankField, + @Cached("create()") UnaryCopyAttributesNode copyResidAttrs, + @Cached("create()") VectorFactory vectorFactory, + @Cached("create()") VectorFactory resultVectorFactory, + @Cached("createIntScalarCast()") CastNode scalarIntCast) { + RAbstractDoubleVector qr = getDoubleField(mqr, accessQrField, "qr"); + RAbstractDoubleVector qraux = getDoubleField(mqr, accessQrauxField, "qraux"); + int n = getDimAttribute.nrows(qr); + int k = (int) scalarIntCast.doCast(accessRankField.execute(mqr, "rank")); + double[] hat = new double[n]; + double[] coefficients = doCoef ? new double[n * k] : new double[0]; + double[] sigma = new double[n]; + double[] residData = getReadonlyData.execute(resid.materialize()); + double[] qrData = getReadonlyData.execute(qr.materialize()); + double[] qrauxData = getReadonlyData.execute(qraux.materialize()); + // Note: it is OK to override data in "e" regardless of its sharing status, GNUR does it too + lminflNode.execute(qrData, n, n, k, doCoef ? 1 : 0, qrauxData, residData, hat, coefficients, sigma, tol); + for (int i = 0; i < n; i++) { + if (hat[i] > 1. - tol) { + hat[i] = 1.; + } + } + Object[] ans = new Object[doCoef ? 4 : 3]; + int idx = 0; + ans[idx++] = vectorFactory.createDoubleVector(hat, RDataFactory.COMPLETE_VECTOR); + if (doCoef) { + ans[idx++] = vectorFactory.createDoubleVector(coefficients, RDataFactory.COMPLETE_VECTOR, new int[]{n, k}); + } + ans[idx++] = vectorFactory.createDoubleVector(sigma, RDataFactory.COMPLETE_VECTOR); + RDoubleVector residResult = vectorFactory.createDoubleVector(residData, RDataFactory.COMPLETE_VECTOR); + copyResidAttrs.execute(residResult, resid); + ans[idx] = residResult; + return resultVectorFactory.createList(ans, getNames(doCoef)); + } + + protected static CastNode createIntScalarCast() { + return CastNodeBuilder.newCastBuilder().asIntegerVector().findFirst().buildCastNode(); + } + + private RStringVector getNames(boolean withCoef) { + if (withCoef) { + if (namesWithCoef == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + namesWithCoef = RDataFactory.getPermanent().createStringVector(new String[]{"hat", "coefficients", "sigma", "wt.res"}, RDataFactory.COMPLETE_VECTOR); + } + return namesWithCoef; + } + if (names == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + names = RDataFactory.getPermanent().createStringVector(new String[]{"hat", "sigma", "wt.res"}, RDataFactory.COMPLETE_VECTOR); + } + return names; + } + + private RAbstractDoubleVector getDoubleField(RList mqr, AccessListField access, String name) { + Object obj = access.execute(mqr, name); + if (!(obj instanceof RAbstractDoubleVector)) { + throw error(Message.INVALID_TYPE, "numeric", name, "numeric"); + } + return (RAbstractDoubleVector) obj; + } +} diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/stats/src/stats_rffi.c b/com.oracle.truffle.r.native/gnur/patch/src/library/stats/src/stats_rffi.c new file mode 100644 index 0000000000000000000000000000000000000000..39f30a900842d68fbc7cd58fbb9a22050bfb230a --- /dev/null +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/stats/src/stats_rffi.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* This file includes FastR specific wrappers for fortran functions from the stats package */ + + +void lminfl_(double *x, int *ldx, int *n, int *k, int *docoef, double *qraux, double *resid, + double *hat, double *coef, double *sigma, double *tol); + +void call_stats_lminfl(double *x, int ldx, int n, int k, int docoef, double *qraux, double *resid, + double *hat, double *coef, double *sigma, double tol) { + lminfl_(x, &ldx, &n, &k, &docoef, qraux, resid, hat, coef, sigma, &tol); +} + diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source index ea90ee31980757b2e469741512bcb39e73494e78..9e5feb5256930f3cae636754eef8a244ede164eb 100644 --- a/com.oracle.truffle.r.native/version.source +++ b/com.oracle.truffle.r.native/version.source @@ -1 +1 @@ -45 +46 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 97bdda9d9a8aa0ef9ce10ea25e39e47dfed0f6b1..20e64dfe9f310042948fe50412e51f71b74ae7ed 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 @@ -44,6 +44,7 @@ import com.oracle.truffle.r.library.stats.CompleteCases; import com.oracle.truffle.r.library.stats.CovcorNodeGen; import com.oracle.truffle.r.library.stats.CutreeNodeGen; import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen; +import com.oracle.truffle.r.library.stats.Influence; import com.oracle.truffle.r.library.stats.PPSum; import com.oracle.truffle.r.library.stats.RMultinomNode; import com.oracle.truffle.r.library.stats.RandFunctionsNodes; @@ -521,6 +522,8 @@ public class CallAndExternalFunctions { return CutreeNodeGen.create(); case "BinDist": return BinDist.create(); + case "influence": + return Influence.create(); case "isoreg": case "monoFC_m": case "numeric_deriv": @@ -566,7 +569,6 @@ public class CallAndExternalFunctions { case "Rsm": case "tukeyline": case "runmed": - case "influence": case "pSmirnov2x": case "pKolmogorov2x": case "pKS2": diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java index cdccb88e21d9dcf5333184494b6e1e0fb73bdac3..2459063d8d409da5b067fb0ca9a7b8e6d5d60c18 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java @@ -76,6 +76,7 @@ public enum NativeFunction { // stats fft_factor("(sint32, [sint32], [sint32]): void", "", "stats"), fft_work("([double], sint32, sint32, sint32, sint32, [double], [sint32]): sint32", "", "stats"), + lminfl("([double], sint32, sint32, sint32, sint32, [double], [double], [double], [double], [double], double): void", "call_stats_", "stats"), // FastR helpers set_exception_flag("(): void"), // user-defined RNG diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java index 5fc727da587d79245183abee162095104739d644..5fcbb0417f429677b0e2d52588462c62b953a8db 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java @@ -46,8 +46,17 @@ public interface StatsRFFI { } } + interface LminflNode extends NodeInterface { + void execute(double[] x, int ldx, int n, int k, int docoef, double[] qraux, double[] resid, double[] hat, double[] coef, double[] sigma, double tol); + + static LminflNode create() { + return RFFIFactory.getStatsRFFI().createLminflNode(); + } + } + FactorNode createFactorNode(); WorkNode createWorkNode(); + LminflNode createLminflNode(); } 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 43c0b9d92097f032b88e765bc27b963ab8898277..dbd0accdaac4128efde9e05b950f06661f49541f 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 @@ -159533,6 +159533,40 @@ Error: 'x' is NULL #.Call(stats:::C_cov, c('1','2','3','4','5'), 1:5, 4, FALSE) [1] 2.5 +##com.oracle.truffle.r.test.library.stats.TestExternal_influence.testInfluence# +#lm.influence(lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings[1:10,])) +$hat + Australia Austria Belgium Bolivia Brazil Canada Chile + 0.3737868 0.5896671 0.4573853 0.6751949 0.3594008 0.7094555 0.3635687 + China Colombia Costa Rica + 0.6197947 0.3083626 0.5433837 + +$coefficients + (Intercept) pop15 pop75 dpi ddpi +Australia 8.97151391 -0.1675404625 -1.09588438 3.404872e-04 -0.14354355 +Austria -0.23114405 0.0068984905 -0.06573352 1.002458e-04 -0.01380218 +Belgium -0.09597747 0.0015323497 0.01702356 -3.281366e-07 0.00269680 +Bolivia 16.27309105 -0.2181784568 -0.80056737 -1.699963e-03 -1.13657588 +Brazil 17.27353239 -0.3205150165 -2.30144312 -2.423851e-04 0.12719601 +Canada 9.32211441 -0.1901400954 -0.27147576 -2.155664e-03 0.08411897 +Chile -36.32966200 0.6442739385 3.76036825 1.353012e-03 0.60529206 +China 0.10948533 0.0002053262 0.03214020 2.055369e-05 -0.08291478 +Colombia 12.45441319 -0.2628336324 -1.31059668 -1.173403e-04 -0.07712777 +Costa Rica -22.04228903 0.4475455100 2.22992704 6.390793e-04 0.12477654 + +$sigma + Australia Austria Belgium Bolivia Brazil Canada Chile + 4.119867 4.338004 4.340310 3.738430 3.548807 4.105360 2.590317 + China Colombia Costa Rica + 4.335941 3.865813 4.059223 + +$wt.res + Australia Austria Belgium Bolivia Brazil Canada + 2.16161662 -0.18317364 0.03027155 2.51354855 4.00016991 -1.51875342 + Chile China Colombia Costa Rica +-5.55671071 -0.24145935 -3.28230239 2.07679287 + + ##com.oracle.truffle.r.test.library.stats.TestExternal_qgamma.testQgamma# #qgamma(0, 1) [1] 0 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_influence.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_influence.java new file mode 100644 index 0000000000000000000000000000000000000000..dc0b5a5065d9b8409779b18347f2a17e4b5d3b15 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_influence.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017, 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_influence extends TestBase { + @Test + public void testInfluence() { + assertEval("lm.influence(lm(sr ~ pop15 + pop75 + dpi + ddpi, data = LifeCycleSavings[1:10,]))"); + } +} diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 2fc42967eda91aaf0c1f6f4016805c22820b5a71..5b02a6c5934344ce3cd83627d3a87cf9a4284de7 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -40,6 +40,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/BinDist.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Influence.java,gnu_r.core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java,gnu_r.copyright