From d1c834c664f2e5cb9b4bdd30b8326d785c44f922 Mon Sep 17 00:00:00 2001
From: stepan <stepan.sindelar@oracle.com>
Date: Tue, 7 Jun 2016 14:00:30 +0200
Subject: [PATCH] Implement Cdqrls external used in lm

Cdqrls is implemented as R function, which invokes .fastr.dqrls,
which is invokes Fortran routine dqrls through RFFI.
---
 .../com/oracle/truffle/r/library/stats/lm.R   |  63 ++
 .../r/nodes/builtin/base/BasePackage.java     |   3 +
 .../base/foreign/ForeignFunctions.java        |   4 +-
 .../r/nodes/builtin/fastr/FastrDqrls.java     | 102 +++
 .../truffle/r/runtime/ffi/jnr/JNR_RAppl.java  |   8 +
 .../truffle/r/runtime/ffi/RApplRFFI.java      |   4 +-
 .../truffle/r/test/ExpectedTestOutput.test    | 796 ++++++++++++++++++
 .../r/test/library/stats/TestFitting.java     |  53 ++
 mx.fastr/copyrights/overrides                 |   1 +
 9 files changed, 1032 insertions(+), 2 deletions(-)
 create mode 100644 com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/lm.R
 create mode 100644 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
 create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java

diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/lm.R b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/lm.R
new file mode 100644
index 0000000000..a86b2870b6
--- /dev/null
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/lm.R
@@ -0,0 +1,63 @@
+#
+# 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) 1995, 1996  Robert Gentleman and Ross Ihaka
+# Copyright (c) 1997-2013,  The R Core Team
+# Copyright (c) 2016, Oracle and/or its affiliates
+#
+# All rights reserved.
+#
+
+#
+# This file defines FastR counterparts of C function Cdqrls defined in lm.c in GnuR
+# This functions are called using .Call. See model.R for details
+#
+
+Cdqrls <- function(x, y, tol, check) {
+    ans <- dim(x)
+    if (check && length(ans) != 2) {
+        error("'x' is not a matrix")
+    }
+    n <- ans[[1]]
+    p <- ans[[2]]
+    ny <- if (n != 0L) ny <- length(y)%/%n else 0L;
+    
+    if (check && n * ny != length(y)) {
+        error(paste0("dimensions of 'x' (",n ,"," ,p , ") and 'y' (", length(y), ") do not match"));
+    }
+    
+    if (any(!is.finite(x))) {
+        error("NA/NaN/Inf in 'x'")
+    }
+    if (any(!is.finite(y))) {
+        error("NA/NaN/Inf in 'y'")
+    }
+    
+    # GnuR allocates memory, assigns it to a list that will be later returned and with 
+    # this allocated memory it invokes Fortran code to actually fill it in with useful 
+    # data. We do not have to pre-allocate, so we just invoke Fortran
+    coeff <- mat.or.vec(p, ny)
+    storage.mode(coeff) <- 'double'
+    storage.mode(tol) <- 'double'
+    
+    # in the call to dqrls we omit pointers to preallocated memory that does not 
+    # hold any actual input data. These are allocated in Java wrapper for _fastr_dqrls
+    # GnuR constucts resulting list from the pointers passed to Fortran, here we 
+    # expect the Java wrapper to construct and return such list (i.e. the wrapper does 
+    # some work that in GnuR is done here in Cdqrls)
+    result <- .fastr.dqrls(x, n, p, y, ny, tol, coeff)
+    
+    result$pivoted <- 0
+    for (i in 1:p) {
+        if (result$pivot[i] != i) {
+            result$pivoted <- 1
+            break
+        }
+    }
+    
+    result
+}
+
+
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index 8c8491b75a..33d0b9b0a2 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -72,6 +72,8 @@ import com.oracle.truffle.r.nodes.builtin.fastr.FastRTree;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeNodeGen;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeStats;
 import com.oracle.truffle.r.nodes.builtin.fastr.FastRTreeStatsNodeGen;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrls;
+import com.oracle.truffle.r.nodes.builtin.fastr.FastrDqrlsNodeGen;
 import com.oracle.truffle.r.nodes.unary.UnaryNotNode;
 import com.oracle.truffle.r.nodes.unary.UnaryNotNodeGen;
 import com.oracle.truffle.r.runtime.RBuiltin;
@@ -288,6 +290,7 @@ public class BasePackage extends RBuiltinPackage {
         add(FastRContext.ChannelSend.class, FastRContextFactory.ChannelSendNodeGen::create);
         add(FastRContext.Spawn.class, FastRContextFactory.SpawnNodeGen::create);
         add(FastRContext.Join.class, FastRContextFactory.JoinNodeGen::create);
+        add(FastrDqrls.class, FastrDqrlsNodeGen::create);
         add(FastRDebug.class, FastRDebugNodeGen::create);
         add(FastRFunctionTimer.CreateFunctionTimer.class, FastRFunctionTimerFactory.CreateFunctionTimerNodeGen::create);
         add(FastRFunctionTimer.GetFunctionTimer.class, FastRFunctionTimerFactory.GetFunctionTimerNodeGen::create);
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 ac398b4806..78519371a7 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
@@ -397,7 +397,6 @@ public class ForeignFunctions {
                 case "logit_mu_eta":
                 case "binomial_dev_resids":
                 case "rWishart":
-                case "Cdqrls":
                 case "Cdist":
                 case "updateform":
                 case "mvfft":
@@ -441,6 +440,9 @@ public class ForeignFunctions {
                 case "d2x2xk":
                     return new UnimplementedExternal(name);
 
+                case "Cdqrls":
+                    return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(StatsUtil.class, "lm.R"), "Cdqrls");
+
                 // tools
                 case "doTabExpand":
                     return DoTabExpandNodeGen.create();
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
new file mode 100644
index 0000000000..4b630fc910
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java
@@ -0,0 +1,102 @@
+/*
+ * 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) 1995-2012, The R Core Team
+ * Copyright (c) 2003, The R Foundation
+ * Copyright (c) 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.nodes.builtin.fastr;
+
+import java.util.Arrays;
+
+import com.oracle.truffle.api.dsl.Cached;
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.nodes.unary.CastDoubleNode;
+import com.oracle.truffle.r.runtime.RBuiltin;
+import com.oracle.truffle.r.runtime.RBuiltinKind;
+import com.oracle.truffle.r.runtime.RVisibility;
+import com.oracle.truffle.r.runtime.data.RAttributeProfiles;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+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.model.RAbstractVector;
+import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
+
+/**
+ * FastR specific internal used in R code of Cdqrls, which is in GunR implemented in C and invokes
+ * directly this Fortran routine.
+ */
+@RBuiltin(name = ".fastr.dqrls", visibility = RVisibility.OFF, kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x", "n", "p", "y", "ny", "tol", "coeff"})
+public abstract class FastrDqrls extends RBuiltinNode {
+
+    private static final String[] NAMES = new String[]{"qr", "coefficients", "residuals", "effects", "rank", "pivot", "qraux", "tol", "pivoted"};
+    private static RStringVector namesVector = null;
+
+    private final RAttributeProfiles coeffAttributeProfiles = RAttributeProfiles.create();
+    private final RAttributeProfiles xAttributeProfiles = RAttributeProfiles.create();
+    private final RAttributeProfiles residualsAttributesProfiles = RAttributeProfiles.create();
+
+    @Specialization
+    public RList doDouble(RAbstractDoubleVector xVec, int n, int p, RAbstractDoubleVector yVec, int ny, double tol, RAbstractDoubleVector coeffVec) {
+        return call(xVec, xVec.materialize(), n, p, yVec, yVec.materialize(), ny, tol, coeffVec);
+    }
+
+    @Specialization(contains = "doDouble")
+    public RList doOther(RAbstractVector xVec, int n, int p, RAbstractVector yVec, int ny, double tol, RAbstractDoubleVector coeffVec, @Cached(value = "create()") CastDoubleNode castNode) {
+        return call(xVec, ((RAbstractDoubleVector) castNode.execute(xVec)).materialize(), n, p, yVec, ((RAbstractDoubleVector) castNode.execute(yVec)).materialize(), ny, tol, coeffVec);
+    }
+
+    private RList call(RAbstractVector originalXVec, RDoubleVector xVec, int n, int p, RAbstractVector originalYVec, RDoubleVector yVec, int ny, double tol, RAbstractDoubleVector coeffVec) {
+        double[] x = xVec.getDataTemp();
+        double[] y = yVec.getDataTemp();
+        double[] coeff = coeffVec.materialize().getDataTemp();
+        double[] residuals = Arrays.copyOf(y, y.length);
+        double[] effects = Arrays.copyOf(y, y.length);
+        double[] qraux = new double[p];
+        double[] work = new double[2 * p];
+        int[] rank = new int[]{0};
+        int[] pivot = new int[p];
+        for (int i = 0; i < p; ++i) {
+            pivot[i] = i + 1;
+        }
+
+        RFFIFactory.getRFFI().getRApplRFFI().dqrls(x, n, p, y, ny, tol, coeff, residuals, effects, rank, pivot, qraux, work);
+
+        RDoubleVector resultCoeffVect = RDataFactory.createDoubleVector(coeff, RDataFactory.COMPLETE_VECTOR);
+        resultCoeffVect.copyAttributesFrom(coeffAttributeProfiles, coeffVec);
+
+        RDoubleVector resultX = RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR);
+        resultX.copyAttributesFrom(xAttributeProfiles, originalXVec);
+
+        RDoubleVector resultResiduals = RDataFactory.createDoubleVector(residuals, RDataFactory.COMPLETE_VECTOR);
+        resultResiduals.copyAttributesFrom(residualsAttributesProfiles, originalYVec);
+
+        Object[] data = new Object[]{
+                        resultX,
+                        resultCoeffVect,
+                        resultResiduals,
+                        RDataFactory.createDoubleVector(effects, RDataFactory.COMPLETE_VECTOR),
+                        RDataFactory.createIntVectorFromScalar(rank[0]),
+                        RDataFactory.createIntVector(pivot, RDataFactory.COMPLETE_VECTOR),
+                        RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR),
+                        tol,
+                        RDataFactory.createIntVectorFromScalar(0) // pivoted
+        };
+
+        return RDataFactory.createList(data, getNamesVector());
+    }
+
+    private static RStringVector getNamesVector() {
+        if (namesVector == null) {
+            namesVector = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR);
+        }
+        return namesVector;
+    }
+}
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
index 09424d1f1c..cb965845d2 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java
@@ -38,6 +38,8 @@ public class JNR_RAppl implements RApplRFFI {
         void dqrdc2_(double[] x, @In int[] ldx, @In int[] n, @In int[] p, @In double[] tol, int[] rank, double[] qraux, int[] pivot, @Out double[] work);
 
         void dqrcf_(double[] x, @In int[] n, @In int[] k, double[] qraux, double[] y, @In int[] ny, double[] b, int[] info);
+
+        void dqrls_(double[] x, int[] n, int[] p, double[] y, int[] ny, double[] tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work);
     }
 
     private static class LinpackProvider {
@@ -72,4 +74,10 @@ public class JNR_RAppl implements RApplRFFI {
     public void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info) {
         linpack().dqrcf_(x, wrapInt(n), wrapInt(k), qraux, y, wrapInt(ny), b, info);
     }
+
+    @Override
+    @TruffleBoundary
+    public void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) {
+        linpack().dqrls_(x, wrapInt(n), wrapInt(p), y, wrapInt(ny), wrapDouble(tol), b, rsd, qty, k, jpvt, qraux, work);
+    }
 }
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java
index 6d58cbc1ea..4f20c85d9b 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -33,4 +33,6 @@ public interface RApplRFFI {
 
     void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info);
 
+    void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work);
+
 }
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 658617f4ef..aed899f40e 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
@@ -106394,6 +106394,802 @@ a b c d e
 #if (length(grep("FastR", R.Version()$version.string)) != 1) { TRUE } else { x<-rep(1, 100); xi1<-fastr.identity(x); f<-function(x) { y<-x; y }; f(x); x[1]<-7; xi2<-fastr.identity(x); xi1 == xi2 }
 [1] TRUE
 
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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
+-2.131628e-14  1.000000e+00
+     1      2      3      4      5      6      7      8      9     10     11
+26.550 37.210 57.280 90.820 20.160 89.838 94.460 20.500 17.600 68.700 38.410
+    12     13     14     15     16
+76.900 49.700 71.000 99.190 16.000
+named list()
+            1             2             3             4             5
+ 1.287943e-14 -3.785953e-14  1.614388e-15  1.485485e-15  4.172133e-15
+            6             7             8             9            10
+ 1.177205e-15  2.628193e-15  4.278870e-15  3.368471e-15  1.646764e-15
+           11            12            13            14            15
+ 2.795942e-15  6.682822e-16  2.454440e-15  2.368804e-15 -2.992342e-15
+           16
+-6.865322e-16
+[1] 0 1
+  (Intercept)             x
+-2.185795e+02  1.169877e+02 -3.552714e-15 -1.421085e-14  1.065814e-14
+
+-1.421085e-14 -1.421085e-14  1.065814e-14  1.065814e-14 -7.105427e-15
+
+ 3.552714e-15 -1.065814e-14 -3.330669e-16 -7.105427e-15 -2.131628e-14
+
+ 7.105427e-15
+   (Intercept)             x
+1        -4.00 -2.185795e+02
+2         0.25  1.169877e+02
+3         0.25 -7.055527e-02
+4         0.25 -3.572520e-01
+5         0.25  2.467430e-01
+6         0.25 -3.488580e-01
+7         0.25 -3.883664e-01
+8         0.25  2.438367e-01
+9         0.25  2.686256e-01
+10        0.25 -1.681723e-01
+11        0.25  9.074371e-02
+12        0.25 -2.382652e-01
+13        0.25 -5.762143e-03
+14        0.25 -1.878325e-01
+15        0.25 -4.287980e-01
+16        0.25  2.823023e-01
+attr(,"assign")
+[1] 0 1
+[1] 2
+        y      x
+1  26.550 26.550
+2  37.210 37.210
+3  57.280 57.280
+4  90.820 90.820
+5  20.160 20.160
+6  89.838 89.838
+7  94.460 94.460
+8  20.500 20.500
+9  17.600 17.600
+10 68.700 68.700
+11 38.410 38.410
+12 76.900 76.900
+13 49.700 49.700
+14 71.000 71.000
+15 99.190 99.190
+16 16.000 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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); z <- 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:z)^3); 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:z
+21.53296234  0.00861965
+        1         2         3         4         5         6         7         8
+ 27.60897  33.46759  49.81402  92.63018  25.03621  91.10100  98.44344  25.15537
+        9        10        11        12        13        14        15        16
+ 24.20299  62.21504  34.24977  72.50621  42.82427  64.98462 106.33873  23.73959
+named list()
+        1         2         3         4         5         6         7         8
+-1.058975  3.742408  7.465981 -1.810180 -4.876209 -1.263002 -3.983438 -4.655370
+        9        10        11        12        13        14        15        16
+-6.602985  6.484964  4.160226  4.393791  6.875727  6.015384 -7.148731 -7.739593
+[1] 0 1
+ (Intercept)          x:z
+-218.5795000  115.0318937    7.6951986   -0.2866112   -5.3960354    0.2143399
+
+  -2.2841310   -5.1715946   -7.1480005    7.0890693    3.9189298    5.3090040
+
+   6.8936417    6.7032154   -5.2107459   -8.2986167
+   (Intercept)           x:z
+1        -4.00 -1.536578e+04
+2         0.25  1.334531e+04
+3         0.25 -5.010123e-03
+4         0.25 -3.772213e-01
+5         0.25  2.103894e-01
+6         0.25 -3.639278e-01
+7         0.25 -4.277574e-01
+8         0.25  2.093535e-01
+9         0.25  2.176328e-01
+10        0.25 -1.128152e-01
+11        0.25  1.302936e-01
+12        0.25 -2.022788e-01
+13        0.25  5.575343e-02
+14        0.25 -1.368918e-01
+15        0.25 -4.963931e-01
+16        0.25  2.216612e-01
+attr(,"assign")
+[1] 0 1
+[1] 2
+        y      x      z
+1  26.550 26.550 26.550
+2  37.210 37.210 37.210
+3  57.280 57.280 57.280
+4  90.820 90.820 90.820
+5  20.160 20.160 20.160
+6  89.838 89.838 89.838
+7  94.460 94.460 94.460
+8  20.500 20.500 20.500
+9  17.600 17.600 17.600
+10 68.700 68.700 68.700
+11 38.410 38.410 38.410
+12 76.900 76.900 76.900
+13 49.700 49.700 49.700
+14 71.000 71.000 71.000
+15 99.190 99.190 99.190
+16 16.000 16.000 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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); z <- 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*z); 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             z           x:z
+-2.131628e-14  1.000000e+00            NA  2.698309e-18
+     1      2      3      4      5      6      7      8      9     10     11
+26.550 37.210 57.280 90.820 20.160 89.838 94.460 20.500 17.600 68.700 38.410
+    12     13     14     15     16
+76.900 49.700 71.000 99.190 16.000
+named list()
+            1             2             3             4             5
+ 1.283954e-14 -3.650704e-14  3.924200e-15  5.433426e-16  3.003613e-15
+            6             7             8             9            10
+ 4.165451e-16  9.679492e-16  3.175953e-15  1.685969e-15  3.530942e-15
+           11            12            13            14            15
+ 4.266776e-15  1.812724e-15  4.658154e-15  4.082112e-15 -5.692549e-15
+           16
+-2.708232e-15
+[1] 0 1 2 3
+  (Intercept)             x           x:z
+-2.185795e+02  1.169877e+02  6.557040e-15 -1.476667e-14  9.005033e-15
+
+-1.457365e-14 -1.553337e-14  9.083088e-15  8.394724e-15 -4.736529e-15
+
+ 5.094424e-15 -9.026011e-15  2.169903e-15 -4.901878e-15 -2.375559e-14
+
+ 4.440308e-15
+   (Intercept)             x           x:z             z
+1        -4.00 -2.185795e+02 -1.536578e+04 -2.185795e+02
+2         0.25  1.169877e+02  1.312220e+04  1.169877e+02
+3         0.25 -7.055527e-02  2.430055e+03  6.557040e-15
+4         0.25 -3.572520e-01 -7.514340e-02  4.060091e-14
+5         0.25  2.467430e-01 -2.234902e-01 -2.217939e-01
+6         0.25 -3.488580e-01 -4.904776e-02  3.589489e-01
+7         0.25 -3.883664e-01 -1.787960e-01  3.825867e-01
+8         0.25  2.438367e-01 -2.129376e-01 -2.237164e-01
+9         0.25  2.686256e-01 -3.060002e-01 -2.067620e-01
+10        0.25 -1.681723e-01  3.202606e-01  1.166607e-01
+11        0.25  9.074371e-02  2.084299e-01 -1.254756e-01
+12        0.25 -2.382652e-01  2.206541e-01  2.223106e-01
+13        0.25 -5.762143e-03  3.383863e-01 -5.344469e-02
+14        0.25 -1.878325e-01  2.979065e-01  1.207332e-01
+15        0.25 -4.287980e-01 -3.297793e-01  5.850999e-01
+16        0.25  2.823023e-01 -3.603079e-01 -1.093647e-01
+attr(,"assign")
+[1] 0 1 2 3
+[1] 3
+        y      x      z
+1  26.550 26.550 26.550
+2  37.210 37.210 37.210
+3  57.280 57.280 57.280
+4  90.820 90.820 90.820
+5  20.160 20.160 20.160
+6  89.838 89.838 89.838
+7  94.460 94.460 94.460
+8  20.500 20.500 20.500
+9  17.600 17.600 17.600
+10 68.700 68.700 68.700
+11 38.410 38.410 38.410
+12 76.900 76.900 76.900
+13 49.700 49.700 49.700
+14 71.000 71.000 71.000
+15 99.190 99.190 99.190
+16 16.000 16.000 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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(rep(1,8), rep(2,8)); 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
+   54.51700     0.08525
+       1        2        3        4        5        6        7        8
+54.60225 54.60225 54.60225 54.60225 54.60225 54.60225 54.60225 54.60225
+       9       10       11       12       13       14       15       16
+54.68750 54.68750 54.68750 54.68750 54.68750 54.68750 54.68750 54.68750
+named list()
+        1         2         3         4         5         6         7         8
+-28.05225 -17.39225   2.67775  36.21775 -34.44225  35.23575  39.85775 -34.10225
+        9        10        11        12        13        14        15        16
+-37.08750  14.01250 -16.27750  22.21250  -4.98750  16.31250  44.50250 -38.68750
+[1] 0 1
+(Intercept)           x
+ -218.57950     0.17050    10.25183    43.79183   -26.86817    42.80983
+
+   47.43183   -26.52817   -34.42250    16.67750   -13.61250    24.87750
+
+   -2.32250    18.97750    47.16750   -36.02250
+   (Intercept)    x
+1        -4.00 -6.0
+2         0.25  2.0
+3         0.25  0.2
+4         0.25  0.2
+5         0.25  0.2
+6         0.25  0.2
+7         0.25  0.2
+8         0.25  0.2
+9         0.25 -0.3
+10        0.25 -0.3
+11        0.25 -0.3
+12        0.25 -0.3
+13        0.25 -0.3
+14        0.25 -0.3
+15        0.25 -0.3
+16        0.25 -0.3
+attr(,"assign")
+[1] 0 1
+[1] 2
+        y x
+1  26.550 1
+2  37.210 1
+3  57.280 1
+4  90.820 1
+5  20.160 1
+6  89.838 1
+7  94.460 1
+8  20.500 1
+9  17.600 2
+10 68.700 2
+11 38.410 2
+12 76.900 2
+13 49.700 2
+14 71.000 2
+15 99.190 2
+16 16.000 2
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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(rep(1,8), rep(2,8)); z <- 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:z)^3); 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:z
+ 17.7285363   0.4502617
+        1         2         3         4         5         6         7         8
+ 29.68298  34.48277  43.51953  58.62131  26.80581  58.17915  60.26026  26.95890
+        9        10        11        12        13        14        15        16
+ 33.57775  79.59450  52.31764  86.97879  62.48455  81.66570 107.05145  32.13691
+named list()
+         1          2          3          4          5          6          7
+ -3.132985   2.727225  13.760473  32.198695  -6.645812  31.658852  34.199742
+         8          9         10         11         12         13         14
+ -6.458901 -15.977749 -10.894496 -13.907641 -10.078788 -12.784551 -10.665700
+        15         16
+ -7.861455 -16.136911
+[1] 0 1
+(Intercept)         x:z
+-218.579500   94.427700   14.199393   33.099749   -6.718353   32.546375
+
+  35.150950   -6.526758  -15.843060   -9.351635  -13.199487   -8.309958
+
+ -11.765276   -9.059457   -5.478376  -16.046314
+   (Intercept)           x:z
+1        -4.00 -327.95450000
+2         0.25  209.71736593
+3         0.25    0.06494884
+4         0.25   -0.09498069
+5         0.25    0.24194897
+6         0.25   -0.09029820
+7         0.25   -0.11233738
+8         0.25    0.24032774
+9         0.25    0.17023340
+10        0.25   -0.31708914
+11        0.25   -0.02822418
+12        0.25   -0.39528963
+13        0.25   -0.13589290
+14        0.25   -0.33902343
+15        0.25   -0.60786144
+16        0.25    0.18549203
+attr(,"assign")
+[1] 0 1
+[1] 2
+        y x      z
+1  26.550 1 26.550
+2  37.210 1 37.210
+3  57.280 1 57.280
+4  90.820 1 90.820
+5  20.160 1 20.160
+6  89.838 1 89.838
+7  94.460 1 94.460
+8  20.500 1 20.500
+9  17.600 2 17.600
+10 68.700 2 68.700
+11 38.410 2 38.410
+12 76.900 2 76.900
+13 49.700 2 49.700
+14 71.000 2 71.000
+15 99.190 2 99.190
+16 16.000 2 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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(rep(1,8), rep(2,8)); z <- 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*z); 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             z           x:z
+-1.087325e-14  2.511880e-15  1.000000e+00 -4.623971e-17
+     1      2      3      4      5      6      7      8      9     10     11
+26.550 37.210 57.280 90.820 20.160 89.838 94.460 20.500 17.600 68.700 38.410
+    12     13     14     15     16
+76.900 49.700 71.000 99.190 16.000
+named list()
+            1             2             3             4             5
+-2.881831e-15 -8.105285e-16  2.665156e-15 -3.159127e-16  2.753576e-15
+            6             7             8             9            10
+-3.226284e-16 -2.910197e-16 -7.968121e-16  4.637280e-15  2.441613e-16
+           11            12            13            14            15
+-1.363585e-15  6.794045e-16 -3.202399e-16 -3.186472e-15  1.862523e-15
+           16
+-2.553073e-15
+[1] 0 1 2 3
+  (Intercept)             x             z           x:z
+-2.185795e+02  1.705000e-01 -1.169876e+02 -2.688673e-15  3.941683e-15
+
+-6.197555e-16 -6.866679e-16  3.840467e-16  6.293211e-15  2.537161e-16
+
+-3.781255e-16  4.247660e-16  3.014702e-16 -3.251020e-15  8.897297e-16
+
+-8.455924e-16
+   (Intercept)    x             z           x:z
+1        -4.00 -6.0 -218.57950000 -327.95450000
+2         0.25  2.0    0.17050000  109.54550000
+3         0.25  0.2 -116.98759829 -169.11579854
+4         0.25  0.2    0.37432885   58.14639876
+5         0.25  0.2   -0.22966679   -0.18930680
+6         0.25  0.2    0.36593480    0.30162805
+7         0.25  0.2    0.40544326    0.33419358
+8         0.25  0.2   -0.22676050   -0.18691124
+9         0.25 -0.3   -0.29424059    0.39529683
+10        0.25 -0.3    0.14255785   -0.12348079
+11        0.25 -0.3   -0.11635849    0.18402947
+12        0.25 -0.3    0.21265075   -0.20672887
+13        0.25 -0.3   -0.01985253    0.06941108
+14        0.25 -0.3    0.16221805   -0.14683086
+15        0.25 -0.3    0.40318376   -0.43302150
+16        0.25 -0.3   -0.30791725    0.41154036
+attr(,"assign")
+[1] 0 1 2 3
+[1] 4
+        y x      z
+1  26.550 1 26.550
+2  37.210 1 37.210
+3  57.280 1 57.280
+4  90.820 1 90.820
+5  20.160 1 20.160
+6  89.838 1 89.838
+7  94.460 1 94.460
+8  20.500 1 20.500
+9  17.600 2 17.600
+10 68.700 2 68.700
+11 38.410 2 38.410
+12 76.900 2 76.900
+13 49.700 2 49.700
+14 71.000 2 71.000
+15 99.190 2 99.190
+16 16.000 2 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#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 <- factor(c('m', 'm', 'f', 'm', 'm', 'm', 'f', 'f', 'f', 'm', 'f', 'f', 'm', 'f', 'f', 'm')); 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)          xm
+   59.41750    -9.54525
+       1        2        3        4        5        6        7        8
+49.87225 49.87225 59.41750 49.87225 49.87225 49.87225 59.41750 59.41750
+       9       10       11       12       13       14       15       16
+59.41750 49.87225 59.41750 59.41750 49.87225 59.41750 59.41750 49.87225
+$x
+[1] "f" "m"
+
+        1         2         3         4         5         6         7         8
+-23.32225 -12.66225  -2.13750  40.94775 -29.71225  39.96575  35.04250 -38.91750
+        9        10        11        12        13        14        15        16
+-41.81750  18.82775 -21.00750  17.48250  -0.17225  11.58250  39.77250 -33.87225
+[1] 0 1
+(Intercept)          xm
+-218.579500   19.090500    0.527500   46.945167  -23.714833   45.963167
+
+  37.707500  -36.252500  -39.152500   24.825167  -18.342500   20.147500
+
+   5.825167   14.247500   42.437500  -27.874833
+   (Intercept)   xm
+1        -4.00 -2.0
+2         0.25 -2.0
+3         0.25 -0.3
+4         0.25  0.2
+5         0.25  0.2
+6         0.25  0.2
+7         0.25 -0.3
+8         0.25 -0.3
+9         0.25 -0.3
+10        0.25  0.2
+11        0.25 -0.3
+12        0.25 -0.3
+13        0.25  0.2
+14        0.25 -0.3
+15        0.25 -0.3
+16        0.25  0.2
+attr(,"assign")
+[1] 0 1
+attr(,"contrasts")
+attr(,"contrasts")$x
+[1] "contr.treatment"
+
+[1] 2
+        y x
+1  26.550 m
+2  37.210 m
+3  57.280 f
+4  90.820 m
+5  20.160 m
+6  89.838 m
+7  94.460 f
+8  20.500 f
+9  17.600 f
+10 68.700 m
+11 38.410 f
+12 76.900 f
+13 49.700 m
+14 71.000 f
+15 99.190 f
+16 16.000 m
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); 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
+1.498638e+00 2.491574e-05
+       1        2        3        4        5        6        7        8
+1.499300 1.499566 1.500066 1.500901 1.499141 1.500877 1.500992 1.499149
+       9       10       11       12       13       14       15       16
+1.499077 1.500350 1.499595 1.500555 1.499877 1.500408 1.501110 1.499037
+named list()
+         1          2          3          4          5          6          7
+-0.4993000 -0.4995656 -0.5000657 -0.5009013 -0.4991408 -0.5008769 -0.5009920
+         8          9         10         11         12         13         14
+-0.4991493  0.5009230  0.4996498  0.5004045  0.4994455  0.5001232  0.4995925
+        15         16
+ 0.4988901  0.5009629
+[1] 0 1
+ (Intercept)            x
+-6.000000000  0.002914836 -0.425819921 -0.530737495 -0.309703632 -0.527665668
+
+-0.542123898 -0.310767197  0.698304388  0.538456803  0.633207945  0.512806114
+
+ 0.597891326  0.531262097  0.443080034  0.703309401
+   (Intercept)             x
+1        -4.00 -2.185795e+02
+2         0.25  1.169877e+02
+3         0.25 -7.055527e-02
+4         0.25 -3.572520e-01
+5         0.25  2.467430e-01
+6         0.25 -3.488580e-01
+7         0.25 -3.883664e-01
+8         0.25  2.438367e-01
+9         0.25  2.686256e-01
+10        0.25 -1.681723e-01
+11        0.25  9.074371e-02
+12        0.25 -2.382652e-01
+13        0.25 -5.762143e-03
+14        0.25 -1.878325e-01
+15        0.25 -4.287980e-01
+16        0.25  2.823023e-01
+attr(,"assign")
+[1] 0 1
+[1] 2
+   y      x
+1  1 26.550
+2  1 37.210
+3  1 57.280
+4  1 90.820
+5  1 20.160
+6  1 89.838
+7  1 94.460
+8  1 20.500
+9  2 17.600
+10 2 68.700
+11 2 38.410
+12 2 76.900
+13 2 49.700
+14 2 71.000
+15 2 99.190
+16 2 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); 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); z <- 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:z)^3); 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:z
+ 1.515259e+00 -3.972145e-06
+       1        2        3        4        5        6        7        8
+1.512459 1.509759 1.502226 1.482495 1.513644 1.483200 1.479817 1.513589
+       9       10       11       12       13       14       15       16
+1.514028 1.496511 1.509399 1.491769 1.505447 1.495235 1.476178 1.514242
+named list()
+         1          2          3          4          5          6          7
+-0.5124588 -0.5097590 -0.5022262 -0.4824954 -0.5136444 -0.4832001 -0.4798166
+         8          9         10         11         12         13         14
+-0.5135895  0.4859716  0.5034885  0.4906014  0.5082309  0.4945528  0.5047648
+        15         16
+ 0.5238218  0.4857581
+[1] 0 1
+(Intercept)         x:z
+-6.00000000 -0.05300951 -0.40152887 -0.51511124 -0.33579849 -0.51105464
+
+-0.53053260 -0.33611460  0.66641188  0.56557381  0.63975984  0.53827347
+
+ 0.61701348  0.55822669  0.44852283  0.66764116
+   (Intercept)           x:z
+1        -4.00 -1.536578e+04
+2         0.25  1.334531e+04
+3         0.25 -5.010123e-03
+4         0.25 -3.772213e-01
+5         0.25  2.103894e-01
+6         0.25 -3.639278e-01
+7         0.25 -4.277574e-01
+8         0.25  2.093535e-01
+9         0.25  2.176328e-01
+10        0.25 -1.128152e-01
+11        0.25  1.302936e-01
+12        0.25 -2.022788e-01
+13        0.25  5.575343e-02
+14        0.25 -1.368918e-01
+15        0.25 -4.963931e-01
+16        0.25  2.216612e-01
+attr(,"assign")
+[1] 0 1
+[1] 2
+   y      x      z
+1  1 26.550 26.550
+2  1 37.210 37.210
+3  1 57.280 57.280
+4  1 90.820 90.820
+5  1 20.160 20.160
+6  1 89.838 89.838
+7  1 94.460 94.460
+8  1 20.500 20.500
+9  2 17.600 17.600
+10 2 68.700 68.700
+11 2 38.410 38.410
+12 2 76.900 76.900
+13 2 49.700 49.700
+14 2 71.000 71.000
+15 2 99.190 99.190
+16 2 16.000 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); 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); z <- 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*z); 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             z           x:z
+ 1.2097300183  0.0141888866            NA -0.0001262754
+       1        2        3        4        5        6        7        8
+1.497433 1.562860 1.608160 1.456811 1.444456 1.465280 1.423296 1.447535
+       9       10       11       12       13       14       15       16
+1.420339 1.588526 1.568428 1.554112 1.603006 1.580587 1.374746 1.404426
+named list()
+         1          2          3          4          5          6          7
+-0.4974331 -0.5628596 -0.6081601 -0.4568110 -0.4444564 -0.4652795 -0.4232960
+         8          9         10         11         12         13         14
+-0.4475350  0.5796606  0.4114741  0.4315725  0.4458879  0.3969939  0.4194132
+        15         16
+ 0.6252543  0.5955743
+[1] 0 1 2 3
+ (Intercept)            x          x:z
+-6.000000000  0.002914836 -0.306856142 -0.537277949 -0.329156136 -0.531934767
+
+-0.557686236 -0.329301207  0.671670249  0.566332170  0.651349607  0.532011761
+
+ 0.627344346  0.557191764  0.414376166  0.671948335
+   (Intercept)             x           x:z             z
+1        -4.00 -2.185795e+02 -1.536578e+04 -2.185795e+02
+2         0.25  1.169877e+02  1.312220e+04  1.169877e+02
+3         0.25 -7.055527e-02  2.430055e+03  6.557040e-15
+4         0.25 -3.572520e-01 -7.514340e-02  4.060091e-14
+5         0.25  2.467430e-01 -2.234902e-01 -2.217939e-01
+6         0.25 -3.488580e-01 -4.904776e-02  3.589489e-01
+7         0.25 -3.883664e-01 -1.787960e-01  3.825867e-01
+8         0.25  2.438367e-01 -2.129376e-01 -2.237164e-01
+9         0.25  2.686256e-01 -3.060002e-01 -2.067620e-01
+10        0.25 -1.681723e-01  3.202606e-01  1.166607e-01
+11        0.25  9.074371e-02  2.084299e-01 -1.254756e-01
+12        0.25 -2.382652e-01  2.206541e-01  2.223106e-01
+13        0.25 -5.762143e-03  3.383863e-01 -5.344469e-02
+14        0.25 -1.878325e-01  2.979065e-01  1.207332e-01
+15        0.25 -4.287980e-01 -3.297793e-01  5.850999e-01
+16        0.25  2.823023e-01 -3.603079e-01 -1.093647e-01
+attr(,"assign")
+[1] 0 1 2 3
+[1] 3
+   y      x      z
+1  1 26.550 26.550
+2  1 37.210 37.210
+3  1 57.280 57.280
+4  1 90.820 90.820
+5  1 20.160 20.160
+6  1 89.838 89.838
+7  1 94.460 94.460
+8  1 20.500 20.500
+9  2 17.600 17.600
+10 2 68.700 68.700
+11 2 38.410 38.410
+12 2 76.900 76.900
+13 2 49.700 49.700
+14 2 71.000 71.000
+15 2 99.190 99.190
+16 2 16.000 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); x <- c(rep(1,8), rep(2,8)); 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
+-6.661338e-16  1.000000e+00
+ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
+ 1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2
+named list()
+            1             2             3             4             5
+ 1.942890e-16 -6.938894e-16  8.326673e-17  8.326673e-17  8.326673e-17
+            6             7             8             9            10
+ 8.326673e-17  8.326673e-17  8.326673e-17 -3.697785e-32 -3.697785e-32
+           11            12            13            14            15
+-3.697785e-32 -3.697785e-32 -3.697785e-32 -3.697785e-32 -3.697785e-32
+           16
+-3.697785e-32
+[1] 0 1
+  (Intercept)             x
+-6.000000e+00  2.000000e+00  1.665335e-16  1.665335e-16  1.665335e-16
+
+ 1.665335e-16  1.665335e-16  1.665335e-16 -2.220446e-16 -2.220446e-16
+
+-2.220446e-16 -2.220446e-16 -2.220446e-16 -2.220446e-16 -2.220446e-16
+
+-2.220446e-16
+   (Intercept)    x
+1        -4.00 -6.0
+2         0.25  2.0
+3         0.25  0.2
+4         0.25  0.2
+5         0.25  0.2
+6         0.25  0.2
+7         0.25  0.2
+8         0.25  0.2
+9         0.25 -0.3
+10        0.25 -0.3
+11        0.25 -0.3
+12        0.25 -0.3
+13        0.25 -0.3
+14        0.25 -0.3
+15        0.25 -0.3
+16        0.25 -0.3
+attr(,"assign")
+[1] 0 1
+[1] 2
+   y x
+1  1 1
+2  1 1
+3  1 1
+4  1 1
+5  1 1
+6  1 1
+7  1 1
+8  1 1
+9  2 2
+10 2 2
+11 2 2
+12 2 2
+13 2 2
+14 2 2
+15 2 2
+16 2 2
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); x <- c(rep(1,8), rep(2,8)); z <- 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:z)^3); 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:z
+ 1.09157779  0.00498145
+       1        2        3        4        5        6        7        8
+1.223835 1.276938 1.376915 1.543993 1.192004 1.539101 1.562126 1.193698
+       9       10       11       12       13       14       15       16
+1.266925 1.776029 1.474253 1.857725 1.586734 1.798944 2.079798 1.250984
+named list()
+          1           2           3           4           5           6
+-0.22383528 -0.27693753 -0.37691523 -0.54399305 -0.19200381 -0.53910127
+          7           8           9          10          11          12
+-0.56212553 -0.19369751  0.73307518  0.22397102  0.52574725  0.14227525
+         13          14          15          16
+ 0.41326611  0.20105635 -0.07979778  0.74901582
+[1] 0 1
+(Intercept)         x:z
+-6.00000000  1.04469651 -0.31915613 -0.51822546 -0.09883849 -0.51239701
+
+-0.53982988 -0.10085648  0.81189488  0.20530914  0.56486848  0.10797053
+
+ 0.43084983  0.17800685 -0.15662431  0.83088778
+   (Intercept)           x:z
+1        -4.00 -327.95450000
+2         0.25  209.71736593
+3         0.25    0.06494884
+4         0.25   -0.09498069
+5         0.25    0.24194897
+6         0.25   -0.09029820
+7         0.25   -0.11233738
+8         0.25    0.24032774
+9         0.25    0.17023340
+10        0.25   -0.31708914
+11        0.25   -0.02822418
+12        0.25   -0.39528963
+13        0.25   -0.13589290
+14        0.25   -0.33902343
+15        0.25   -0.60786144
+16        0.25    0.18549203
+attr(,"assign")
+[1] 0 1
+[1] 2
+   y x      z
+1  1 1 26.550
+2  1 1 37.210
+3  1 1 57.280
+4  1 1 90.820
+5  1 1 20.160
+6  1 1 89.838
+7  1 1 94.460
+8  1 1 20.500
+9  2 2 17.600
+10 2 2 68.700
+11 2 2 38.410
+12 2 2 76.900
+13 2 2 49.700
+14 2 2 71.000
+15 2 2 99.190
+16 2 2 16.000
+
+##com.oracle.truffle.r.test.library.stats.TestFitting.testLm
+#y <- c(rep(1,8), rep(2,8)); x <- c(rep(1,8), rep(2,8)); z <- 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*z); 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             z           x:z
+-6.661338e-16  1.000000e+00  2.741807e-18 -1.370904e-18
+ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16
+ 1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2
+named list()
+            1             2             3             4             5
+ 2.327460e-16 -6.700463e-16  7.959579e-17  3.361568e-17  1.304837e-16
+            6             7             8             9            10
+ 3.496191e-17  2.862559e-17  1.300176e-16  0.000000e+00  0.000000e+00
+           11            12            13            14            15
+ 0.000000e+00 -4.930381e-32  0.000000e+00 -4.930381e-32  0.000000e+00
+           16
+ 0.000000e+00
+[1] 0 1 2 3
+  (Intercept)             x             z           x:z
+-6.000000e+00  2.000000e+00 -8.891599e-17 -7.971311e-17  2.433801e-16
+
+ 4.409147e-17  3.087192e-17  2.424076e-16 -2.007663e-16 -2.405861e-16
+
+-2.169826e-16 -2.469760e-16 -2.257803e-16 -2.423784e-16 -2.643456e-16
+
+-1.995195e-16
+   (Intercept)    x             z           x:z
+1        -4.00 -6.0 -218.57950000 -327.95450000
+2         0.25  2.0    0.17050000  109.54550000
+3         0.25  0.2 -116.98759829 -169.11579854
+4         0.25  0.2    0.37432885   58.14639876
+5         0.25  0.2   -0.22966679   -0.18930680
+6         0.25  0.2    0.36593480    0.30162805
+7         0.25  0.2    0.40544326    0.33419358
+8         0.25  0.2   -0.22676050   -0.18691124
+9         0.25 -0.3   -0.29424059    0.39529683
+10        0.25 -0.3    0.14255785   -0.12348079
+11        0.25 -0.3   -0.11635849    0.18402947
+12        0.25 -0.3    0.21265075   -0.20672887
+13        0.25 -0.3   -0.01985253    0.06941108
+14        0.25 -0.3    0.16221805   -0.14683086
+15        0.25 -0.3    0.40318376   -0.43302150
+16        0.25 -0.3   -0.30791725    0.41154036
+attr(,"assign")
+[1] 0 1 2 3
+[1] 4
+   y x      z
+1  1 1 26.550
+2  1 1 37.210
+3  1 1 57.280
+4  1 1 90.820
+5  1 1 20.160
+6  1 1 89.838
+7  1 1 94.460
+8  1 1 20.500
+9  2 2 17.600
+10 2 2 68.700
+11 2 2 38.410
+12 2 2 76.900
+13 2 2 49.700
+14 2 2 71.000
+15 2 2 99.190
+16 2 2 16.000
+
 ##com.oracle.truffle.r.test.library.stats.TestFormulae.testModelFrame
 #{y<-0:9;z<-1:10;k<-2:11;w<-3:12;m<-4:13;u<-5:14;v<-6:15;; model.frame(terms.formula(u~z*k+w*m)) }
     u  z  k  w  m
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java
new file mode 100644
index 0000000000..d1f775861e
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java
@@ -0,0 +1,53 @@
+/*
+ * 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 fitting functions: {@code lm}.
+ */
+public class TestFitting extends TestBase {
+    private static final String[] CHECK_RESULT_NAMES = new String[]{"coefficients", "fitted.values", "xlevels", "residuals", "assign", "effects", "qr$qr", "rank", "model"};
+    private static final String RANDOM_VECTOR = "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)";
+    private static final String RANDOM_FACTOR = "factor(c('m', 'm', 'f', 'm', 'm', 'm', 'f', 'f', 'f', 'm', 'f', 'f', 'm', 'f', 'f', 'm'))";
+    private static final String[] VALUES = new String[]{
+                    RANDOM_VECTOR,
+                    "c(rep(1,8), rep(2,8))"
+    };
+
+    @Test
+    public void testLm() {
+        StringBuffer printCode = new StringBuffer();
+        for (String name : CHECK_RESULT_NAMES) {
+            printCode.append("print(res$").append(name).append(");");
+        }
+
+        assertEval(Output.IgnoreWhitespace, template("y <- %0; x <- %1; res <- lm(y~x); " + printCode, VALUES, VALUES));
+        assertEval(Output.IgnoreWhitespace, template("y <- %0; x <- %1; z <- %2; res <- lm(y~x*z); " + printCode, VALUES, VALUES, new String[]{RANDOM_VECTOR}));
+        assertEval(Output.IgnoreWhitespace, template("y <- %0; x <- %1; z <- %2; res <- lm(y~(x:z)^3); " + printCode, VALUES, VALUES, new String[]{RANDOM_VECTOR}));
+        assertEval(Output.IgnoreWhitespace, String.format("y <- %s; x <- %s; res <- lm(y~x); " + printCode, RANDOM_VECTOR, RANDOM_FACTOR));
+    }
+}
diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides
index 7cfc8822a9..e852287e55 100644
--- a/mx.fastr/copyrights/overrides
+++ b/mx.fastr/copyrights/overrides
@@ -107,6 +107,7 @@ com.oracle.truffle.r.native/library/utils/src/utils_dummy.c,no.copyright
 com.oracle.truffle.r.native/run/R.sh,oracle_bash.copyright
 com.oracle.truffle.r.native/run/Rscript_exec.sh,oracle_bash.copyright
 com.oracle.truffle.r.native/run/Rscript.sh,oracle_bash.copyright
+com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java,gnu_r.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java,purdue.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java,gnu_r_ihaka.copyright
 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseVariables.java,gnu_r.copyright
-- 
GitLab