[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