[Rcpp-commits] r1789 - in pkg/Rcpp/inst: . include/Rcpp/sugar/functions unitTests
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Jul 6 14:16:39 CEST 2010
Author: romain
Date: 2010-07-06 14:16:38 +0200 (Tue, 06 Jul 2010)
New Revision: 1789
Modified:
pkg/Rcpp/inst/ChangeLog
pkg/Rcpp/inst/include/Rcpp/sugar/functions/ifelse.h
pkg/Rcpp/inst/unitTests/runit.sugar.R
Log:
ifelse improvements
Modified: pkg/Rcpp/inst/ChangeLog
===================================================================
--- pkg/Rcpp/inst/ChangeLog 2010-07-05 22:16:27 UTC (rev 1788)
+++ pkg/Rcpp/inst/ChangeLog 2010-07-06 12:16:38 UTC (rev 1789)
@@ -1,3 +1,9 @@
+2010-07-06 Romain Francois <romain at r-enthusiasts.com>
+
+ * inst/include/Rcpp/sugar/functions/ifelse.h: using compile time dispatch
+ based on the NA-ness of the condition type. ifelse handles primitive
+ arguments on the lhs, rhs or both
+
2010-07-05 Romain Francois <romain at r-enthusiasts.com>
* inst/include/Rcpp/RcppCommon.h : no more using variadic macros in RCPP_DEBUG
@@ -23,8 +29,8 @@
* inst/include/Rcpp/sugar/matrix/upper_tri.h: new sugar function: upper_tri
* inst/include/Rcpp/sugar/functions/rep.h: new sugar function : rep
- * inst/include/Rcpp/sugar/functions/rep.h: new sugar function : rep_len
- * inst/include/Rcpp/sugar/functions/rep.h: new sugar function : rep_each
+ * inst/include/Rcpp/sugar/functions/rep_len.h: new sugar function : rep_len
+ * inst/include/Rcpp/sugar/functions/rep_each.h: new sugar function : rep_each
2010-07-02 Dirk Eddelbuettel <edd at debian.org>
Modified: pkg/Rcpp/inst/include/Rcpp/sugar/functions/ifelse.h
===================================================================
--- pkg/Rcpp/inst/include/Rcpp/sugar/functions/ifelse.h 2010-07-05 22:16:27 UTC (rev 1788)
+++ pkg/Rcpp/inst/include/Rcpp/sugar/functions/ifelse.h 2010-07-06 12:16:38 UTC (rev 1789)
@@ -33,7 +33,7 @@
>
class IfElse : public VectorBase<
RTYPE,
- ( COND_NA && LHS_NA && RHS_NA ) ,
+ ( COND_NA || LHS_NA || RHS_NA ) ,
IfElse<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>
> {
public:
@@ -48,28 +48,274 @@
}
inline STORAGE operator[]( int i ) const {
- return get__impl( i, typename Rcpp::traits::integral_constant<bool,COND_NA>() );
+ int x = cond[i] ;
+ if( Rcpp::traits::is_na<LGLSXP>(x) ) return x ;
+ if( x ) return lhs[i] ;
+ return rhs[i] ;
}
inline int size() const { return cond.size() ; }
private:
+ const COND_TYPE& cond ;
+ const LHS_TYPE& lhs ;
+ const RHS_TYPE& rhs ;
- inline STORAGE get__impl( int i, Rcpp::traits::true_type ) const {
- int x = cond[i] ;
- return Rcpp::traits::is_na<LGLSXP>(x) ? Rcpp::traits::get_na<RTYPE>() : ( x ? lhs[i] : rhs[i] ) ;
+} ;
+
+template <
+ int RTYPE,
+ typename COND_T,
+ bool LHS_NA , typename LHS_T,
+ bool RHS_NA , typename RHS_T
+ >
+class IfElse<RTYPE,false,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T> : public VectorBase<
+ RTYPE,
+ ( LHS_NA || RHS_NA ) ,
+ IfElse<RTYPE,false,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T> LHS_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T> RHS_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse( const COND_TYPE& cond_, const LHS_TYPE& lhs_, const RHS_TYPE& rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
}
- inline STORAGE get__impl( int i, Rcpp::traits::false_type ) const {
- return cond[i] ? lhs[i] : rhs[i] ;
+ inline STORAGE operator[]( int i ) const {
+ if( cond[i] ) return lhs[i] ;
+ return rhs[i] ;
}
+ inline int size() const { return cond.size() ; }
+
+private:
+
const COND_TYPE& cond ;
const LHS_TYPE& lhs ;
const RHS_TYPE& rhs ;
} ;
+
+
+/* ifelse( cond, primitive, Vector ) */
+
+template <
+ int RTYPE,
+ bool COND_NA, typename COND_T,
+ bool RHS_NA , typename RHS_T
+ >
+class IfElse_Primitive_Vector : public VectorBase<
+ RTYPE,
+ true ,
+ IfElse_Primitive_Vector<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T> RHS_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+ IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ int x = cond[i] ;
+ if( Rcpp::traits::is_na<LGLSXP>(x) ) return x ;
+ if( x ) return lhs ;
+ return rhs[i] ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ STORAGE lhs ;
+ const RHS_TYPE& rhs ;
+
+} ;
+
+template <
+ int RTYPE,
+ typename COND_T,
+ bool RHS_NA , typename RHS_T
+ >
+class IfElse_Primitive_Vector<RTYPE,false,COND_T,RHS_NA,RHS_T> : public VectorBase<
+ RTYPE,
+ true,
+ IfElse_Primitive_Vector<RTYPE,false,COND_T,RHS_NA,RHS_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T> RHS_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse_Primitive_Vector( const COND_TYPE& cond_, STORAGE lhs_, const RHS_TYPE& rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ if( cond[i] ) return lhs ;
+ return rhs[i] ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ STORAGE lhs ;
+ const RHS_TYPE& rhs ;
+
+} ;
+
+
+
+/* ifelse( cond, Vector, primitive ) */
+
+template <
+ int RTYPE,
+ bool COND_NA, typename COND_T,
+ bool LHS_NA , typename LHS_T
+ >
+class IfElse_Vector_Primitive : public VectorBase<
+ RTYPE,
+ true ,
+ IfElse_Vector_Primitive<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T> LHS_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ int x = cond[i] ;
+ if( Rcpp::traits::is_na<LGLSXP>(x) ) return Rcpp::traits::get_na<RTYPE>() ;
+ if( x ) return lhs[i] ;
+ return rhs ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ const LHS_TYPE& lhs ;
+ const STORAGE rhs ;
+
+} ;
+
+template <
+ int RTYPE,
+ typename COND_T,
+ bool LHS_NA , typename LHS_T
+ >
+class IfElse_Vector_Primitive<RTYPE,false,COND_T,LHS_NA,LHS_T> : public VectorBase<
+ RTYPE,
+ true ,
+ IfElse_Vector_Primitive<RTYPE,false,COND_T,LHS_NA,LHS_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
+ typedef Rcpp::VectorBase<RTYPE ,LHS_NA ,LHS_T> LHS_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse_Vector_Primitive( const COND_TYPE& cond_, const LHS_TYPE& lhs_, STORAGE rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ if( cond[i] ) return lhs[i] ;
+ return rhs ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ const LHS_TYPE& lhs ;
+ const STORAGE rhs ;
+
+} ;
+
+
+
+
+
+/* ifelse( cond, primitive, primitive ) */
+
+template <
+ int RTYPE,
+ bool COND_NA, typename COND_T
+ >
+class IfElse_Primitive_Primitive : public VectorBase<
+ RTYPE,
+ true ,
+ IfElse_Primitive_Primitive<RTYPE,COND_NA,COND_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,COND_NA,COND_T> COND_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ int x = cond[i] ;
+ if( Rcpp::traits::is_na<LGLSXP>(x) ) return Rcpp::traits::get_na<RTYPE>() ;
+ return x ? lhs : rhs ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ STORAGE lhs ;
+ STORAGE rhs ;
+
+} ;
+
+template <
+ int RTYPE, typename COND_T
+ >
+class IfElse_Primitive_Primitive<RTYPE,false,COND_T> : public VectorBase<
+ RTYPE,
+ true ,
+ IfElse_Primitive_Primitive<RTYPE,false,COND_T>
+> {
+public:
+ typedef Rcpp::VectorBase<LGLSXP,false,COND_T> COND_TYPE ;
+ typedef typename traits::storage_type<RTYPE>::type STORAGE ;
+
+ IfElse_Primitive_Primitive( const COND_TYPE& cond_, STORAGE lhs_, STORAGE rhs_ ) :
+ cond(cond_), lhs(lhs_), rhs(rhs_) {
+ /* FIXME : cond, lhs and rhs must all have the sale size */
+ }
+
+ inline STORAGE operator[]( int i ) const {
+ return cond[i] ? lhs : rhs ;
+ }
+
+ inline int size() const { return cond.size() ; }
+
+private:
+ const COND_TYPE& cond ;
+ STORAGE lhs ;
+ STORAGE rhs ;
+
+} ;
+
} // sugar
template <
@@ -87,6 +333,84 @@
return sugar::IfElse<RTYPE,COND_NA,COND_T,LHS_NA,LHS_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
}
+
+template <
+ int RTYPE,
+ bool COND_NA, typename COND_T,
+ bool RHS_NA , typename RHS_T
+ >
+inline sugar::IfElse_Primitive_Vector< RTYPE,COND_NA,COND_T,RHS_NA,RHS_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ typename traits::storage_type<RTYPE>::type lhs,
+ const Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>& rhs
+ ){
+ return sugar::IfElse_Primitive_Vector<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
+}
+
+template <
+ int RTYPE,
+ bool COND_NA, typename COND_T,
+ bool RHS_NA , typename RHS_T
+ >
+inline sugar::IfElse_Vector_Primitive< RTYPE,COND_NA,COND_T,RHS_NA,RHS_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ const Rcpp::VectorBase<RTYPE ,RHS_NA ,RHS_T>& lhs,
+ typename traits::storage_type<RTYPE>::type rhs
+ ){
+ return sugar::IfElse_Vector_Primitive<RTYPE,COND_NA,COND_T,RHS_NA,RHS_T>( cond, lhs, rhs ) ;
+}
+
+template<
+ bool COND_NA, typename COND_T
+>
+inline sugar::IfElse_Primitive_Primitive< REALSXP,COND_NA,COND_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ double lhs,
+ double rhs
+ ){
+ return sugar::IfElse_Primitive_Primitive<REALSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
+}
+
+template<
+ bool COND_NA, typename COND_T
+>
+inline sugar::IfElse_Primitive_Primitive< INTSXP,COND_NA,COND_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ int lhs,
+ int rhs
+ ){
+ return sugar::IfElse_Primitive_Primitive<INTSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
+}
+
+template<
+ bool COND_NA, typename COND_T
+>
+inline sugar::IfElse_Primitive_Primitive< CPLXSXP,COND_NA,COND_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ Rcomplex lhs,
+ Rcomplex rhs
+ ){
+ return sugar::IfElse_Primitive_Primitive<CPLXSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
+}
+
+template<
+ bool COND_NA, typename COND_T
+>
+inline sugar::IfElse_Primitive_Primitive< LGLSXP,COND_NA,COND_T >
+ifelse(
+ const Rcpp::VectorBase<LGLSXP,COND_NA,COND_T>& cond,
+ bool lhs,
+ bool rhs
+ ){
+ return sugar::IfElse_Primitive_Primitive<LGLSXP,COND_NA,COND_T>( cond, lhs, rhs ) ;
+}
+
+
} // Rcpp
#endif
Modified: pkg/Rcpp/inst/unitTests/runit.sugar.R
===================================================================
--- pkg/Rcpp/inst/unitTests/runit.sugar.R 2010-07-05 22:16:27 UTC (rev 1788)
+++ pkg/Rcpp/inst/unitTests/runit.sugar.R 2010-07-06 12:16:38 UTC (rev 1789)
@@ -236,8 +236,12 @@
NumericVector xx(x) ;
NumericVector yy(y) ;
- NumericVector res = ifelse( xx < yy, xx*xx, -(yy*yy) ) ;
- return res ;
+ return List::create(
+ _["vec_vec" ] = ifelse( xx < yy, xx*xx, -(yy*yy) ),
+ _["vec_prim"] = ifelse( xx < yy, 1.0 , -(yy*yy) ),
+ _["prim_vec"] = ifelse( xx < yy, xx*xx, 1.0 )
+ // , _["prim_prim"] = ifelse( xx < yy, 1.0, 2.0 )
+ ) ;
'
),
"runit_isna" = list(
@@ -748,7 +752,12 @@
fx <- .rcpp.sugar$runit_ifelse
x <- 1:10
y <- 10:1
- checkEquals( fx( x, y), ifelse( x<y, x*x, -(y*y) ) )
+ checkEquals( fx( x, y), list(
+ "vec_vec" = ifelse( x<y, x*x, -(y*y) ),
+ "vec_prim" = ifelse( x<y, 1.0, -(y*y) ),
+ "prim_vec" = ifelse( x<y, x*x, 1.0 )
+ # , "prim_prim" = ifelse( x<y, 1.0, 2.0 )
+ ) )
}
More information about the Rcpp-commits
mailing list