Create NumericMatrix from NumericVector - rcpp

Is there a way to create NumericMatrix from NumericVectors? Something like this:
Rcpp::cppFunction("NumericMatrix f(){
NumericVector A(10, 2.0);
NumericVector B(10, 1.0);
return NumericMatrix(10,2,C(A,B)); //ERROR
}")
> f()

Sure. There is for example cbind.
Code
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix makeMatrix(Rcpp::NumericVector a, Rcpp::NumericVector b) {
return Rcpp::cbind(a, b);
}
/*** R
a <- c(1,2,3)
b <- c(3,2,1)
makeMatrix(a,b)
*/
Output
> Rcpp::sourceCpp("~/git/stackoverflow/65538515/answer.cpp")
> a <- c(1,2,3)
> b <- c(3,2,1)
> makeMatrix(a,b)
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
>

Related

Conversion of Rcpp::NumericMatrix to Eigen::MatrixXd

I am facing a very similar issue to these questions:
convert Rcpp::NumericVector to Eigen::VectorXd
Converting between NumericVector/Matrix and VectorXd/MatrixXd in Rcpp(Eigen) to perform Cholesky solve
I am writing an R-package, that uses the RcppEigen library for Matrix arithmetic. My problem is that the project is not compiling because of an error in the conversion of the Rcpp::NumericMatrix input to an Eigen::MatrixXd.
The file looks like this:
#include <map>
#include <Rcpp.h>
...
using namespace Eigen;
...
// [[Rcpp::export]]
Rcpp::List my_function(Rcpp::NumericMatrix input_matrix)
{
...
Map<MatrixXd> GATE_matrixx(Rcpp::as<Map<MatrixXd> >(GATE_matrix));
...
}
This gives me the following error:
Myfile.cpp:40:65: required from here
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/Rcpp/include/Rcpp/internal/Exporter.h:31:31:error:
matching function for call to 'Eigen::Map<Eigen::Matrix<double, -1,
-1> >::Map(SEXPREC*&) 31 | Exporter( SEXP x ) : t(x) | ^ In file included from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/Core:19
from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/SparseCore:11
from
C:/Users/User/AppData/Local/Programs/R/R-4.2.2/library/RcppEigen/include/Eigen/Sparse:26
from Myfile.cpp:8
I have also tried to change the line to:
MatrixXd input_matrix_eigen(Rcpp::as\<MatrixXd\>(input_matrix));
This gives me the equivalent error :
Myfile.cpp:40:54: required from here
C:/Users/User/AppData/Local/Programs/R/R
4.2.2/library/RcppEigen/include/Eigen/src/Core/Matrix.h:332:31:error: matching function for call to 'Eigen::Matrix<double, -1,
-1>::_init1<SEXPREC*>(SEXPREC* const&)
Do you have any ideas?
If more information is required to evaluate the issue, just let me know.
If you use the command
RcppEigen::RcppEigen.package.skeleton("demoPackage")
an example package demoPackage is created for you which you can install the usual way. It contains example functions to create amd return a matrix:
// [[Rcpp::export]]
Eigen::MatrixXd rcppeigen_hello_world() {
Eigen::MatrixXd m1 = Eigen::MatrixXd::Identity(3, 3);
// Eigen::MatrixXd m2 = Eigen::MatrixXd::Random(3, 3);
// Do not use Random() here to not promote use of a non-R RNG
Eigen::MatrixXd m2 = Eigen::MatrixXd::Zero(3, 3);
for (auto i=0; i<m2.rows(); i++)
for (auto j=0; j<m2.cols(); j++)
m2(i,j) = R::rnorm(0, 1);
return m1 + 3 * (m1 + m2);
}
If you set the same seed as I do you should get the same matrix
> set.seed(42)
> demoPackage::rcppeigen_hello_world()
[,1] [,2] [,3]
[1,] 8.11288 -1.694095 1.089385
[2,] 1.89859 5.212805 -0.318374
[3,] 4.53457 -0.283977 10.055271
>

Ignore missing values while finding min in Rcpp

I am trying to find the minimum of 2 values from 2 vectors in Rcpp. But the following does not compile:
#include <cmath>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector timesTwo(int time_length, double BXadd,
NumericVector vn_complete, NumericVector vn1_complete) {
// Empty vectors
NumericVector BX (time_length);
for(int t = 0; t < time_length; t++) {
BX[t] = BXadd * sqrt(std::min(na_omit(vn_complete[t], vn1_complete[t])));
}
return BX;
// return vn_complete[0];
}
Error 1 occurred building shared library.
It works if I don't use na_omit.
R code for running the function:
Rcpp::sourceCpp("test.cpp")
timesTwo(5, 2, 5:9, 1:5)
What follows below is a slightly non-sensical answer (as it only works with vectors not containing NA) but it has all the component your code has, and it compiles.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector foo(int time_length, double BXadd,
NumericVector vn_complete, NumericVector vn1_complete) {
// Empty vectors
NumericVector BX (time_length);
vn_complete = na_omit(vn_complete);
vn1_complete = na_omit(vn1_complete);
for(int t = 0; t < time_length; t++) {
double a = vn_complete[t];
double b = vn1_complete[t];
BX[t] = BXadd * std::sqrt(std::min(a,b));
}
return BX;
}
// Edited version with new function added
// [[Rcpp::export]]
NumericVector foo2(double BXadd, NumericVector vn_complete,
NumericVector vn1_complete) {
return BXadd * sqrt(pmin(vn_complete, vn1_complete));
}
/*** R
foo(5, 2, 5:9, 1:5)
foo2(5, 2, 5:9, 1:5)
*/
For a real solution you will have to think harder about what the removal of NA is supposed to do as it will alter the lenth of your vectors too. So this still needs work.
Lastly, your whole function can be written in R as
2 * sqrt(pmin(5:9, 1:5))
and I think you could write that same expression using Rcpp sugar too as we have pmin() and sqrt():
// [[Rcpp::export]]
NumericVector foo2(double BXadd, NumericVector vn_complete,
NumericVector vn1_complete) {
return BXadd * sqrt(pmin(vn_complete, vn1_complete));
}

In Rcpp How to create a NumericMatrix by a NumbericaVector?

In Rcpp How to create a NumericMatrix by a NumbericaVector?
Something like
// vector_1 has 16 element
NumericMatrix mat = NumericMatrix(vector_1, nrow = 4);
Thanks.
Edit: I knew we had something better. See below for update.
Looks like we do not have a matching convenience constructor for this. But you can just drop in a helper function -- the following is minimally viable (one should check that n + k == length(vector)) and taken from one of the unit tests:
// [[Rcpp::export]]
Rcpp::NumericMatrix vec2mat(Rcpp::NumericVector vec, int n, int k) {
Rcpp::NumericMatrix mat = Rcpp::no_init(n, k);
for (auto i = 0; i < n * k; i++) mat[i] = vec[i];
return mat;
}
Another constructor takes the explicit dimensions and then copies the payload for you (via memcpy()), removing the need for the loop:
// [[Rcpp::export]]
Rcpp::NumericMatrix vec2mat2(Rcpp::NumericVector s, int n, int k) {
Rcpp::NumericMatrix mat(n, k, s.begin());
return mat;
}
Full example below:
> Rcpp::sourceCpp("~/git/stackoverflow/66720922/answer.cpp")
> v <- (1:9) * 1.0 # numeric
> vec2mat(v, 3, 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> vec2mat2(v, 3, 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
>
Full source code below.
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericMatrix vec2mat(Rcpp::NumericVector vec, int n, int k) {
Rcpp::NumericMatrix mat = Rcpp::no_init(n, k);
for (auto i = 0; i < n * k; i++) mat[i] = vec[i];
return mat;
}
// [[Rcpp::export]]
Rcpp::NumericMatrix vec2mat2(Rcpp::NumericVector s, int n, int k) {
Rcpp::NumericMatrix mat(n, k, s.begin());
return mat;
}
/*** R
v <- (1:9) * 1.0 # numeric
vec2mat(v, 3, 3)
vec2mat2(v, 3, 3)
*/
Depending on what you want to do with the matrix object (linear algrebra?) you may want to consider RcppArmadillo (or RcppEigen) as those packages also have plenty of vector/matrix converters.

Fill a NumericMatrix with a single value on construction

I'm trying to fill a NumericMatrix with a single value on construction. As an example, consider the following:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test() {
NumericMatrix res(1, 1, NA_REAL);
}
This is throwing the error of:
error: call to constructor of 'Vector<14, PreserveStorage>' is ambiguous
VECTOR( start, start + (static_cast<R_xlen_t>(nrows_)*ncols) ),
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
file46e92f4e027d.cpp:6:17: note: in instantiation of function template specialization 'Rcpp::Matrix<14, PreserveStorage>::Matrix<double>' requested here
NumericMatrix res(1, 1, NA_REAL);
/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include/Rcpp/vector/Vector.h:88:5: note: candidate constructor [with T = double]
Vector( const T& size, const stored_type& u,
^
/Library/Frameworks/R.framework/Versions/4.0/Resources/library/Rcpp/include/Rcpp/vector/Vector.h:211:5: note: candidate constructor [with InputIterator = double]
Vector( InputIterator first, InputIterator last){
^
Why is a NumericMatrix unable to be instantiated with a single value alongside fixed dimensions?
So in short this works (one longer line broken in three for display):
> Rcpp::cppFunction("NumericVector fp() {
+ NumericVector res(3,NA_REAL);
+ return res;}")
> fp()
[1] NA NA NA
>
but there is no matching constructor using rows, cols for matrices. So you have to use what vectors give you above, and set dimensions by hand.
For example via (where I had it all in one line which I broke up here for exposition)
> Rcpp::cppFunction("NumericMatrix fp(int n, int k) {
+ NumericVector res(n*k,NA_REAL);
+ res.attr(\"dim\") = IntegerVector::create(n,k);
+ return NumericMatrix(res);}")
> fp(2,3)
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
>
Not to usurp Dirk, but there isn't a need to set the dimensions of the matrix with .attr().
Filling a matrix, unlike a vector, requires supplying an iterator with n * p elements alongside dimensions for the constructor.
Matrix(const int& nrows_, const int& ncols, Iterator start)
For other constructors, please see: inst/include/Rcpp/vector/Matrix.h
With this in mind, the original example can be changed to:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::NumericMatrix matrix_fill_by_vec(int n, int p) {
// fill matrix using a vector
Rcpp::NumericVector A = Rcpp::NumericVector(n * p, NA_REAL);
Rcpp::NumericMatrix B = Rcpp::NumericMatrix(n, p, A.begin());
return B;
}
Taking it for a test drive, we get:
matrix_fill_by_vec(3, 2)
# [,1] [,2]
# [1,] NA NA
# [2,] NA NA
# [3,] NA NA

Apply lambda function to `arma::cube` in `RcppArmadillo`

I tried to use RcppArmadillo to compute the Frobenious norm across each slice of an array(arma::cube). The example code in file cxxFuns.cpp is presented below.
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
arma::vec array_norm (arma::cube & x) {
arma::vec out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
return out ;
}
After the cpp file is compiled successfully, the function array_norm throws an exception:
set.seed(2020)
Rcpp::sourceCpp('cxxFuns.cpp')
x <- array(rnorm(3*4*5), 3:5)
array_norm(x)
#> error: copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
#> Error in array_norm(x) :
#> copy into matrix: can't interpret cube with dimensions 3x4x5 as a vector
Created on 2020-12-02 by the reprex package (v0.3.0)
That actually an error message from Armadillo because something is not right with your logic yet -- the result is not a vector. You can see that by changing to this (self-contained, a very nice Rcpp trick) code:
Code
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
// [[Rcpp::export]]
bool array_norm (arma::cube & x) {
auto out = x.each_slice([](arma::mat& x0) {return arma::norm(x0, "fro") ;}) ;
out.print("out");
return true;
}
/*** R
set.seed(2020)
x <- array(rnorm(3*4*5), 3:5)
array_norm2(x)
*/
Output
> Rcpp::sourceCpp("~/git/stackoverflow/65104769/answer.cpp")
> set.seed(2020)
> x <- array(rnorm(3*4*5), 3:5)
> array_norm2(x)
out
[cube slice 0]
0.3770 -1.1304 0.9391 0.1174
0.3015 -2.7965 -0.2294 -0.8531
-1.0980 0.7206 1.7591 0.9093
[cube slice 1]
1.1964 1.8000 -2.2890 1.0982
-0.3716 1.7040 0.0583 0.3182
-0.1233 -3.0388 2.1744 -0.0731
[cube slice 2]
0.8343 0.9367 -0.8125 2.4354
0.1988 -0.1474 -0.7437 0.3881
1.2978 0.1104 1.0953 0.2906
[cube slice 3]
-0.2856 0.4472 -0.3010 0.2531
0.0760 0.9085 -0.7260 -0.3707
-0.5603 -0.5051 -1.1801 0.0222
[cube slice 4]
0.6600 0.6014 0.1188 -1.3283
0.4888 -0.6738 0.1212 -0.5669
-0.1888 0.4761 -0.1860 0.5788
[1] TRUE

Resources