#!/usr/bin/r -t
#
# Copyright (C) 2011 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 RcppEigen. If not, see .
.setUp <- function(){
suppressMessages(require(inline))
}
test.wrap.R <- function(){
fx <- cxxfunction( , '
List vecs = List::create(
_["Vec"] = Eigen::VectorXcd::Zero(5),
_["Vec"] = Eigen::VectorXd::Zero(5),
_["Vec"] = Eigen::VectorXf::Zero(5),
_["Vec"] = Eigen::VectorXi::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(
_["Col"] = Eigen::MatrixXcd::Zero(5, 1),
_["Col"] = Eigen::MatrixXd::Zero(5, 1),
_["Col"] = Eigen::MatrixXf::Zero(5, 1),
_["Col"] = Eigen::MatrixXi::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 ;
' , plugin = "RcppEigen" )
res <- fx()
checkEquals( res[["vectors : VectorX"]][["Vec"]], complex(5), msg = "VectorXcd::Zero(5)")
checkEquals( res[["vectors : VectorX"]][["Vec"]], double(5), msg = "VectorXd::Zero(5)")
checkEquals( res[["vectors : VectorX"]][["Vec"]], double(5), msg = "VectorXf::Zero(5)")
checkEquals( res[["vectors : VectorX"]][["Vec"]], integer(5), msg = "VectorXi::Zero(5)")
checkEquals( res[["matrices : MatrixX"]][["Mat"]], (1+0i) * diag(nr=3L), msg = "MatrixXcd::Identity(3,3)")
checkEquals( res[["matrices : MatrixX"]][["Mat"]], diag(nr=3L), msg = "MatrixXd::Identity(3,3)")
checkEquals( res[["matrices : MatrixX"]][["Mat"]], diag(nr=3L), msg = "MatrixXf::Identity(3,3)")
checkEquals( res[["matrices : MatrixX"]][["Mat"]], matrix(as.integer((diag(nr=3L))),nr=3L), msg = "MatrixXi::Identity(3,3)")
checkEquals( res[["rows : RowVectorX"]][["Row"]], matrix(complex(5), nr=1L), msg = "RowVectorXcd::Zero(5)")
checkEquals( res[["rows : RowVectorX"]][["Row"]], matrix(numeric(5), nr=1L), msg = "RowVectorXd::Zero(5)")
checkEquals( res[["rows : RowVectorX"]][["Row"]], matrix(numeric(5), nr=1L), msg = "RowVectorXf::Zero(5)")
checkEquals( res[["rows : RowVectorX"]][["Row"]], matrix(integer(5), nr=1L), msg = "RowVectorXi::Zero(5)")
checkEquals( res[["columns : MatrixX"]][["Col"]], as.matrix(complex(5)), msg = "MatrixXcd::Zero(5, 1)")
checkEquals( res[["columns : MatrixX"]][["Col"]], as.matrix(numeric(5)), msg = "MatrixXd::Zero(5, 1)")
checkEquals( res[["columns : MatrixX"]][["Col"]], as.matrix(numeric(5)), msg = "MatrixXf::Zero(5, 1)")
checkEquals( res[["columns : MatrixX"]][["Col"]], as.matrix(integer(5)), msg = "MatrixXi::Zero(5, 1)")
checkEquals( res[["arrays2d : ArrayXX"]][["Arr2"]], matrix(complex(9L), nc=3L), msg = "ArrayXXcd::Zero(3,3)")
checkEquals( res[["arrays2d : ArrayXX"]][["Arr2"]], matrix(numeric(9L), nc=3L), msg = "ArrayXXd::Zero(3,3)")
checkEquals( res[["arrays2d : ArrayXX"]][["Arr2"]], matrix(numeric(9L), nc=3L), msg = "ArrayXXf::Zero(3,3)")
checkEquals( res[["arrays2d : ArrayXX"]][["Arr2"]], matrix(integer(9L), nc=3L), msg = "ArrayXXi::Zero(3,3)")
checkEquals( res[["arrays1d : ArrayX"]][["Arr1"]], complex(5), msg = "ArrayXcd::Zero(5)")
checkEquals( res[["arrays1d : ArrayX"]][["Arr1"]], double(5), msg = "ArrayXd::Zero(5)")
checkEquals( res[["arrays1d : ArrayX"]][["Arr1"]], double(5), msg = "ArrayXf::Zero(5)")
checkEquals( res[["arrays1d : ArrayX"]][["Arr1"]], integer(5), msg = "ArrayXi::Zero(5)")
oneTen <- seq(1, 10, length.out=6L)
checkEquals( res[["operations : ArrayXd"]][["Op_seq"]], oneTen, msg = "Op_seq")
checkEquals( res[["operations : ArrayXd"]][["Op_log"]], log(oneTen), msg = "Op_log")
checkEquals( res[["operations : ArrayXd"]][["Op_exp"]], exp(oneTen), msg = "Op_exp")
checkEquals( res[["operations : ArrayXd"]][["Op_sqrt"]], sqrt(oneTen), msg = "Op_sqrt")
checkEquals( res[["operations : ArrayXd"]][["Op_cos"]], cos(oneTen), msg = "Op_cos")
}
test.as.Vec <- function(){
fx <- cxxfunction( 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 ;
', plugin = "RcppEigen" )
res <- fx( list( 1:10, as.numeric(1:10) ) )
checkEquals( unlist( res ), rep(55.0, 4 ), msg = "as" )
}
test.as.MVec <- function(){
fx <- cxxfunction( signature(input_ = "list" ) , '
List input(input_) ;
const Eigen::Map m1 = input[0] ; // maps share storage and do not allow conversion
const Eigen::Map 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" )
}
test.as.MMat <- function(){
fx <- cxxfunction( signature(input_ = "list" ) , '
List input(input_) ;
const Eigen::Map m1 = input[0]; // maps share storage and do not allow conversion
const Eigen::Map m2 = input[1] ;
// FIXME: Write a version of as specifically for complex matrices.
// const Eigen::Map 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" )
}
test.as.MSpMat <- function() {
suppressMessages(require("Matrix"))
data("KNex", package = "Matrix")
fx <- cxxfunction( signature(input_ = "list"), '
List input(input_) ;
const Eigen::MappedSparseMatrix m1 = input[0]; // maps share storage and do not allow conversion
List res = List::create(_["nnz"] = m1.nonZeros(),
_["nr"] = m1.rows(),
_["nc"] = m1.cols(),
_["inSz"] = m1.innerSize(),
_["outSz"] = m1.outerSize(),
_["sum"] = m1.sum());
return res ;
', plugin = "RcppEigen" )
KNX <- KNex[[1]]
res <- fx(KNex)
checkEquals(unname(unlist(res)),
c(nnzero(KNX), nrow(KNX), ncol(KNX), nrow(KNX), ncol(KNX), sum(KNX@x)),
msg = "as")
}
test.as.SpMat <- function() {
suppressMessages(require("Matrix"))
data("KNex", package = "Matrix")
fx <- cxxfunction( signature(input_ = "list"), '
List input(input_) ;
const Eigen::SparseMatrix m1 = input[0];
List res = List::create(_["nnz"] = m1.nonZeros(),
_["nr"] = m1.rows(),
_["nc"] = m1.cols(),
_["inSz"] = m1.innerSize(),
_["outSz"] = m1.outerSize(),
_["sum"] = m1.sum());
return res ;
', plugin = "RcppEigen" )
KNX <- KNex[[1]]
res <- fx(KNex)
checkEquals(unname(unlist(res)),
c(nnzero(KNX), nrow(KNX), ncol(KNX), nrow(KNX), ncol(KNX), sum(KNX@x)),
msg = "as")
}