[Rcpp-devel] problem compiling with const in RcppEigen

M A markoilcan at gmail.com
Fri Feb 1 17:26:45 CET 2013


Yes, I can understand why it's not clear what the Cm_class is for (I
did take out all the linear algebra and other parts of the class).
That is, after all, a consequence of creating a minimal example. And,
I am also happy to declare functions as you do. The point is, though,
that the typedef used in the function definition does not work with
the constructor for the Cm_class, even though they are conceptually
the same thing. I appreciate your interest in what the purpose of the
code is, but it's probably not worth trying to explain the reasons for
why it's designed they way it is. I can already work around the
problem, for instance by using two different typedefs and making sure
they mesh properly at the right points (though it's annoying to have
two different typedefs for a single conceptual thing), or other things
I mentioned previously.

The fundamental problem is, as you said, that RcppEigen doesn't know
how to form an Eigen::Map<const Eigen::MatrixXd> with the as function.
Unfortunately, this is the only way of creating a read-only mapping
from a constant pointer (i.e. const double*) in Eigen (see below
code). So, when 'as' operates I need to use a const Map<MatrixXd>, but
when I want to create my own read-only mapping from a constant pointer
I need a Map< const MatrixXd>, hence two different typedefs even
though they're really supposed to be the same thing.

In Eigen this works:
const double *p=&somearray;
Map<const MatrixXd> mapping(p, n, n);

In Eigen this doesn't work: (maybe there's an argument to make Eigen allow this)
const double *p=&somearray;
const Map<MatrixXd> mapping(p, n, n);



On Thu, Jan 31, 2013 at 2:38 PM, Douglas Bates <bates at stat.wisc.edu> wrote:
> Sorry but I am still struggling (even after reformatting the source code) to
> understand what the problem is.  For one thing it is not clear to me what
> the Cm_class is for.
>
> The fundamental rule for me is that I always declare functions like
>
> //[[Rcpp::Export]]
> Eigen::VectorXd testfunc(const MapVecd ytrait, const MapMatd xmat) {
>    ...
> }
>
> If you need to get a pointer to the contents of the matrix you could use a
> const_cast but in that case I don't understand why you would use the Eigen
> classes.  If all you want is the dimensions and a pointer to the contents
> you should use NumericMatrix class.
>
>
>
> On Thu, Jan 31, 2013 at 1:27 PM, M A <markoilcan at gmail.com> wrote:
>>
>> Right. The problem comes up because of the constructor with one of my
>> classes. Here is a slightly extended minimal example:
>>
>> // [[Rcpp::depends(RcppEigen)]]
>>
>> #include <RcppEigen.h>
>> #include <Rcpp.h>
>>
>> typedef Eigen::Map<Eigen::VectorXd> MapVecd;
>> typedef Eigen::Map<Eigen::MatrixXd> MapMatd; // (A). This one works
>> with (1) below
>> //typedef Eigen::Map<const Eigen::MatrixXd> MapMatd; // (B). This one
>> fails with (1) below
>>
>> class Cm_class {
>> public:
>>     const MapMatd c_matrix;
>>
>>     //Cm_class( double *p_pdmat, const int nr, const int nc ) : //
>> Works with (A) or (B)
>>     Cm_class( const double *p_pdmat, const int nr, const int nc ) : //
>> Works with (B) fails with (A)
>>         c_matrix(p_pdmat, nr, nc) {}
>> };
>>
>> //Eigen::VectorXd testfunc(const MapVecd ytrait, MapMatd xmat) { //
>> (1). This only works with (A)
>> // [[Rcpp::export]]
>> Eigen::VectorXd testfunc(const MapVecd ytrait) {
>>
>>     return ytrait;
>> }
>>
>> I really want testfunc to be as in (1) where xmat gets mapped into a
>> double matrix, though I take it out above for simplicity. I have my
>> class constructor taking a const double*, but that fails with the
>> typedef (A), the way you recommend. To get that constructor
>> initialization to work I have to use typedef (B), but that causes
>> failure with (1), which is what I was originally writing about. I can
>> certainly work around this by removing the const from the double* in
>> the class constructor, etc, but I guess there's the larger question of
>> whether the RcppEigen 'as' function should be able to form an
>> Eigen::Map<const Eigen::MatrixXd>. Thanks for the info regarding the
>> point of failure.
>>
>> Mark A
>>
>> On Thu, Jan 31, 2013 at 11:34 AM, Douglas Bates <bates at stat.wisc.edu>
>> wrote:
>> > I should check the syntax before sending the message.
>> >
>> > On Thu, Jan 31, 2013 at 11:30 AM, Douglas Bates <bates at stat.wisc.edu>
>> > wrote:
>> >>
>> >> The as function in RcppEigen can form an
>> >>
>> >> Eigen::Map<Eigen::MatrixXd>
>> >>
>> >> but doesn't know how to form an
>> >>
>> >> Eigen::Map<const Eigen::MatrixXd>
>> >>
>> >> Generally I find that I confuse myself less when the const is outside
>> >> the
>> >> Eigen::Map.  In other words, I use something like
>> >>
>> >> typedef Eigen::Map<Eigen::MatrixXd> mMat;
>> >>
>> >> const mMat M(mat_from_R);
>> >
>> >
>> > That should be
>> >
>> > const mMat M = as<mMat>(mat_from_R);
>> >
>> > Well, at least I think so.
>> >
>> > The bottom line is that I find it easier to use const in the declaration
>> > of
>> > an instance of a class, not in the typedef.
>> >>
>> >>
>> >> This tells me that M is a mapped MatrixXd object which is constructed
>> >> from
>> >> the SEXP mat_from_R and is read-only.
>> >>
>> >>
>> >>
>> >> On Thu, Jan 31, 2013 at 11:01 AM, M A <markoilcan at gmail.com> wrote:
>> >>>
>> >>> I am compiling some source code using sourceCpp and getting a
>> >>> compiling failure when the source has the line with the const keyword
>> >>> but no failure when it does not, in the below source.
>> >>>
>> >>> // file: minimaltest.cpp
>> >>> // [[Rcpp::depends(RcppEigen)]]
>> >>>
>> >>> #include <RcppEigen.h>
>> >>> #include <Rcpp.h>
>> >>>
>> >>> typedef Eigen::Map<Eigen::VectorXd> MapVecd;
>> >>> //typedef Eigen::Map<Eigen::MatrixXd> MapMatd; // This one works
>> >>> typedef Eigen::Map<const Eigen::MatrixXd> MapMatd; // This one fails
>> >>>
>> >>> // [[Rcpp::export]]
>> >>> Eigen::VectorXd testfunc(const MapVecd ytrait, MapMatd xmat) {
>> >>>
>> >>>     return ytrait;
>> >>> }
>> >>>
>> >>> This is the error:
>> >>>
>> >>> > sourceCpp("minimaltest.cpp")
>> >>> g++ -arch x86_64 -I/Library/Frameworks/R.framework/Resources/include
>> >>> -I/Library/Frameworks/R.framework/Resources/include/x86_64 -DNDEBUG
>> >>> -I/usr/local/include
>> >>>
>> >>>
>> >>> -I"/Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include"
>> >>>
>> >>>
>> >>> -I"/Library/Frameworks/R.framework/Versions/2.15/Resources/library/RcppEigen/include"
>> >>>   -fPIC  -g -O2  -c minimaltest.cpp -o minimaltest.o
>> >>> Error in sourceCpp("minimaltest.cpp") :
>> >>>   Error 1 occurred building shared library.
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/Rcpp/internal/Exporter.h:
>> >>> In constructor ‘Rcpp::traits::Exporter<T>::Exporter(SEXPREC*) [with T
>> >>> = Eigen::Map<const Eigen::Matrix<double, -0x00000000000000001,
>> >>> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>,
>> >>> 0, Eigen::Stride<0, 0> >]’:
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/Rcpp/as.h:67:
>> >>>   instantiated from ‘T Rcpp::internal::as(SEXPREC*,
>> >>> Rcpp::traits::r_type_generic_tag) [with T = Eigen::Map<const
>> >>> Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001, 0,
>> >>> -0x00000000000000001, -0x00000000000000001>, 0, Eigen::Stride<0, 0>
>> >>> >]’
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/Rcpp/as.h:112:
>> >>>   instantiated from ‘T Rcpp::as(SEXPREC*) [with T = Eigen::Map<const
>> >>> Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001, 0,
>> >>> -0x00000000000000001, -0x00000000000000001>, 0, Eigen::Stride<0, 0>
>> >>> >]’
>> >>> minimaltest.cpp:35:   instantiated from here
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/Rcpp/include/Rcpp/internal/Exporter.h:31:
>> >>> error: no matching function for call to ‘Eigen::Map<const
>> >>> Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001, 0,
>> >>> -0x00000000000000001, -0x00000000000000001>, 0, Eigen::Stride<0, 0>
>> >>> >::Map(SEXPREC*&)’
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/RcppEigen/include/Eigen/src/Core/Map.h:164:
>> >>> note: candidates are: Eigen::Map<MatrixType, MapOptions,
>> >>> StrideType>::Map(typename Eigen::MapBase<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType>,
>> >>> (Eigen::internal::accessors_level<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType> >::has_write_access ?  WriteAccessors :
>> >>> ReadOnlyAccessors)>::PointerType, typename
>> >>> Eigen::internal::traits<Eigen::Map<PlainObjectType, MapOptions,
>> >>> StrideType> >::Index, typename
>> >>> Eigen::internal::traits<Eigen::Map<PlainObjectType, MapOptions,
>> >>> StrideType> >::Index, const StrideType&) [with PlainObjectType = const
>> >>> Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001, 0,
>> >>> -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0,
>> >>> StrideType = Eigen::Stride<0, 0>]
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/RcppEigen/include/Eigen/src/Core/Map.h:151:
>> >>> note:                 Eigen::Map<MatrixType, MapOptions,
>> >>> StrideType>::Map(typename Eigen::MapBase<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType>,
>> >>> (Eigen::internal::accessors_level<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType> >::has_write_access ?  WriteAccessors :
>> >>> ReadOnlyAccessors)>::PointerType, typename
>> >>> Eigen::internal::traits<Eigen::Map<PlainObjectType, MapOptions,
>> >>> StrideType> >::Index, const StrideType&) [with PlainObjectType = const
>> >>> Eigen::Matrix<double, -0x00000000000000001, -0x00000000000000001, 0,
>> >>> -0x00000000000000001, -0x00000000000000001>, int MapOptions = 0,
>> >>> StrideType = Eigen::Stride<0, 0>]
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/RcppEigen/include/Eigen/src/Core/Map.h:139:
>> >>> note:                 Eigen::Map<MatrixType, MapOptions,
>> >>> StrideType>::Map(typename Eigen::MapBase<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType>,
>> >>> (Eigen::internal::accessors_level<Eigen::Map<PlainObjectType,
>> >>> MapOptions, StrideType> >::has_write_access ?  WriteAccessors :
>> >>> ReadOnlyAccessors)>::PointerType, const StrideType&) [with
>> >>> PlainObjectType = const Eigen::Matrix<double, -0x00000000000000001,
>> >>> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>,
>> >>> int MapOptions = 0, StrideType = Eigen::Stride<0, 0>]
>> >>>
>> >>>
>> >>> /Library/Frameworks/R.framework/Versions/2.15/Resources/library/RcppEigen/include/Eigen/src/Core/Map.h:106:
>> >>> note:                 Eigen::Map<const Eigen::Matrix<double,
>> >>> -0x00000000000000001, -0x00000000000000001, 0, -0x00000000000000001,
>> >>> -0x00000000000000001>, 0, Eigen::Stride<0, 0> >::Map(const
>> >>> Eigen::Map<const Eigen::Matrix<double, -0x00000000000000001,
>> >>> -0x00000000000000001, 0, -0x00000000000000001, -0x00000000000000001>,
>> >>> 0, Eigen::Stride<0, 0> >&)
>> >>> make: *** [minimaltest.o] Error 1
>> >>>
>> >>> Here is my session info:
>> >>> > sessionInfo()
>> >>> R version 2.15.2 (2012-10-26)
>> >>> Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)
>> >>>
>> >>> locale:
>> >>> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
>> >>>
>> >>> attached base packages:
>> >>> [1] stats     graphics  grDevices utils     datasets  methods   base
>> >>>
>> >>> other attached packages:
>> >>> [1] RcppEigen_0.3.1.2 Matrix_1.0-9      lattice_0.20-10   Rcpp_0.10.2
>> >>>
>> >>> loaded via a namespace (and not attached):
>> >>> [1] grid_2.15.2  tools_2.15.2
>> >>>
>> >>> Note that the g++... portion works fine on the command line, so I
>> >>> guess the failure is somewhere in the building of the library. Of
>> >>> course I can get around this by not using the const keyword, but why
>> >>> is there a problem and what is the right fix?
>> >>>
>> >>> Thanks,
>> >>> Mark A
>> >>> _______________________________________________
>> >>> 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
>> >>
>> >>
>> >
>
>


More information about the Rcpp-devel mailing list