[Rcpp-devel] fill a NumericMatrix row by row
Michael Love
michaelisaiahlove at gmail.com
Wed Mar 27 12:06:38 CET 2013
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:
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)
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130327/fb13618d/attachment.html>
More information about the Rcpp-devel
mailing list