[Rcpp-devel] Assignment and extraction from a Vector in a templated function

Romain Francois romain at r-enthusiasts.com
Tue Jul 6 13:14:06 CEST 2010


Hi,

(just saw I did not pick this one up)

It might be one of those cases where we lack a const version of some 
operator. or maybe the compiler is confused about R_len_t

operator[] are defined as:

inline Proxy operator[]( const int& i ){ return cache.ref(i) ; }
inline Proxy operator[]( const int& i ) const { return cache.ref(i) ; }
	
so perhaps with :

x[ i ] ;

with x a Vector and i a R_len_t, the compiler finds it more suitable to 
convert x to a SEXP and use pointer arithmetics, which is usually the 
reason when it starts to complain about "forward declaration of 'struct 
SEXPREC'

Can you try with int ?
Should we move to use R_len_t as indexers ?

I do plan to have a sugar version of "rev". Actually I think I'll write 
it right after I press "send".

Perhaps we can also accomodate vector indexing so that we can do:

IntegerVector x ;
NumericVector y ;
NumericVector z = y[ x ] ;

We already have something that goes in this direction with the Range class:

"runit_Range" = list(
				signature(  ),
				'
					NumericVector xx(8) ;
					xx[ Range(0,3) ] = exp( seq_len(4) ) ;
					xx[ Range(4,7) ] = exp( - seq_len(4) ) ;
					return xx ;
				'	
			),
			

we can probably extend this to make it possible to index a vector by any 
integer sugar expression, probably also with logical expressions

Romain

Le 30/06/10 17:59, Douglas Bates a écrit :
>
> Apparently I have gotten too fancy in writing a templated function to
> apply a permutation to Rcpp::Vector classes.  The templates are at the
> end of lme4a/src/MatrixNs.h which can be obtained from R-forge under
> the lme4 project.  One of them is
>
>      class Permutation {
> 	Rcpp::IntegerVector d_perm;
> 	int n;
>      public:
> 	Permutation(Rcpp::IntegerVector&);
>
> 	template<int Rtype>
> 	Rcpp::Vector<Rtype>  forward(const Rcpp::Vector<Rtype>&) const;
> 	template<int Rtype>
> 	Rcpp::Vector<Rtype>  inverse(const Rcpp::Vector<Rtype>&) const;
> 	template<int Rtype>
> 	void inPlaceFwd(Rcpp::Vector<Rtype>&) const;
> 	template<int Rtype>
> 	void inPlaceInv(Rcpp::Vector<Rtype>&) const;
>      };
>
>      template<int Rtype>  inline
>      Rcpp::Vector<Rtype>  Permutation::forward(const
> Rcpp::Vector<Rtype>&  vv) const {
>      	if (vv.size() != n)
> 	    throw std::runtime_error("size mismatch in permutation");
> 	Rcpp::Vector<Rtype>  ans(n);
> 	int *ppt = d_perm.begin();
> 	for (R_len_t i = 0; i<  n; ++i) ans[i] = vv[ppt[i]];
> 	return ans;
>      }
>
> This code compiles under 32-bit and 64-bit Linux on R-forge but not
> under Windows or Mac OS X.  The compilation transcript under Windows
> 32-bit contains
>
> g++ -I"R:/R/R-patched/include"   -I"R:/R/lib/CRAN/2.11/Matrix/include"
> -I"R:/R/lib/CRAN/2.11/Rcpp/include"      -O2 -Wall  -c Permutation.cpp
> -o Permutation.o
> In file included from Permutation.cpp:1:0:
> MatrixNs.h: In member function 'Rcpp::Vector
> MatrixNs::Permutation::forward(const Rcpp::Vector&) const [with int
> Rtype = 13]':
> Permutation.cpp:32:49:   instantiated from here
> MatrixNs.h:274:34: error: invalid use of incomplete type 'struct SEXPREC'
> R:/R/R-patched/include/Rinternals.h:333:16: error: forward declaration
> of 'struct SEXPREC'
> Permutation.cpp:32:49:   instantiated from here
> MatrixNs.h:274:34: error: cannot convert 'SEXPREC' to
> 'Rcpp::traits::storage_type<13>::type' in assignment
> MatrixNs.h: In member function 'Rcpp::Vector
> MatrixNs::Permutation::inverse(const Rcpp::Vector&) const [with int
> Rtype = 13]':
> Permutation.cpp:33:27:   instantiated from here
> MatrixNs.h:284:34: error: invalid use of incomplete type 'struct SEXPREC'
> R:/R/R-patched/include/Rinternals.h:333:16: error: forward declaration
> of 'struct SEXPREC'
> MatrixNs.h:284:34: error: cannot convert 'SEXPREC' to
> 'Rcpp::traits::storage_type<13>::type' in assignment
> make: *** [Permutation.o] Error 1
>    ... done
>
> The function with the instantiation of forward is
>
>
> RCPP_FUNCTION_2(List, lme4_PermChk, IntegerVector perm, IntegerVector x) {
>      IntegerVector zerob = clone(perm); // modifiable copy
>      int bb = *(std::min_element(zerob.begin(), zerob.end()));
>      if (bb != 0)
> 	std::transform(zerob.begin(), zerob.end(), zerob.begin(),
> bind2nd(minus<int>(), bb));
>      MatrixNs::Permutation pp(zerob);
>      return List::create(_["forw"] = pp.forward(x),
> 			_["inv"] = pp.inverse(x));
> }
>
> I am not using this code at present and I think I will just remove it
> to see if I can get the rest of the package to compile under those
> unenlightened operating systems.  Still, I would be grateful if
> someone could point out a cleaner way of writing such code.  All I am
> doing is copying the elements of one Rcpp::Vector to another by
> reordering them according to the 0-based permutation in d_perm.
> _______________________________________________
> 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
>
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/98Uf7u : Rcpp 0.8.1
|- http://bit.ly/c6YnCi : graph gallery collage
`- http://bit.ly/bZ7ltC : inline 0.3.5



More information about the Rcpp-devel mailing list