[Rcpp-commits] r439 - in pkg: inst inst/doc inst/unitTests src src/Rcpp

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Jan 24 12:40:04 CET 2010


Author: romain
Date: 2010-01-24 12:40:04 +0100 (Sun, 24 Jan 2010)
New Revision: 439

Modified:
   pkg/inst/ChangeLog
   pkg/inst/doc/Rcpp-unitTests.R
   pkg/inst/unitTests/runit.NumericVector.R
   pkg/src/NumericVector.cpp
   pkg/src/Rcpp/NumericVector.h
   pkg/src/Rcpp/VectorBase.h
Log:
first pass at matrix indexing

Modified: pkg/inst/ChangeLog
===================================================================
--- pkg/inst/ChangeLog	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/inst/ChangeLog	2010-01-24 11:40:04 UTC (rev 439)
@@ -1,5 +1,10 @@
 2010-01-23  Romain Francois <francoisromain at free.fr>
 
+	* src/NumericVector.cpp: first pass at matrix indexing using 
+	operator()(size_t, size_t)
+
+2010-01-23  Romain Francois <francoisromain at free.fr>
+
 	* src/wrap.cpp: s/copy/std::copy/
 
 	* src/RcppDateTime.h: explicitely include <time.h> (win64 warning)

Modified: pkg/inst/doc/Rcpp-unitTests.R
===================================================================
--- pkg/inst/doc/Rcpp-unitTests.R	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/inst/doc/Rcpp-unitTests.R	2010-01-24 11:40:04 UTC (rev 439)
@@ -1,7 +1,6 @@
 #!/usr/bin/r -t
 #
-# Copyright (C) 2009 Dirk Eddelbuettel
-# Copyright (C) 2009 Romain Francois
+# Copyright (C) 2009 - 2010 Dirk Eddelbuettel and Romain Francois
 #
 # This file is part of Rcpp.
 #

Modified: pkg/inst/unitTests/runit.NumericVector.R
===================================================================
--- pkg/inst/unitTests/runit.NumericVector.R	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/inst/unitTests/runit.NumericVector.R	2010-01-24 11:40:04 UTC (rev 439)
@@ -53,4 +53,20 @@
 	}
 }
 
+test.NumericVector.matrix.indexing <- function(){
+	funx <- cfunction(signature(x = "numeric" ), '
+		NumericVector m(x) ;
+		double trace = 0.0 ;
+		for( size_t i=0 ; i<4; i++){
+			trace += m(i,i) ;
+		}
+		return wrap( trace ) ;
+	', Rcpp = TRUE, includes = "using namespace Rcpp;"  )
+	x <- matrix( 1:16 + .5, ncol = 4 )
+	checkEquals( funx(x), sum(diag(x)), msg = "matrix indexing" )
+	
+	y <- as.vector( x )
+	checkException( funx(y) , msg = "not a matrix" )
+	
+}
 

Modified: pkg/src/NumericVector.cpp
===================================================================
--- pkg/src/NumericVector.cpp	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/src/NumericVector.cpp	2010-01-24 11:40:04 UTC (rev 439)
@@ -42,4 +42,18 @@
 		setSEXP( Rf_allocVector(REALSXP, size) ) ;
 	}
 
+	double& NumericVector::operator()( const size_t& i) throw(index_out_of_bounds){
+		if( i >= static_cast<size_t>(Rf_length(m_sexp)) ) throw index_out_of_bounds() ;
+		return start[i] ;
+	}
+	
+	double& NumericVector::operator()( const size_t& i, const size_t& j) throw(not_a_matrix,index_out_of_bounds){
+		if( !Rf_isMatrix(m_sexp) ) throw not_a_matrix() ;
+		int *dim = INTEGER( Rf_getAttrib( m_sexp, R_DimSymbol ) ) ;
+		size_t nrow = static_cast<size_t>(dim[0]) ;
+		size_t ncol = static_cast<size_t>(dim[1]) ;
+		if( i >= nrow || j >= ncol ) throw index_out_of_bounds() ;
+		return start[ i + nrow*j ] ;
+	}
+	
 } // namespace 

Modified: pkg/src/Rcpp/NumericVector.h
===================================================================
--- pkg/src/Rcpp/NumericVector.h	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/src/Rcpp/NumericVector.h	2010-01-24 11:40:04 UTC (rev 439)
@@ -47,14 +47,33 @@
 		simple_fill( list.begin(), list.end() ) ;
 	}
 #endif
-
+	/** Fast 1d 0-based indexing. no bounds checking are performed */
 	inline double& operator[]( const int& i ) { return start[i] ; }
-	inline const double& operator[]( const int& i ) const { return start[i]; }
-	inline double* begin() const { return start ; } 
-	inline double* end() const   { return start+LENGTH(m_sexp);}
 	
+	/** Returns a pointer to the internal array */
+	inline double* begin() const { return start ; }
+	
+	/** Returns a pointer to the element after the last element of the array */
+	inline double* end() const   { return start + Rf_length(m_sexp);}
+	
+	/** convenience typedef */
 	typedef double* iterator ;
 
+	/** secure 1d 0-based indexing. 
+	 * As opposed to operator[], this operator performs bounds checks
+	 * to make sure that i is valid. There is however a price associated 
+	 * with the check
+	 * 
+	 * @param i 0-based index. this indexes the object as a vector
+	 * so if it is actually a matrix the order is column-major (as in R)
+	 */
+	double& operator()( const size_t& i ) throw(index_out_of_bounds) ;
+	
+	/**
+	 * matrix indexing. 
+	 */
+	double& operator()( const size_t&i, const size_t& j) throw(not_a_matrix,index_out_of_bounds);
+	
 private:
 	double *start ;
 	virtual void update(){ start = REAL(m_sexp);}

Modified: pkg/src/Rcpp/VectorBase.h
===================================================================
--- pkg/src/Rcpp/VectorBase.h	2010-01-23 23:22:04 UTC (rev 438)
+++ pkg/src/Rcpp/VectorBase.h	2010-01-24 11:40:04 UTC (rev 439)
@@ -29,7 +29,13 @@
 
 class VectorBase : public RObject {     
 public:
-	
+	class not_a_matrix : public std::exception{
+	public:
+		not_a_matrix(){} ;
+		virtual ~not_a_matrix() throw() {} ;
+		virtual const char* what() const throw() { return "not a matrix" ; };
+	} ;
+  
     VectorBase() ;
     virtual ~VectorBase() = 0;
 	



More information about the Rcpp-commits mailing list