[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