If you want to do something crazy like that, you should use Rcpp:
library(RcppEigen)
library(inline)
incl <- '
using Eigen::LLT;
using Eigen::Lower;
using Eigen::Map;
using Eigen::MatrixXd;
using Eigen::MatrixXi;
using Eigen::Upper;
using Eigen::VectorXd;
using Eigen::Vector3d;
typedef Map<MatrixXd> MapMatd;
typedef Map<MatrixXi> MapMati;
typedef Map<VectorXd> MapVecd;
inline MatrixXd AtA(const MatrixXd& A) {
int n(A.cols());
return MatrixXd(n,n).setZero().selfadjointView<Lower>().rankUpdate(A.adjoint());
}
'
body <- '
const MapMatd X(as<MapMatd>(XX));
const MapVecd y(as<MapVecd>(yy));
const int n(X.rows()), m(X.cols());
LLT<MatrixXd> llt;
MatrixXd Res(n*n,m), Xbar(n,m);
Vector3d betahat;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
Xbar=X;
for (int k = 0; k < n; ++k) {
Xbar(k,1) -= X(i,1);
Xbar(k,2) -= X(j,2);
};
llt=AtA(Xbar);
betahat =llt.solve(Xbar.adjoint() * y);
Res.row(i*n+j) = betahat;
};
};
return wrap(Res);
'
crazyLm <- cxxfunction(signature(XX = "matrix", yy = "numeric"),
body, "RcppEigen", incl)
set.seed(1)
n=4
y=rnorm(n)
x1=rnorm(n)
x2=rnorm(n)
lm.ft=function(y,x1,x2) lm.fit(cbind(1,x1.bar,x2.bar), y)$coef
res=array(,dim=c(3,n,n))
for(i in 1:n)
for(j in 1:n){
x1.bar=x1-x1[i]
x2.bar=x2-x2[j]
res[,i,j]=lm.ft(y,x1.bar,x2.bar)
}
res2 <- aperm(array(t(crazyLm(cbind(1,x1,x2), y)), dim=c(3,n,n)), c(1,3,2))
all.equal(res, res2)
#[1] TRUE
system.time({
set.seed(1)
n=1000
y=rnorm(n)
x1=rnorm(n)
x2=rnorm(n)
res <- aperm(array(t(crazyLm(cbind(1,x1,x2), y)), dim=c(3,n,n)), c(1,3,2))
})
# User System elapsed
#36.130 0.033 36.158
That allows you to fit one million models in under one minute. However, I don't see a usecase.