Hi,
I am trying to return several Armadillo matrices back to R and to set
the names for the rows and the columns of each matrix. I have tried
converting each Armadillo matrix to a NumericMatrix and then setting
the dimnames on that before returning a list to R. This seems to work
(see snippet below) however I am not sure if this is the right way to
go or if I am converting the matrices properly or if extra copies are
being made. Any advice will be appreciated.
library(RcppArmadillo)
library(inline)
a <- matrix(c(0.5,0.1,0.1,0.5),nrow=2)
code <- '
arma::mat coeff = Rcpp::as<arma::mat>(a);
coeff %= coeff; // some arma calculations
Rcpp::CharacterVector names = Rcpp::CharacterVector::create("a", "b");
Rcpp::NumericVector rcoeff(wrap(coeff)); // convert to Rcpp?
rcoeff.attr("dimnames") = Rcpp::List::create(names, names);
return Rcpp::List::create(Rcpp::Named("coeff") = rcoeff);
'
testfunc <- cxxfunction(signature(a="numeric"), code,
plugin="RcppArmadillo")
testfunc(a)
Thanks in advance.
Regards
Sameer
[Rcpp-devel] Returning Armadillo matrices with dimnames
8 messages · Sameer D'Costa, Dirk Eddelbuettel, Krzysztof Sakrejda
Hi Sameer,
On 2 May 2013 at 10:16, Sameer D'Costa wrote:
| Hi,
|
| I am trying to return several Armadillo matrices back to R and to set
| the names for the rows and the columns of each matrix. I have tried
| converting each Armadillo matrix to a NumericMatrix and then setting
| the dimnames on that before returning a list to R. This seems to work
| (see snippet below) however I am not sure if this is the right way to
| go or if I am converting the matrices properly or if extra copies are
| being made. Any advice will be appreciated.
That looks pretty good. I would simply change to things:
-- on entry, create an Armadillo matrix "two-step-way" we have been using
here a lot (and which is used eg in fastLm.cpp): create a NumericMatrix
from SEXP (no copies), then instantiate arma::mat() using the begin()
iterator, row, cols and FALSE --- and that way you are sure that only
pointers to the original memory get copied, and the content itself should
not.
-- on exit, do the reverse: do you Armadillo calculations, then access the
memory behind the arma matrix (also guaranteed to be contiguous) to
instantiate an Rcpp NumericMatrix. Then set the attributes as you do
below and return it.
That should be the most efficient way to go about it while also setting
dimnames.
Dirk
|
| library(RcppArmadillo)
| library(inline)
|
| a <- matrix(c(0.5,0.1,0.1,0.5),nrow=2)
|
| code <- '
| arma::mat coeff = Rcpp::as<arma::mat>(a);
| coeff %= coeff; // some arma calculations
|
| Rcpp::CharacterVector names = Rcpp::CharacterVector::create("a", "b");
|
| Rcpp::NumericVector rcoeff(wrap(coeff)); // convert to Rcpp?
| rcoeff.attr("dimnames") = Rcpp::List::create(names, names);
|
| return Rcpp::List::create(Rcpp::Named("coeff") = rcoeff);
| '
|
| testfunc <- cxxfunction(signature(a="numeric"), code,
| plugin="RcppArmadillo")
|
| testfunc(a)
|
|
| Thanks in advance.
|
| Regards
| Sameer
| _______________________________________________
| 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
Thanks for the reply Dirk.
On Thu, May 2, 2013 at 12:53 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
Hi Sameer,
On 2 May 2013 at 10:16, Sameer D'Costa wrote:
| Hi,
|
| I am trying to return several Armadillo matrices back to R and to set
| the names for the rows and the columns of each matrix. I have tried
| converting each Armadillo matrix to a NumericMatrix and then setting
| the dimnames on that before returning a list to R. This seems to work
| (see snippet below) however I am not sure if this is the right way to
| go or if I am converting the matrices properly or if extra copies are
| being made. Any advice will be appreciated.
That looks pretty good. I would simply change to things:
-- on entry, create an Armadillo matrix "two-step-way" we have been using
here a lot (and which is used eg in fastLm.cpp): create a NumericMatrix
from SEXP (no copies), then instantiate arma::mat() using the begin()
iterator, row, cols and FALSE --- and that way you are sure that only
pointers to the original memory get copied, and the content itself should
not.
-- on exit, do the reverse: do you Armadillo calculations, then access the
memory behind the arma matrix (also guaranteed to be contiguous) to
instantiate an Rcpp NumericMatrix. Then set the attributes as you do
below and return it.
I understand how to do the entry based on what fastLm.cpp is doing. I'm more interested in the exit because in my real work I have the matrices generated in c++ itself. I put the entry code just to have a self contained inline example to send to the list. However, I'm not sure how to do the exit in the way you describe. Would you be able to tell me how to use the relevant NumericMatrix constructor or point me to an example somewhere? Thanks. Rgds
On 2 May 2013 at 14:33, Sameer D'Costa wrote:
| Thanks for the reply Dirk. |
| On Thu, May 2, 2013 at 12:53 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
| > | > Hi Sameer, | >
| > On 2 May 2013 at 10:16, Sameer D'Costa wrote:
| > | Hi, | > | | > | I am trying to return several Armadillo matrices back to R and to set | > | the names for the rows and the columns of each matrix. I have tried | > | converting each Armadillo matrix to a NumericMatrix and then setting | > | the dimnames on that before returning a list to R. This seems to work | > | (see snippet below) however I am not sure if this is the right way to | > | go or if I am converting the matrices properly or if extra copies are | > | being made. Any advice will be appreciated. | > | > That looks pretty good. I would simply change to things: | > | > -- on entry, create an Armadillo matrix "two-step-way" we have been using | > here a lot (and which is used eg in fastLm.cpp): create a NumericMatrix | > from SEXP (no copies), then instantiate arma::mat() using the begin() | > iterator, row, cols and FALSE --- and that way you are sure that only | > pointers to the original memory get copied, and the content itself should | > not. | > -- on exit, do the reverse: do you Armadillo calculations, then access the | > memory behind the arma matrix (also guaranteed to be contiguous) to | > instantiate an Rcpp NumericMatrix. Then set the attributes as you do | > below and return it. | | I understand how to do the entry based on what fastLm.cpp is doing. | I'm more interested in the exit because in my real work I have the | matrices generated in c++ itself. I put the entry code just to have a | self contained inline example to send to the list. However, I'm not | sure how to do the exit in the way you describe. Would you be able to | tell me how to use the relevant NumericMatrix constructor or point me | to an example somewhere? Thanks.
From a quick look at the header file Matrix.h it seems that
template <typename Iterator>
Matrix( const int& nrows_, const int& ncols, Iterator start ) ;
should be what you are after. (The various types are just typedefs to the
templated variants of Matrix for int, double, char, ...)
But do check the source file to be sure and maybe do a quick performance for
both 'small' and 'large' matrices -- run-time should be constant if there are
only pointer copies.
Dirk
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
On Thu, May 2, 2013 at 3:06 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
On 2 May 2013 at 14:33, Sameer D'Costa wrote:
| Thanks for the reply Dirk.
|
| On Thu, May 2, 2013 at 12:53 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
| >
| > Hi Sameer,
| >
| > On 2 May 2013 at 10:16, Sameer D'Costa wrote:
| > | Hi,
| > |
| > | I am trying to return several Armadillo matrices back to R and to set
| > | the names for the rows and the columns of each matrix. I have tried
| > | converting each Armadillo matrix to a NumericMatrix and then setting
| > | the dimnames on that before returning a list to R. This seems to work
| > | (see snippet below) however I am not sure if this is the right way to
| > | go or if I am converting the matrices properly or if extra copies are
| > | being made. Any advice will be appreciated.
| >
| > That looks pretty good. I would simply change to things:
| >
| > -- on entry, create an Armadillo matrix "two-step-way" we have been using
| > here a lot (and which is used eg in fastLm.cpp): create a NumericMatrix
| > from SEXP (no copies), then instantiate arma::mat() using the begin()
| > iterator, row, cols and FALSE --- and that way you are sure that only
| > pointers to the original memory get copied, and the content itself should
| > not.
| > -- on exit, do the reverse: do you Armadillo calculations, then access the
| > memory behind the arma matrix (also guaranteed to be contiguous) to
| > instantiate an Rcpp NumericMatrix. Then set the attributes as you do
| > below and return it.
|
| I understand how to do the entry based on what fastLm.cpp is doing.
| I'm more interested in the exit because in my real work I have the
| matrices generated in c++ itself. I put the entry code just to have a
| self contained inline example to send to the list. However, I'm not
| sure how to do the exit in the way you describe. Would you be able to
| tell me how to use the relevant NumericMatrix constructor or point me
| to an example somewhere? Thanks.
From a quick look at the header file Matrix.h it seems that
template <typename Iterator>
Matrix( const int& nrows_, const int& ncols, Iterator start ) ;
should be what you are after. (The various types are just typedefs to the
templated variants of Matrix for int, double, char, ...)
But do check the source file to be sure and maybe do a quick performance for
both 'small' and 'large' matrices -- run-time should be constant if there are
only pointer copies.
I tried this constructor and it looks like it does make a copy. (line 119 of Rcpp/inst/include/Rcpp/api/meat/Vector.h if I am reading it correctly). Also looks like the run time does increase significantly as the dimension increases. Oh well. never mind. Thanks.
On 2 May 2013 at 16:37, Sameer D'Costa wrote:
| > From a quick look at the header file Matrix.h it seems that | > | > template <typename Iterator> | > Matrix( const int& nrows_, const int& ncols, Iterator start ) ; | > | > should be what you are after. (The various types are just typedefs to the | > templated variants of Matrix for int, double, char, ...) | > | > But do check the source file to be sure and maybe do a quick performance for | > both 'small' and 'large' matrices -- run-time should be constant if there are | > only pointer copies. | | I tried this constructor and it looks like it does make a copy. (line | 119 of Rcpp/inst/include/Rcpp/api/meat/Vector.h if I am reading it | correctly). Also looks like the run time does increase significantly | as the dimension increases. Oh well. never mind. Thanks. Sorry. It was just a quick guess. On second thought, I think your earlier approach was actually pretty good: Take your arma object, use wrap to turn it into a SEXP (or maybe an RObject) and you should then be able to set attributes. Dirk
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
On 2 May 2013 at 17:24, Dirk Eddelbuettel wrote:
| Sorry. It was just a quick guess.
|
| On second thought, I think your earlier approach was actually pretty good:
| Take your arma object, use wrap to turn it into a SEXP (or maybe an RObject)
| and you should then be able to set attributes.
And on third thought, I think we both overlooked one aspect:
-- R and Rcpp can share objects, passing them back and forth efficiently via
pointers as _both use the same allocation scheme_. So when Rcpp creates
an object, it is "as if" R created it. Which is why we can generally
move them back and forth.
-- That does not hold for Armadillo. So to bring an Armadillo object back,
we are better off making a copy.
So once again the "No Free Lunch" theorem at work. Sorry.
Dirk
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
On May 2, 2013 11:22 PM, "Dirk Eddelbuettel" <edd at debian.org> wrote:
On 2 May 2013 at 17:24, Dirk Eddelbuettel wrote: | Sorry. It was just a quick guess. | | On second thought, I think your earlier approach was actually pretty
good:
| Take your arma object, use wrap to turn it into a SEXP (or maybe an
RObject)
| and you should then be able to set attributes. And on third thought, I think we both overlooked one aspect: -- R and Rcpp can share objects, passing them back and forth efficiently
via
pointers as _both use the same allocation scheme_. So when Rcpp
creates
an object, it is "as if" R created it. Which is why we can generally
move them back and forth.
-- That does not hold for Armadillo. So to bring an Armadillo object
back,
we are better off making a copy.
Depending on the context, you could pre-create both matrices in R and pass them in to Rcpp/Armadillo as Dirk suggests. Manipulate them as necessary and they are available back in R when you are done. Krzysztof
So once again the "No Free Lunch" theorem at work. Sorry. Dirk -- Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
_______________________________________________ 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
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20130503/8249c17d/attachment.html>