[Rcpp-devel] Wrapping uBlas Matrices into Rcpp Matrices

Douglas Bates bates at stat.wisc.edu
Thu Jun 9 17:34:34 CEST 2011


On Thu, Jun 9, 2011 at 9:53 AM, Cedric Ginestet
<c.ginestet05 at googlemail.com> wrote:
> Thank you very much for this Romain, and sorry for the delay in testing
> that. Basically, I have tested it in my system and I get the following error
> messages
>
> //////////////////////////////////////////////////////////////////////////////
> // Matrices:
> template <typename Iterator>
>    Matrix( const int& nrows_, const int& ncols, Iterator start ) :
>        VECTOR( start, start + (nrows_*ncols) ),
>        nrows(nrows_)
>    {
>        VECTOR::attr( "dim" ) = Dimension( nrows, ncols ) ;
>    }
>
> template <typename T>
> Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >
> ublas2rcpp( const matrix<T>& x ){
>    return Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >(
>        x.size1(), x.size2(), x.begin1()
>    );
> }
> ///////////////////////////////////////////////////////////////////////////////////
>
> templatedFunction.h:60:65: error: ISO C++ forbids declaration of ‘Matrix’
> with no type
> templatedFunction.h: In function ‘int Matrix(const int&, const int&,
> Iterator)’:
> templatedFunction.h:61:9: error: only constructors take base initializers
> templatedFunction.h:64:9: error: ‘VECTOR’ has not been declared
> templatedFunction.h:64:44: error: ‘nrows’ was not declared in this scope

I'm currently checking on more general ways of using ublas with Rcpp
so perhaps I can take a look at this particular problem and save
Romain the trouble.

> On 06/06/11 12:55, Romain Francois wrote:
>>
>> Le 02/06/11 14:43, Cedric Ginestet a écrit :
>>>
>>> Hi again,
>>>
>>> I have tried to do the same for Matrices. Here my naive attempt:
>>> ////////////////////////////////////////////////////////////////
>>> template <typename T>
>>> Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >
>>> ublas2rcpp( const matrix<T>& x ){
>>> return Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >(
>>> x.begin(), x.end()
>>> );
>>> }
>>> //////////////////////////////////////////////////////////////
>>> Obviously that doesn't work, and I get the following error message:
>>> templatedFunction.h:63:5: error: ‘const class
>>> boost::numeric::ublas::matrix<int>’ has no member named ‘begin’
>>> templatedFunction.h:63:5: error: ‘const class
>>> boost::numeric::ublas::matrix<int>’ has no member named ‘end’
>>>
>>> I suppose that I either need to 'vectorized' the matrices or to run
>>> through both set of row and column indices. What is the best way to do
>>> so?
>>>
>>> Best wishes,
>>> Cedric
>>
>> Again untested, but you might like this constructor from Rcpp::Matrix:
>>
>>    template <typename Iterator>
>>    Matrix( const int& nrows_, const int& ncols, Iterator start ) :
>>        VECTOR( start, start + (nrows_*ncols) ),
>>        nrows(nrows_)
>>    {
>>        VECTOR::attr( "dim" ) = Dimension( nrows, ncols ) ;
>>    }
>>
>>
>> So you'd use it something like this:
>>
>>
>> template <typename T>
>> Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >
>> ublas2rcpp( const matrix<T>& x ){
>>    return Rcpp::Matrix< Rcpp::traits::r_sexptype_traits<T>::rtype >(
>>        x.size1(), x.size2(), x.begin1()
>>    );
>> }
>>
>> This is untested by guessing what would do the functions found in the
>> documentation of uBlas:
>> http://www.boost.org/doc/libs/1_42_0/libs/numeric/ublas/doc/matrix.htm
>>
>> Romain
>>
>>> On 01/06/11 14:14, Romain Francois wrote:
>>>>
>>>> Le 01/06/11 14:28, Cedric Ginestet a écrit :
>>>>>
>>>>> Dear Romain,
>>>>>
>>>>> Thank you very much for your help. I tried what you suggested by
>>>>> including the following templated function in templatedFunction.h, as
>>>>> follows:
>>>>> template <typename T>
>>>>> Rcpp::Vector< Rcpp::traits::r_sexptype_traits<T>::rtype >
>>>>> ublas2rcpp( const vector<T>& x ){
>>>>> return Rcpp::Vector< r_sexptype_traits<T>::rtype >(
>>>>> x.begin(), x.end()
>>>>> ) ;
>>>>> }
>>>>> In addition, I have tested the function using in subgraph.cpp:
>>>>> Rcpp::Vector<int> xY = ublas2rcpp(Y);
>>>>>
>>>>> And I got the following error messages:
>>>>> templatedFunction.h: In function
>>>>> ‘Rcpp::Vector<Rcpp::traits::r_sexptype_traits<T>::rtype>
>>>>> ublas2rcpp(const boost::numeric::ublas::vector<T>&)’:
>>>>> templatedFunction.h:50:26: error: ‘r_sexptype_traits’ was not declared
>>>>> in this scope
>>>>> templatedFunction.h:50:45: error: template argument 1 is invalid
>>>>> subgraph.cpp: In function ‘SEXPREC* cxx_Mask2Graph(SEXPREC*, SEXPREC*,
>>>>> SEXPREC*, SEXPREC*)’:
>>>>> subgraph.cpp:32:19: error: type/value mismatch at argument 1 in
>>>>> template
>>>>> parameter list for ‘template<int RTYPE> class Rcpp::Vector’
>>>>> subgraph.cpp:32:19: error: expected a constant of type ‘int’, got ‘int’
>>>>> subgraph.cpp:32:24: error: invalid type in declaration before ‘=’ token
>>>>> subgraph.cpp:32:38: error: invalid conversion from ‘SEXPREC*’ to ‘int’
>>>>> subgraph.cpp:34:8: error: invalid conversion from ‘int’ to ‘SEXPREC*’
>>>>> ...
>>>>
>>>> Sure. This was a typo/thinko: go with something like this :
>>>>
>>>> template <typename T>
>>>> Rcpp::Vector< Rcpp::traits::r_sexptype_traits<T>::rtype >
>>>> ublas2rcpp( const vector<T>& x ){
>>>> return Rcpp::Vector< Rcpp::traits::r_sexptype_traits<T>::rtype >(
>>>> x.begin(), x.end()
>>>> ) ;
>>>> }
>>>>
>>>> and Rcpp::Vector<int> makes no sense, you probably want IntegerVector,
>>>> or (the same class):
>>>>
>>>> Rcpp::Vector< r_sexptype_traits<int>::rtype >
>>>>
>>>> Rcpp::Vector is templated by the SEXP type.
>>>>
>>>>> Also, as an aside, I was wondering what I should use instead of
>>>>> push_back for Rcpp Vectors. Do I necessarily have to specify the size
>>>>> of
>>>>> the vector before I assign its elements to specific values?
>>>>
>>>> That is much better yes. ublas probably gives a way to access the size
>>>> of the vector.
>>>>
>>>>> Thanks a lot,
>>>>> Cedric
>>>>>
>>>>>
>>>>> On 01/06/11 11:44, Romain Francois wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I've not used uBlas, but what you are trying to do is quite similar to
>>>>>> what we do in RcppArmadillo.
>>>>>>
>>>>>> You can probably manage to guess the output type from the input type,
>>>>>> so you only have to parameterise your template on the input type.
>>>>>> something like (untested) :
>>>>>>
>>>>>> template <typename T>
>>>>>> Rcpp::Vector< Rcpp::traits::r_sexptype_traits<T>::rtype >
>>>>>> ublas2rcpp( const vector<T>& x ){
>>>>>> return Rcpp::Vector< r_sexptype_traits<T>::rtype >(
>>>>>> x.begin(), x.end()
>>>>>> ) ;
>>>>>> }
>>>>>>
>>>>>> This way you don't have to specify template parameter when you call
>>>>>> ublas2rcpp because the compiler is smart enough.
>>>>>>
>>>>>> Nicer than this would be to implement wrap and as for ublas vectors,
>>>>>> the way to go is documented in the Rcpp-extended vignettes, with
>>>>>> examples implementations in RcppArmadillo and RcppGSL.
>>>>>>
>>>>>> As a side note, you don't want to use push_back on Rcpp types, because
>>>>>> it creates a new vector each time, so this is HUGE memory waste.
>>>>>>
>>>>>> Now, this could get much smarter as ublas has vector expressions,
>>>>>> similar to armadillo, so I suppose someone could write something like
>>>>>> RcppUBlas with nice goodies. This is not me, at least not now ;-)
>>>>>>
>>>>>> Romain
>>>>>>
>>>>>>
>>>>>> Le 01/06/11 12:24, Cedric Ginestet a écrit :
>>>>>>>
>>>>>>> Dear Rcpp experts,
>>>>>>>
>>>>>>> I have started to use the uBlas library, and I am trying to ensure
>>>>>>> that
>>>>>>> I can pass from uBlas vectors to Rcpp vectors relatively easily. So
>>>>>>> far,
>>>>>>> I have tried the following templated function:
>>>>>>>
>>>>>>>
>>>>>>> ///////////////////////////////////////////////////////////////////////
>>>>>>>
>>>>>>> using namespace Rcpp;
>>>>>>> using namespace boost::numeric::ublas;
>>>>>>>
>>>>>>> template <class T1, class T2>
>>>>>>> T1 ublas2rcpp(T2& uVec){
>>>>>>> T1 rcppVec;
>>>>>>> for(int i=0; i<uVec.size(); ++i) rcppVec.push_back(uVec(i));
>>>>>>> return rcppVec;
>>>>>>> }//ublas2rcpp.
>>>>>>>
>>>>>>> ////////
>>>>>>> SEXP foo(vector<int> &y){
>>>>>>> ...
>>>>>>> IntegerVector rcppY=ublas2rcpp<IntegerVector,vector<int> >(y);
>>>>>>> ....
>>>>>>> return rcppY;
>>>>>>> }
>>>>>>>
>>>>>>> ///////////////////////////////////////////////////////////////////////
>>>>>>>
>>>>>>>
>>>>>>> I have got two questions:
>>>>>>> a. This templated function doesn't work. It compiles fine, but hangs
>>>>>>> when I try to run it in R. What do you think is faulty in the codes
>>>>>>> above?
>>>>>>> b. Is there a better way to wrap uBlas vectors into Rcpp ones? Is
>>>>>>> that
>>>>>>> something that you are planning to implement (or have already
>>>>>>> implemented) within the Rcpp suite?
>>>>>>>
>>>>>>> Thank you very much for your help,
>>>>>>>
>>>>>>> --
>>>>>>> Cedric Ginestet, PhD
>>>>>>> Centre for Neuroimaging Sciences (L3.04)
>>>>>>> NIHR Biomedical Research Centre
>>>>>>> Department of Neuroimaging
>>>>>>> Institute of Psychiatry, Box P089
>>>>>>> King's College London
>>>>>>> De Crespigny Park
>>>>>>> London
>>>>>>> SE5 8AF
>>>>>>> http://arxiv.org/find/q-bio/1/au:+Ginestet_C/0/1/0/all/0/1
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
> _______________________________________________
> 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