|
2 | 2 | // |
3 | 3 | // fastLm.cpp: Rcpp/Eigen example of a simple lm() alternative |
4 | 4 | // |
5 | | -// Copyright (C) 2011 Douglas Bates, Dirk Eddelbuettel and Romain Francois |
| 5 | +// Copyright (C) 2011 - 2015 Douglas Bates, Dirk Eddelbuettel and Romain Francois |
6 | 6 | // |
7 | 7 | // This file is part of RcppEigen. |
8 | 8 | // |
@@ -202,45 +202,45 @@ namespace lmsol { |
202 | 202 | return ColPivQR(X, y); // -Wall |
203 | 203 | } |
204 | 204 |
|
205 | | - extern "C" SEXP fastLm(SEXP Xs, SEXP ys, SEXP type) { |
206 | | - try { |
207 | | - const Map<MatrixXd> X(as<Map<MatrixXd> >(Xs)); |
208 | | - const Map<VectorXd> y(as<Map<VectorXd> >(ys)); |
209 | | - Index n = X.rows(); |
210 | | - if ((Index)y.size() != n) throw invalid_argument("size mismatch"); |
211 | | - |
212 | | - // Select and apply the least squares method |
213 | | - lm ans(do_lm(X, y, ::Rf_asInteger(type))); |
214 | | - |
215 | | - // Copy coefficients and install names, if any |
216 | | - NumericVector coef(wrap(ans.coef())); |
217 | | - List dimnames(NumericMatrix(Xs).attr("dimnames")); |
218 | | - if (dimnames.size() > 1) { |
219 | | - RObject colnames = dimnames[1]; |
220 | | - if (!(colnames).isNULL()) |
221 | | - coef.attr("names") = clone(CharacterVector(colnames)); |
222 | | - } |
| 205 | + List fastLm(Rcpp::NumericMatrix Xs, Rcpp::NumericVector ys, int type) { |
| 206 | + const Map<MatrixXd> X(as<Map<MatrixXd> >(Xs)); |
| 207 | + const Map<VectorXd> y(as<Map<VectorXd> >(ys)); |
| 208 | + Index n = X.rows(); |
| 209 | + if ((Index)y.size() != n) throw invalid_argument("size mismatch"); |
| 210 | + |
| 211 | + // Select and apply the least squares method |
| 212 | + lm ans(do_lm(X, y, type)); |
| 213 | + |
| 214 | + // Copy coefficients and install names, if any |
| 215 | + NumericVector coef(wrap(ans.coef())); |
| 216 | + |
| 217 | + List dimnames(NumericMatrix(Xs).attr("dimnames")); |
| 218 | + if (dimnames.size() > 1) { |
| 219 | + RObject colnames = dimnames[1]; |
| 220 | + if (!(colnames).isNULL()) |
| 221 | + coef.attr("names") = clone(CharacterVector(colnames)); |
| 222 | + } |
223 | 223 |
|
224 | | - VectorXd resid = y - ans.fitted(); |
225 | | - int rank = ans.rank(); |
226 | | - int df = (rank == ::NA_INTEGER) ? n - X.cols() : n - rank; |
227 | | - double s = resid.norm() / std::sqrt(double(df)); |
228 | | - // Create the standard errors |
229 | | - VectorXd se = s * ans.se(); |
230 | | - |
231 | | - return List::create(_["coefficients"] = coef, |
232 | | - _["se"] = se, |
233 | | - _["rank"] = rank, |
234 | | - _["df.residual"] = df, |
235 | | - _["residuals"] = resid, |
236 | | - _["s"] = s, |
237 | | - _["fitted.values"] = ans.fitted()); |
238 | | - |
239 | | - } catch( std::exception &ex ) { |
240 | | - forward_exception_to_r( ex ); |
241 | | - } catch(...) { |
242 | | - ::Rf_error( "c++ exception (unknown reason)" ); |
243 | | - } |
244 | | - return R_NilValue; // -Wall |
| 224 | + VectorXd resid = y - ans.fitted(); |
| 225 | + int rank = ans.rank(); |
| 226 | + int df = (rank == ::NA_INTEGER) ? n - X.cols() : n - rank; |
| 227 | + double s = resid.norm() / std::sqrt(double(df)); |
| 228 | + // Create the standard errors |
| 229 | + VectorXd se = s * ans.se(); |
| 230 | + |
| 231 | + return List::create(_["coefficients"] = coef, |
| 232 | + _["se"] = se, |
| 233 | + _["rank"] = rank, |
| 234 | + _["df.residual"] = df, |
| 235 | + _["residuals"] = resid, |
| 236 | + _["s"] = s, |
| 237 | + _["fitted.values"] = ans.fitted()); |
245 | 238 | } |
246 | 239 | } |
| 240 | + |
| 241 | +// This defines the R-callable function 'fastLm' |
| 242 | +// [[Rcpp::export]] |
| 243 | +Rcpp::List fastLm(Rcpp::NumericMatrix X, Rcpp::NumericVector y, int type) { |
| 244 | + return lmsol::fastLm(X, y, type); |
| 245 | +} |
| 246 | + |
0 commit comments