Fill a NumericMatrix with a single value on construction - rcpp

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

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
>

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.

Create NumericMatrix from NumericVector

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
>

How to slice Rcpp NumericVector for elements 2 to 101?

Hi I'm trying to slice Rcpp's NumericVector for elements 2 to 101
in R, I would do this:
array[2:101]
How do I do the same in RCpp?
I tried looking here: http://gallery.rcpp.org/articles/subsetting/
But the resource has an example that lists all the elements using IntegerVector::create(). However, ::create() is limited by the number of elements. (in addition to being tedious). Any way to slice a vector given 2 indices?
This is possible with Rcpp's Range function. This generates the equivalent C++ positional index sequence. e.g.
Rcpp::Range(0, 3)
would give:
0 1 2 3
Note: C++ indices begin at 0 not 1!
Example:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericVector subset_range(Rcpp::NumericVector x,
int start = 1, int end = 100) {
// Use the Range function to create a positional index sequence
return x[Rcpp::Range(start, end)];
}
/***R
x = rnorm(101)
# Note: C++ indices start at 0 not 1!
all.equal(x[2:101], subset_range(x, 1, 100))
*/

RcppArmadillo and C++ division issue

A very simple question regarding RcppArmadillo. Trying to multiply a vector by a scalar, and getting different results depending on small changes in syntax.
Any ideas?
// [[Rcpp::depends("RcppArmadillo")]]
// [[Rcpp::export]]
arma::vec funtemp(arma::vec x)
{
// return(x/10); // this works
// return((1/10)*x); // this does not work
return(x*(1/10)); // this does not work
}
Ahh, the good ol' integer vs. double division problem in C++. Before we begin, note that: arma::vec is by default a double and 1, 10, 1/10 are all ints...
Let's take a look at your functions separately:
#include <RcppArmadillo.h>
// [[Rcpp::depends("RcppArmadillo")]]
// [[Rcpp::export]]
arma::vec funtemp_one(arma::vec x)
{
return(x/10); // this works
}
// [[Rcpp::export]]
arma::vec funtemp_two(arma::vec x)
{
return((1/10)*x); // this does not work
}
// [[Rcpp::export]]
arma::vec funtemp_three(arma::vec x)
{
return(x*(1/10)); // this does not work
}
Therefore, when we run through your problem we get:
> funtemp_one(1)
[,1]
[1,] 0.1
> funtemp_two(1)
[,1]
[1,] 0
> funtemp_three(1)
[,1]
[1,] 0
In the later functions (e.g. the 1/10), the operator/ that is being used is int based division. As a result, 2 ints enter and 1 int is returned. If the result is not divisible, then you end up with a zero being returned as it is outside of the integer scope.
In order to use the double version, which returns a double, at least one of the ints must be explicitly cast to a double. This happens by default in the first case as you have a double/int due to arma::vec's structure. The second and third cases have an int/int structure that can be dealt with in two ways: 1. use a .0 after the int or 2. explicitly cast the value as a double with double(int)
e.g.
// [[Rcpp::export]]
arma::vec funtemp_four(arma::vec x)
{
return(x*(1/10.0)); // this works
}
// [[Rcpp::export]]
arma::vec funtemp_five(arma::vec x)
{
return(x*(1/double(10))); // this works
}
Will give what you expect:
> funtemp_four(1)
[,1]
[1,] 0.1
> funtemp_five(1)
[,1]
[1,] 0.1

Resources