

# Creation: 6/2016
# Author: Nicola Cortesi
# Aim: modified version of the lm.fit() base R function, to increase its speed by removing some unnecessary outputs (such as the QR decomposition)
# Assumptions: the first column of the x matrix must be a column of 1, to represent the constant term.
# I/O: none, it's a function, not a script :)
# Branch: general

lm.fit.fast<-function (x, y, offset = NULL, method = "qr", tol = 1e-07, singular.ok = TRUE, ...) 
{
    if (is.null(n <- nrow(x))) 
        stop("'x' must be a matrix")
    if (n == 0L) 
        stop("0 (non-NA) cases")
    p <- ncol(x)
    if (p == 0L) {
        return(list(coefficients = numeric(0L), residuals = y, 
            fitted.values = 0 * y, rank = 0, df.residual = length(y)))
    }
    ny <- NCOL(y)
    if (is.matrix(y) && ny == 1) 
        y <- drop(y)
    if (!is.null(offset)) 
        y <- y - offset
    if (NROW(y) != n) 
        stop("incompatible dimensions")
    if (method != "qr") 
        warning(gettextf("method = '%s' is not supported. Using 'qr'", 
            method), domain = NA)
    if (length(list(...))) 
        warning("extra arguments ", paste(names(list(...)), sep = ", "), 
            " are just disregarded.")
    storage.mode(x) <- "double"
    storage.mode(y) <- "double"
	
	z <- .Call(stats:::C_Cdqrls, x, y, tol, TRUE)
	
    if (!singular.ok && z$rank < p) 
        stop("singular fit encountered")
    coef <- z$coefficients
    pivot <- z$pivot
    r1 <- seq_len(z$rank)
    dn <- colnames(x)
    if (is.null(dn)) 
        dn <- paste("x", 1L:p, sep = "")
    r2 <- if (z$rank < p) 
        (z$rank + 1L):p
    else integer(0L)
    if (is.matrix(y)) {
        coef[r2, ] <- NA
        coef[pivot, ] <- coef
        dimnames(coef) <- list(dn, colnames(y))
    }
    else {
        coef[r2] <- NA
        coef[pivot] <- coef
        names(coef) <- dn
    }
    z$coefficients <- coef
    r1 <- y - z$residuals
    if (!is.null(offset)) 
        r1 <- r1 + offset
   c(z[c("coefficients", "residuals", "rank")], list(fitted.values = r1, df.residual = n - z$rank))
}
