-
-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Second pass at Rcpp::algorithm #481
Conversation
Will peruse. |
@eddelbuettel asked me to send a motivating reason for all of this so here it is:
See this example: namespace Rcpp{
namespace sugar{
template <int RTYPE, bool NA, typename T>
class Min {
public:
typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ;
Min( const T& obj_) : obj(obj_) {}
operator STORAGE() const {
STORAGE min, current ;
min = obj[0] ;
if( Rcpp::traits::is_na<RTYPE>( min ) ) return min ;
R_xlen_t n = obj.size() ;
for( R_xlen_t i=1; i<n; i++){
current = obj[i] ;
if( Rcpp::traits::is_na<RTYPE>( current ) ) return current;
if( current < min ) min = current ;
}
return min ;
}
const T& obj ;
} ;
// version for NA = false
template <int RTYPE, typename T>
class Min<RTYPE,false,T> {
public:
typedef typename Rcpp::traits::storage_type<RTYPE>::type STORAGE ;
Min( const T& obj_) : obj(obj_) {}
operator STORAGE() const {
STORAGE min, current ;
min = obj[0] ;
R_xlen_t n = obj.size() ;
for( R_xlen_t i=1; i<n; i++){
current = obj[i] ;
if( current < min ) min = current ;
}
return min ;
}
const T& obj ;
} ;
} // sugar
template <int RTYPE, bool NA, typename T>
sugar::Min<RTYPE,NA,T> min( const VectorBase<RTYPE,NA,T>& x){
return sugar::Min<RTYPE,NA,T>(x.get_ref()) ;
}
} // Rcpp First off we have here the Additionally, I just recently had to add the Finally, the namespace Rcpp
{
template< int RTYPE, typename T >
typename traits::storage_type< RTYPE >::type min(const Vector< RTYPE, true, T> &v) {
return Rcpp::algorithm::min(v.begin(), v.end());
}
template< int RTYPE, typename T >
typename traits::storage_type< RTYPE >::type min(const Vector< RTYPE, false, T> &v) {
return Rcpp::algorithm::min_nona(v.begin(), v.end());
}
} // namespace Rcpp This also gives the freedom to either the user (or the implementers) to do something equivalent to: arma::vec minByRow(const NumericMatrix &m) {
arma::colvec retval(m.nrow());
for (R_xlen_t i = 0; i < m.nrow(); ++i) {
retval[i] = algorithm::min(m.Row(i).begin(), m.Row(i).end());
}
return retval;
} These could either be easy-to-maintain extensions of Either way, I think the STL got it right here and we should use a similar pattern to what has been presented to us by the language for executing "algorithms" on our data structures. |
I decided to leave this point out because this is an This can also be used to apply R "algorithms" to any iterator based structure. Specifically |
FWIW, I think there were two main motivations behind the Rcpp sugar work:
Overall, this makes Rcpp a lot more accessible to R developers new to C++, which I think is something we'd like to keep Rcpp tailored towards when possible. That said, I do think that having iterator-based algorithm methods will be useful, but these are somewhat more 'expert-friendly' (coming from the perspective of an R user). |
… the primitive arithmetic types or to std::string and applied this to the current algorithms.
I buy the expression templates, but I am suspicious of whether it's been done correctly. Just looking at the So, I guess I will amend my earlier comments to suggest that things that aren't really expression templates should not be implemented to look like they are. They should just be implemented as the functions that they are. This applies mostly to things in |
…an be passed to these functions
Sounds good! |
Now that the conference week is behind me, some more time for Rcpp. This PR is purely additive with new code, does not alter any existing interfaces, and adds tests. No reason not to like it. In it goes then. |
So here's a second pass (with an existing fork behind it) at implementing some iterator-based algorithms for Rcpp. Implemented so far for real types (to be extended) are:
At this point I need some other eyes on this, specifically with regards to the unit tests. These need to be as complete as possible and any help is welcome.