[Rcpp-devel] fill a NumericMatrix row by row
Dirk Eddelbuettel
edd at debian.org
Wed Mar 27 14:42:56 CET 2013
On 27 March 2013 at 12:06, Michael Love wrote:
| Thanks for the reply and great libraries Conrad and Romain.
|
| Conrad, my example is a bit too simple maybe, I am really doing:
|
| for i from 1 to m:
| do computation
| store a row of results into a tall m x n matrix
|
| ...where i am pretty sure that the time required for computation is more than
| storing the results.
|
| Out of curiosity, I tried to do some profiling for row filling of tall
| Armadillo matrices vs. column filling. Row filling becomes worse when the rows
| are long. I guess the memory allocation could obscure some speed differences:
You did read the line where we explained that storage is by _columns_ so
insertion by row _has to_ result in copies?
This too has been discussed before. If performance matters, grow columns and
transose at the end.
Dirk
|
| library(Rcpp)
| library(inline)
|
| # fill a matrix by row with m0 rows and n0 columns
| row.code <- '
| int m = Rcpp::as<int>(m0);
| int n = Rcpp::as<int>(n0);
| arma::mat mat = arma::zeros(m,n);
| arma::rowvec vec = Rcpp::as<arma::rowvec>(vec0);
| for (int i = 0; i < m; i++) {
| mat.row(i) = vec;
| }
| return Rcpp::wrap(mat);
| '
| row.f <- cxxfunction(signature(m0="integer",n0="integer",vec0=
| "numeric"),row.code,plugin="RcppArmadillo")
|
| # so here we swap, fill by column, m0 is the number of columns and n0 is the
| number of rows
| col.code <- '
| int m = Rcpp::as<int>(m0);
| int n = Rcpp::as<int>(n0);
| arma::mat mat = arma::zeros(n,m);
| arma::colvec vec = Rcpp::as<arma::colvec>(vec0);
| for (int i = 0; i < m; i++) {
| mat.col(i) = vec;
| }
| return Rcpp::wrap(mat);
| '
| col.f <- cxxfunction(signature(m0="
| integer",n0="integer",vec0="numeric"),col.code,plugin="RcppArmadillo")
|
| > m <- 1e7
| > n <- 10
| > vec0 <- seq_len(n)
| > system.time({row.f(m,n,vec0)})
| user system elapsed
| 0.779 1.022 1.801
| > system.time({col.f(m,n,vec0)})
| user system elapsed
| 0.957 0.966 1.922
| > all.equal(row.f(m,n,vec0), t(col.f(m,n,vec0)))
| [1] TRUE
|
| > m <- 1e6
| > n <- 100
| > vec0 <- seq_len(n)
| > system.time({row.f(m,n,vec0)})
| user system elapsed
| 1.925 1.425 3.351
| > system.time({col.f(m,n,vec0)})
| user system elapsed
| 1.244 1.423 2.667
| > all.equal(row.f(m,n,vec0), t(col.f(m,n,vec0)))
| [1] TRUE
|
|
| On Wed, Mar 27, 2013 at 9:44 AM, Conrad S <conradsand.arma at gmail.com> wrote:
|
| There's an even simpler way when using Armadillo, so that no loop is
| required:
| http://arma.sourceforge.net/docs.html#each_colrow
|
| For example:
|
| mat X(4,5);
| rowvec r(5);
|
| X.each_row() = r;
|
|
| (btw, in general it's more efficient to access matrices as columns
| rather than rows).
|
|
| On Wed, Mar 27, 2013 at 6:23 PM, Michael Love
| <michaelisaiahlove at gmail.com> wrote:
| > As recommended, I have switched to using Armadillo matrices, which
| doesn't
| > print out these lines.
| > ...
| > Example with Armadillo:
| >
| > arma.code <- '
| > arma::mat mat = Rcpp::as<arma::mat>(mat0);
| > arma::rowvec vec = Rcpp::as<arma::rowvec>(vec0);
| > for (int i = 0; i < mat.n_rows; i++) {
| > mat.row(i) = vec;
| > }
| > return Rcpp::wrap(mat);
| > '
| > arma.f <-
| > cxxfunction(signature(mat0="numeric",vec0="numeric"),arma.code,plugin=
| "RcppArmadillo")
| > arma.f(mat0,vec0)
|
|
|
| ----------------------------------------------------------------------
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
--
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
More information about the Rcpp-devel
mailing list