From ae1fe67595dae2d32ba7a16b1d75f44c8cc79d02 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Mon, 27 Nov 2017 09:44:37 +0100
Subject: [PATCH] Implement 'influence' external from stats package

---
 .../r/ffi/impl/llvm/TruffleLLVM_Stats.java    |  14 +-
 .../ffi/impl/managed/Managed_RFFIFactory.java |   5 +
 .../r/ffi/impl/nfi/TruffleNFI_Stats.java      |  17 +++
 .../truffle/r/library/stats/Influence.java    | 121 ++++++++++++++++++
 .../patch/src/library/stats/src/stats_rffi.c  |  34 +++++
 com.oracle.truffle.r.native/version.source    |   2 +-
 .../foreign/CallAndExternalFunctions.java     |   4 +-
 .../truffle/r/runtime/ffi/NativeFunction.java |   1 +
 .../truffle/r/runtime/ffi/StatsRFFI.java      |   9 ++
 .../truffle/r/test/ExpectedTestOutput.test    |  34 +++++
 .../library/stats/TestExternal_influence.java |  35 +++++
 mx.fastr/copyrights/overrides                 |   1 +
 12 files changed, 274 insertions(+), 3 deletions(-)
 create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Influence.java
 create mode 100644 com.oracle.truffle.r.native/gnur/patch/src/library/stats/src/stats_rffi.c
 create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_influence.java

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 a0b16fc81a..9623d02f48 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 4461a0b77c..9a6e29a594 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 c9d3ac77c1..86a8ce5bf3 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 0000000000..cad4aa2cc1
--- /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 0000000000..39f30a9008
--- /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 ea90ee3198..9e5feb5256 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 97bdda9d9a..20e64dfe9f 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 cdccb88e21..2459063d8d 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 5fc727da58..5fcbb0417f 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 43c0b9d920..dbd0accdaa 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 0000000000..dc0b5a5065
--- /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 2fc42967ed..5b02a6c593 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
-- 
GitLab