[Rcpp-commits] r3126 - in pkg/RcppEigen/inst: include unitTests

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Sun Jul 10 23:15:03 CEST 2011


Author: dmbates
Date: 2011-07-10 23:15:01 +0200 (Sun, 10 Jul 2011)
New Revision: 3126

Modified:
   pkg/RcppEigen/inst/include/RcppEigenForward.h
   pkg/RcppEigen/inst/include/RcppEigenWrap.h
   pkg/RcppEigen/inst/unitTests/runit.RcppEigen.R
Log:
Added as methods for mapped vectors and mapped matrices (still some code duplication) and tests of same.


Modified: pkg/RcppEigen/inst/include/RcppEigenForward.h
===================================================================
--- pkg/RcppEigen/inst/include/RcppEigenForward.h	2011-07-09 16:36:37 UTC (rev 3125)
+++ pkg/RcppEigen/inst/include/RcppEigenForward.h	2011-07-10 21:15:01 UTC (rev 3126)
@@ -25,32 +25,35 @@
 #include <RcppCommon.h>
 #include <Rconfig.h>
 #include <RcppEigenConfig.h>
-
+#define EIGEN_PLAINOBJECTBASE_PLUGIN "PlainObjectBaseAddon.h"
 #include <Eigen/Dense>
 #include <unsupported/Eigen/SparseExtra> // also includes Eigen/Sparse
 
 /* forward declarations */
 namespace Rcpp {
     /* support for wrap */
+    template<typename Derived> SEXP wrap(const Eigen::EigenBase<Derived>&);
     template<typename T> SEXP wrap(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>&);
     template<typename T> SEXP wrap(const Eigen::Matrix<T, Eigen::Dynamic, 1>&);
     template<typename T> SEXP wrap(const Eigen::Matrix<T, 1, Eigen::Dynamic>&);
     template<typename T> SEXP wrap(const Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic>&);
     template<typename T> SEXP wrap(const Eigen::Array<T, Eigen::Dynamic, 1>&);
-    template<typename T> SEXP wrap(const Eigen::SparseMatrix<T>&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> >&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::Matrix<T, 1, Eigen::Dynamic> >&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::Array<T, Eigen::Dynamic, Eigen::Dynamic> >&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::Array<T, Eigen::Dynamic, 1> >&);
+    template<typename T> SEXP wrap(const Eigen::SparseMatrix<T>&);
     template<typename T> SEXP wrap(const Eigen::Map<Eigen::SparseMatrix<T> >&);
     
     namespace traits {
 
 	/* support for as */
-	template<typename T> class Exporter< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > ;
-	template<typename T> class Exporter< Eigen::Matrix<T, Eigen::Dynamic, 1> > ;
-	template<typename T> class Exporter< Eigen::Matrix<T, 1, Eigen::Dynamic> > ;
+	template<typename T> class Exporter< Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> > >;
+	template<typename T> class Exporter< Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > >;
+	template<typename T> class Exporter< Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >;
+	template<typename T> class Exporter< Eigen::Matrix<T, Eigen::Dynamic, 1> >;
+	template<typename T> class Exporter< Eigen::Matrix<T, 1, Eigen::Dynamic> >;
 
     } // namespace traits 
 

Modified: pkg/RcppEigen/inst/include/RcppEigenWrap.h
===================================================================
--- pkg/RcppEigen/inst/include/RcppEigenWrap.h	2011-07-09 16:36:37 UTC (rev 3125)
+++ pkg/RcppEigen/inst/include/RcppEigenWrap.h	2011-07-10 21:15:01 UTC (rev 3126)
@@ -34,8 +34,15 @@
 		}
 
     } /* namespace RcppEigen */
-	
+
     /* wrap */
+	template <typename Derived>
+	SEXP wrap(const Eigen::EigenBase<Derived>& object) {
+//FIXME: Check IsRowMajor and transpose if needed
+		::Rcpp::RObject x = ::Rcpp::wrap(object.data(), object.data() + object.size());
+		if (object.ColsAtCompileTime == 1) return x; // represented as a vector
+		x.attr("dim") = ::Rcpp::Dimension(object.rows(), object.cols());
+	}
 
     template <typename T>
 	SEXP wrap(const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& data) {
@@ -105,7 +112,46 @@
     /* support for Rcpp::as */
 	
     namespace traits {
-		
+
+		template<typename T>
+		class Exporter<Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> > > {
+		public:
+			typedef typename Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> >  MVType;
+			Exporter(SEXP x) : d_size(::Rf_length(x)) {
+				const int RTYPE = ::Rcpp::traits::r_sexptype_traits<T>::rtype ;
+				if (TYPEOF(x) != RTYPE)
+					throw std::invalid_argument("Wrong R type for mapped vector");
+				typedef typename ::Rcpp::traits::storage_type<RTYPE>::type STORAGE;
+				d_start         = ::Rcpp::internal::r_vector_start<RTYPE,STORAGE>(x);
+			}
+			MVType get() {return MVType(d_start, d_size);}
+		protected:
+			const int d_size;
+			T*        d_start;
+		};
+
+		template<typename T>
+		class Exporter<Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> > > {
+		public:
+			typedef typename Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> >  MMType;
+			Exporter(SEXP x) : d_nrow(::Rf_length(x)), d_ncol(1) {
+				const int RTYPE = ::Rcpp::traits::r_sexptype_traits<T>::rtype ;
+				if (TYPEOF(x) != RTYPE)
+					throw std::invalid_argument("Wrong R type for mapped vector");
+				typedef typename ::Rcpp::traits::storage_type<RTYPE>::type STORAGE;
+				d_start         = ::Rcpp::internal::r_vector_start<RTYPE,STORAGE>(x);
+				if (::Rf_isMatrix(x)) {
+					int *dims = INTEGER(::Rf_getAttrib(x, R_DimSymbol));
+					d_nrow = dims[0];
+					d_ncol = dims[1];
+				}
+			}
+			MMType get() {return MMType(d_start, d_nrow, d_ncol);}
+		protected:
+			int   d_nrow, d_ncol;
+			T*    d_start;
+		};
+
 		template <typename T> 
 		class Exporter<Eigen::Matrix<T, Eigen::Dynamic, 1> >
 			: public IndexingExporter<Eigen::Matrix<T, Eigen::Dynamic, 1>, T> {

Modified: pkg/RcppEigen/inst/unitTests/runit.RcppEigen.R
===================================================================
--- pkg/RcppEigen/inst/unitTests/runit.RcppEigen.R	2011-07-09 16:36:37 UTC (rev 3125)
+++ pkg/RcppEigen/inst/unitTests/runit.RcppEigen.R	2011-07-10 21:15:01 UTC (rev 3126)
@@ -146,7 +146,7 @@
 
 }
 
-test.as.Col <- function(){
+test.as.Vec <- function(){
     fx <- cxxfunction( signature(input_ = "list" ) , '
 
     List input(input_) ;
@@ -162,9 +162,48 @@
     ', plugin = "RcppEigen" )
 
     res <- fx( list( 1:10, as.numeric(1:10) ) )
-    checkEquals( unlist( res ), rep(55.0, 4 ), msg = "as<Col>" )
+    checkEquals( unlist( res ), rep(55.0, 4 ), msg = "as<Vec>" )
 }
 
+test.as.MVec <- function(){
+    fx <- cxxfunction( signature(input_ = "list" ) , '
+
+    List input(input_) ;
+    const Eigen::Map<Eigen::VectorXi>   m1 = input[0] ; // maps share storage and do not allow conversion
+    const Eigen::Map<Eigen::VectorXd>   m2 = input[1] ; 
+
+    List res = List::create(m1.sum(), m2.sum());
+
+    return res ;
+
+    ', plugin = "RcppEigen" )
+
+    res <- fx( list( 1:10, as.numeric(1:10) ) )
+    checkEquals( unlist( res ), rep(55.0, 2 ), msg = "as<MVec>" )
+}
+
+test.as.MMat <- function(){
+    fx <- cxxfunction( signature(input_ = "list" ) , '
+
+    List input(input_) ;
+    const Eigen::Map<Eigen::MatrixXi>   m1 = input[0]; // maps share storage and do not allow conversion
+    const Eigen::Map<Eigen::MatrixXd>   m2 = input[1] ;
+//    const Eigen::Map<Eigen::MatrixXcd>  m3 = input[2] ; 
+
+    List res = List::create(m1.sum(), m2.sum()); //, m3.sum());
+
+    return res ;
+
+    ', plugin = "RcppEigen" )
+
+    integer_mat <- matrix(as.integer(diag(nr=4L)), nc=4L)
+    numeric_mat <- diag(nr=5L)
+#    complex_mat <- (1+0i) * diag(nr=5L)
+    res <- fx(list(integer_mat, numeric_mat)) #, complex_mat))
+    checkEquals(unlist(res), c(4L, 5#, 5+0i
+                               ), msg = "as<MMat>" )
+}
+
 if (FALSE) {
 
 test.as.Mat <- function(){



More information about the Rcpp-commits mailing list