[Rcpp-devel] Wrapping uBlas Matrices into Rcpp Matrices

Cedric Ginestet c.ginestet05 at googlemail.com
Thu Jun 9 16:53:36 CEST 2011


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

//////////////////////////////////////////////////////////////////////////////////

Cheers,
Cedric


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
>>>>>
>>>>
>>>
>>>
>>
>
>


More information about the Rcpp-devel mailing list