|
5 | 5 | ## This file is part of RcppEigen. |
6 | 6 |
|
7 | 7 | require("stats", character=TRUE, quietly=TRUE) |
8 | | -require("rbenchmark", character=TRUE, quietly=TRUE) |
9 | 8 | require("RcppEigen", character=TRUE, quietly=TRUE) |
10 | 9 |
|
11 | | -## define different versions of lm |
12 | | -exprs <- list() |
13 | | - |
14 | | -## These versions use rank-revealing decompositions and thus can |
15 | | -## handle rank-deficient cases. |
16 | | - |
17 | | - # default version used in lm() |
18 | | -exprs$lm.fit <- expression(stats::lm.fit(mm, y)) |
19 | | - # versions from RcppEigen |
20 | | -## column-pivoted QR decomposition - similar to lm.fit |
21 | | -exprs$PivQR <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 0L, PACKAGE="RcppEigen")) |
22 | | -## LDLt Cholesky decomposition with rank detection |
23 | | -exprs$LDLt <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 2L, PACKAGE="RcppEigen")) |
24 | | -## SVD using the Lapack subroutine dgesdd and Eigen support |
25 | | -exprs$GESDD <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 6L, PACKAGE="RcppEigen")) |
26 | | -## SVD (the JacobiSVD class from Eigen) |
27 | | -exprs$SVD <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 4L, PACKAGE="RcppEigen")) |
28 | | -## eigenvalues and eigenvectors of X'X |
29 | | -exprs$SymmEig <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 5L, PACKAGE="RcppEigen")) |
30 | | - |
31 | | -## Non-rank-revealing decompositions. These work fine except when |
32 | | -## they don't. |
33 | | - |
34 | | -## Unpivoted QR decomposition |
35 | | -exprs$QR <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 1L, PACKAGE="RcppEigen")) |
36 | | -## LLt Cholesky decomposition |
37 | | -exprs$LLt <- expression(.Call("RcppEigen_fastLm_Impl", mm, y, 3L, PACKAGE="RcppEigen")) |
38 | | - |
39 | | -if (suppressMessages(require("RcppArmadillo", character=TRUE, quietly=TRUE))) { |
40 | | - exprs$arma <- expression(.Call("RcppArmadillo_fastLm", mm, y, PACKAGE="RcppArmadillo")) |
41 | | -} |
| 10 | +if(require("microbenchmark", character=TRUE, quietly=TRUE)){ |
42 | 11 |
|
43 | | -if (suppressMessages(require("RcppGSL", character=TRUE, quietly=TRUE))) { |
44 | | - exprs$GSL <- expression(.Call("RcppGSL_fastLm", mm, y, PACKAGE="RcppGSL")) |
45 | | -} |
| 12 | + ## define different versions of lm |
| 13 | + exprs <- list() |
46 | 14 |
|
47 | | -do_bench <- function(n=100000L, p=40L, nrep=20L, suppressSVD=(n > 100000L)) { |
48 | | - mm <- cbind(1, matrix(rnorm(n * (p - 1L)), nc=p-1L)) |
49 | | - y <- rnorm(n) |
50 | | - if (suppressSVD) exprs <- exprs[!names(exprs) %in% c("SVD", "GSL")] |
51 | | - cat("lm benchmark for n = ", n, " and p = ", p, ": nrep = ", nrep, "\n", sep='') |
52 | | - do.call(benchmark, c(exprs, |
53 | | - list(order="relative", |
54 | | - columns = c("test", "relative", |
55 | | - "elapsed", "user.self", "sys.self"), |
56 | | - replications = nrep))) |
57 | | -} |
| 15 | + ## These versions use rank-revealing decompositions and thus can |
| 16 | + ## handle rank-deficient cases. |
| 17 | + |
| 18 | + # default version used in lm() |
| 19 | + exprs["lm.fit"] <- alist(stats::lm.fit(mm, y)) |
| 20 | + |
| 21 | + # versions from RcppEigen |
| 22 | + ## column-pivoted QR decomposition - similar to lm.fit |
| 23 | + exprs["PivQR"] <- alist(RcppEigen::fastLmPure(mm, y, 0L)) |
| 24 | + ## LDLt Cholesky decomposition with rank detection |
| 25 | + exprs["LDLt"] <- alist(RcppEigen::fastLmPure(mm, y, 2L)) |
| 26 | + ## SVD using the Lapack subroutine dgesdd and Eigen support |
| 27 | + exprs["GESDD"] <- alist(RcppEigen::fastLmPure(mm, y, 6L)) |
| 28 | + ## SVD (the JacobiSVD class from Eigen) |
| 29 | + exprs["SVD"] <- alist(RcppEigen::fastLmPure(mm, y, 4L)) |
| 30 | + ## eigenvalues and eigenvectors of X'X |
| 31 | + exprs["SymmEig"] <- alist(RcppEigen::fastLmPure(mm, y, 5L)) |
| 32 | + |
| 33 | + ## Non-rank-revealing decompositions. These work fine except when |
| 34 | + ## they don't. |
| 35 | + |
| 36 | + ## Unpivoted QR decomposition |
| 37 | + exprs["QR"] <- alist(RcppEigen::fastLmPure(mm, y, 1L)) |
| 38 | + ## LLt Cholesky decomposition |
| 39 | + exprs["LLt"] <- alist(RcppEigen::fastLmPure(mm, y, 3L)) |
| 40 | + |
| 41 | + if (suppressMessages(require("RcppArmadillo", character=TRUE, quietly=TRUE))) { |
| 42 | + exprs["arma"] <- alist(RcppArmadillo::fastLmPure(mm, y)) |
| 43 | + } |
58 | 44 |
|
59 | | -print(do_bench()) |
| 45 | + if (suppressMessages(require("RcppGSL", character=TRUE, quietly=TRUE))) { |
| 46 | + exprs["GSL"] <- alist(RcppGSL::fastLmPure(mm, y)) |
| 47 | + } |
60 | 48 |
|
61 | | -sessionInfo() |
| 49 | + do_bench <- function(n=100000L, p=40L, nrep=20L, suppressSVD=(n > 100000L)) { |
| 50 | + mm <- cbind(1, matrix(rnorm(n * (p - 1L)), nc=p-1L)) |
| 51 | + y <- rnorm(n) |
| 52 | + if (suppressSVD) exprs <- exprs[!names(exprs) %in% c("SVD", "GSL")] |
62 | 53 |
|
63 | | -.Call("RcppEigen_eigen_version", FALSE, PACKAGE="RcppEigen") |
| 54 | + cat("lm benchmark for n = ", n, " and p = ", p, ": nrep = ", nrep, "\n", sep='') |
| 55 | + cat("RcppEigen: Included Eigen version", paste(RcppEigen:::eigen_version(FALSE), collapse="."), "\n") |
| 56 | + cat("RcppEigen: Eigen SSE support", RcppEigen:::Eigen_SSE(), "\n") |
64 | 57 |
|
65 | | -.Call("RcppEigen_Eigen_SSE", PACKAGE="RcppEigen") |
| 58 | + mb <- microbenchmark(list=exprs, times = nrep) |
| 59 | + |
| 60 | + op <- options(microbenchmark.unit="relative") |
| 61 | + on.exit(options(op)) |
| 62 | + |
| 63 | + mb_relative <- summary(mb) |
| 64 | + levels(mb_relative$expr) <- names(exprs) |
| 65 | + |
| 66 | + options(microbenchmark.unit=NULL) |
| 67 | + mb_absolute <- summary(mb) |
| 68 | + levels(mb_absolute$expr) <- names(exprs) |
| 69 | + |
| 70 | + mb_combined <- merge(mb_relative[, c("expr", "median")], |
| 71 | + mb_absolute[, c("expr", "median")], |
| 72 | + by="expr") |
| 73 | + |
| 74 | + colnames(mb_combined) <- c("Method", |
| 75 | + "Relative", |
| 76 | + paste0("Elapsed (", attr(mb_absolute, "unit"), ")")) |
| 77 | + |
| 78 | + mb_combined[order(mb_combined$Relative),] |
| 79 | + } |
| 80 | + |
| 81 | + print(do_bench()) |
| 82 | +} |
0 commit comments