# # Copyright (C) 2012 - 2013 Douglas Bates, Dirk Eddelbuettel and Romain Francois # # This file is part of RcppEigen. # # RcppEigen is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # RcppEigen is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Rcpp. If not, see . incl <- ' typedef Eigen::ArrayXd Ar1; typedef Eigen::Map MAr1; typedef Eigen::ArrayXXd Ar2; typedef Eigen::Map MAr2; typedef Eigen::MatrixXd Mat; typedef Eigen::Map MMat; typedef Eigen::VectorXd Vec; typedef Eigen::Map MVec; typedef Eigen::ArrayXi iAr1; typedef Eigen::Map MiAr1; typedef Eigen::ArrayXXi iAr2; typedef Eigen::Map MiAr2; typedef Eigen::MatrixXi iMat; typedef Eigen::Map MiMat; typedef Eigen::VectorXi iVec; typedef Eigen::Map MiVec; typedef Eigen::ArrayXf fAr1; typedef Eigen::Map MfAr1; typedef Eigen::ArrayXXf fAr2; typedef Eigen::Map MfAr2; typedef Eigen::MatrixXf fMat; typedef Eigen::Map MfMat; typedef Eigen::VectorXf fVec; typedef Eigen::Map MfVec; typedef Eigen::ArrayXcd cdAr1; typedef Eigen::Map McdAr1; typedef Eigen::ArrayXXcd cdAr2; typedef Eigen::Map McdAr2; typedef Eigen::MatrixXcd cdMat; typedef Eigen::Map McdMat; typedef Eigen::VectorXcd cdVec; typedef Eigen::Map McdVec; ' definitions <- list( "wrap_vectors" = list(signature(), ' List vecs = List::create(Named("Vec", cdVec::Zero(5)), Named("Vec", Vec::Zero(5)), Named("Vec", fVec::Zero(5)), Named("Vec", iVec::Zero(5)) ); // A VectorX behaves as a matrix with one column but is converted to // a vector object in R, not a matrix of one column. The distinction is // that VectorX objects are defined at compile time to have one column, // whereas a MatrixX has a dynamic number of columns that is set to 1 // during execution of the code. A MatrixX object can be resized to have // a different number of columns. A VectorX object cannot. List cols = List::create(Named("Col", cdMat::Zero(5, 1)), Named("Col", Mat::Zero(5, 1)), Named("Col", fMat::Zero(5, 1)), Named("Col", iMat::Zero(5, 1)) ); // List rows = List::create( // _["Row"] = Eigen::RowVectorXcd::Zero(5), // _["Row"] = Eigen::RowVectorXd::Zero(5), // _["Row"] = Eigen::RowVectorXf::Zero(5), // _["Row"] = Eigen::RowVectorXi::Zero(5) // ); List matrices = List::create( _["Mat"] = Eigen::MatrixXcd::Identity(3, 3), _["Mat"] = Eigen::MatrixXd::Identity(3, 3), _["Mat"] = Eigen::MatrixXf::Identity(3, 3), _["Mat"] = Eigen::MatrixXi::Identity(3, 3) ); // ArrayXX objects have the same structure as matrices but allow // componentwise arithmetic. A * B is matrix multiplication for // matrices and componentwise multiplication for arrays. List arrays2 = List::create( _["Arr2"] = Eigen::ArrayXXcd::Zero(3, 3), _["Arr2"] = Eigen::ArrayXXd::Zero(3, 3), _["Arr2"] = Eigen::ArrayXXf::Zero(3, 3), _["Arr2"] = Eigen::ArrayXXi::Zero(3, 3) ); // ArrayX objects have the same structure as VectorX objects // but allow componentwise arithmetic, including functions like exp, log, // sqrt, ... List arrays1 = List::create( _["Arr1"] = Eigen::ArrayXcd::Zero(5), _["Arr1"] = Eigen::ArrayXd::Zero(5), _["Arr1"] = Eigen::ArrayXf::Zero(5), _["Arr1"] = Eigen::ArrayXi::Zero(5) ); List operations = List::create( _["Op_seq"] = Eigen::ArrayXd::LinSpaced(6, 1, 10), // arguments are length.out, start, end _["Op_log"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).log(), _["Op_exp"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).exp(), _["Op_sqrt"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).sqrt(), _["Op_cos"] = Eigen::ArrayXd::LinSpaced(6, 1, 10).cos() ); List output = List::create( _["vectors : VectorX"] = vecs, _["matrices : MatrixX"] = matrices, // _["rows : RowVectorX"] = rows, _["columns : MatrixX"] = cols, _["arrays2d : ArrayXX"] = arrays2, _["arrays1d : ArrayX"] = arrays1, _["operations : ArrayXd"] = operations ); return output; '), "as_Vec" = list(signature(input_ = "list"), ' List input(input_) ; Eigen::VectorXi m1 = input[0] ; /* implicit as */ Eigen::VectorXd m2 = input[1] ; /* implicit as */ Eigen::Matrix m3 = input[0] ; /* implicit as */ Eigen::VectorXf m4 = input[1] ; /* implicit as */ List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum()); return res ; '), "as_rowVec" = list(signature(input_ = "list"), ' List input(input_) ; Eigen::Matrix m1 = input[0] ; /* implicit as */ Eigen::Matrix m2 = input[1] ; /* implicit as */ Eigen::Matrix m3 = input[0] ; /* implicit as */ Eigen::Matrix m4 = input[1] ; /* implicit as */ List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum()); return res ; '), "as_Array" = list(signature(input_ = "list"), ' List input(input_) ; Eigen::ArrayXi m1 = input[0] ; /* implicit as */ Eigen::ArrayXd m2 = input[1] ; /* implicit as */ Eigen::Array m3 = input[0] ; /* implicit as */ Eigen::ArrayXf m4 = input[1] ; /* implicit as */ List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum()); return res ; '), "as_rowArray" = list(signature(input_ = "list"), ' List input(input_) ; Eigen::Array m1 = input[0] ; /* implicit as */ Eigen::Array m2 = input[1] ; /* implicit as */ Eigen::Array m3 = input[0] ; /* implicit as */ Eigen::Array m4 = input[1] ; /* implicit as */ List res = List::create(m1.sum(), m2.sum(), m3.sum(), m4.sum()); return res ; ') ) .setUp <- function() { suppressMessages(require(inline)) suppressMessages(require(RcppEigen)) cxxargs <- ifelse(Rcpp:::capabilities()[["initializer lists"]], "-std=c++0x","") tests <- ".rcppeigen.wrap" if( ! exists( tests, globalenv() )) { fun <- RcppEigen:::compile_unit_tests(definitions, includes=incl, cxxargs = cxxargs) names(fun) <- names(definitions) assign(tests, fun, globalenv()) } } test.wrapVectors <- function() { res <- .rcppeigen.wrap$wrap_vectors() checkEquals(res[[1]][[1]], complex(5)) checkEquals(res[[1]][[2]], double(5)) checkEquals(res[[1]][[3]], double(5)) checkEquals(res[[1]][[4]], integer(5)) checkEquals(res[[2]][[1]], (1+0i) * diag(nr=3L)) checkEquals(res[[2]][[2]], diag(nr=3L)) checkEquals(res[[2]][[3]], diag(nr=3L)) checkEquals(res[[2]][[4]], matrix(as.integer((diag(nr=3L))),nr=3L)) ## checkEquals(res[[3]][[1]], matrix(complex(5), nr=1L)) ## checkEquals(res[[3]][[1]], matrix(numeric(5), nr=1L)) ## checkEquals(res[[3]][[2]], matrix(numeric(5), nr=1L)) ## checkEquals(res[[3]][[3]], matrix(integer(5), nr=1L)) checkEquals(res[[3]][[1]], as.matrix(complex(5))) checkEquals(res[[3]][[2]], as.matrix(numeric(5))) checkEquals(res[[3]][[3]], as.matrix(numeric(5))) checkEquals(res[[3]][[4]], as.matrix(integer(5))) checkEquals(res[[4]][[1]], matrix(complex(9L), nc=3L)) checkEquals(res[[4]][[2]], matrix(numeric(9L), nc=3L)) checkEquals(res[[4]][[3]], matrix(numeric(9L), nc=3L)) checkEquals(res[[4]][[4]], matrix(integer(9L), nc=3L)) checkEquals(res[[5]][[1]], complex(5)) checkEquals(res[[5]][[2]], double(5)) checkEquals(res[[5]][[3]], double(5)) checkEquals(res[[5]][[4]], integer(5)) oneTen <- seq(1, 10, length.out=6L) checkEquals(res[[6]][[1]], oneTen) checkEquals(res[[6]][[2]], log(oneTen)) checkEquals(res[[6]][[3]], exp(oneTen)) checkEquals(res[[6]][[4]], sqrt(oneTen)) checkEquals(res[[6]][[5]], cos(oneTen)) } test.wrapAsVec <- function() { res <- .rcppeigen.wrap$as_Vec(list(1:10, as.numeric(1:10))) checkEquals(unlist(res), rep.int(55, 4L)) } test.wrapAsRowVec <- function() { res <- .rcppeigen.wrap$as_rowVec(list(1:10, as.numeric(1:10))) checkEquals(unlist(res), rep.int(55, 4L)) } test.wrapAsArray <- function() { res <- .rcppeigen.wrap$as_Array(list(1:10, as.numeric(1:10))) checkEquals(unlist(res), rep.int(55, 4L)) } test.wrapAsRowArray <- function() { res <- .rcppeigen.wrap$as_rowArray(list(1:10, as.numeric(1:10))) checkEquals(unlist(res), rep.int(55, 4L)) }