Sequence of Integers in Rcpp - r

I want to create a sequence of integer numbers for indexing within a matrix. The R pendant would be:
indexRow <- max(0,1):min(2,12)
matrix1[indexRow, ]
This is what i have tried in Rcpp to create the sequence of integers:
#include <Rcpp.h>
#include <algorithm>
#include <vector>
#include <numeric>
using namespace Rcpp;
using namespace std;
// [[Rcpp::export]]
NumericVector test(NumericVector x) {
IntegerVector indexRow = Rcpp::seq_along(max(0, 1), min(1, 12));
}
However I get the Error message:
no matching function for call to 'seq_along(const int&, const int&)'
How can I create a sequence of integers in Rcpp?

Here is a possible Rcpp implementation :
library(Rcpp)
cppFunction(plugins='cpp11','NumericVector myseq(int &first, int &last) {
NumericVector y(abs(last - first) + 1);
if (first < last)
std::iota(y.begin(), y.end(), first);
else {
std::iota(y.begin(), y.end(), last);
std::reverse(y.begin(), y.end());
}
return y;
}')
#> myseq(max(0,1), min(13,17))
#[1] 1 2 3 4 5 6 7 8 9 10 11 12 13
This code generates a function myseq which takes two arguments: The first and the last number in an integer series. It is similar to R's seq function called with two integer arguments seq(first, last).
A documentation on the C++11 function std::iota is given here.

seq_along takes in a vector, what you want to use is seq combined with min and max, both take vectors. seq returns an IntegerVector. Here is an example.
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector test(IntegerVector a, IntegerVector b) {
IntegerVector vec = seq(max(a), min(b));
return vec;
}
In R you use
> test(c(0,1), c(2,12))
[1] 1 2

Related

setting element name Rcpp error stack usage

In rcpp I want to create characterVector, with the vector variable set as character element
I tried with
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
CharacterVector assignName(){
CharacterVector rn={"a","b","c"};
rn.names()=rn;
return rn;
}
/***R
assignName()
m <- assignName()
m
*/
For example i have a CharacterVector rn as a,b,c.
rn should be set : a="a", b="b", c="c"
then in R after the call of this function as :
m<-assignName()
An error occurr :
Error: C stack usage 7969212 is too close to the limit
But if i do not assign the function to a variable all works, for example if i do :
>assignName()
a b c
"a""b""c"
I am not sure why this is the case, but it seems it is not a good idea to use the vector itself as name. You can fix this by using Rcpp::clone:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
CharacterVector assignName(){
CharacterVector rn={"a","b","c"};
// original rn.names()=rn;
rn.names()=clone(rn);
return rn;
}
/***R
assignName()
m <- assignName()
m
*/

Matrix indexing via integer vector

I want to access non-consecutive matrix elements and then pass the sub-selection to (for instance) the sum() function. In the example below I get a compile error about invalid conversion.
I am relatively new to Rcpp, so I am sure the answer is simple. Perhaps I am missing some type of cast?
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins("cpp11")]]
double sumExample() {
// these are the matrix row elements I want to sum (the column in this example will be fixed)
IntegerVector a = {2,4,6};
// create 10x10 matrix filled with random numbers [0,1]
NumericVector v = runif(100);
NumericMatrix x(10, 10, v.begin());
// sum the row elements 2,4,6 from column 0
double result = sum( x(a,0) );
return(result);
}
You were close. Indexing uses [] only -- see this write up at the Rcpp Gallery -- and you missed the export tag. The main issue is that compound expresssion are sometimes too much for the compiler and the template programming. So it works if you take it apart.
Corrected Code
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins("cpp11")]]
// [[Rcpp::export]]
double sumExample() {
// these are the matrix row elements I want to sum
// (the column in this example will be fixed)
IntegerVector a = {2,4,6};
// create 10x10 matrix filled with random numbers [0,1]
NumericVector v = runif(100);
NumericMatrix x(10, 10, v.begin());
// sum the row elements 2,4,6 from column 0
NumericVector z1 = x.column(0);
NumericVector z2 = z1[a];
double result = sum( z2 );
return(result);
}
/*** R
sumExample()
*/
Demo
R> Rcpp::sourceCpp("~/git/stackoverflow/56739765/question.cpp")
R> sumExample()
[1] 0.758416
R>

rcpp: how to apply gamma function to a scalar?

I guess the function gamma only works for a vector as the input. Is there a way to apply it to a scalar, say,gamma(3)`?
Actually, I would get the correct output if I include gamma(3) as part of my code, but there's a warning message....
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List fool(NumericVector vec){
double res = 0;
res = sum(gamma(vec)) + gamma(3);
List result;result["num"] = res;
return result;
}
Here is the warning messgae:
exp.cpp:7:27: warning: 'gamma' is deprecated: first deprecated in OS X 10.9 [-Wdeprecated-declarations]
res = sum(gamma(vec)) + gamma(3);
^
/usr/include/math.h:720:15: note: 'gamma' has been explicitly marked deprecated here
extern double gamma(double) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0, __MAC_10_9, __IPHONE_NA, __IPHONE_NA);
^
1 warning generated.
Thanks for posting code. You fell victim of being careless with namespaces. There is a (vectorized) gamma() in the Rcpp namespace -- the first argument and there is (was) a scalar gamma() (preferred: tgamma()) in the C math library. And it is better to be explicit.
Corrected code below:
#include <Rcpp.h>
// [[Rcpp::export]]
double fool(Rcpp::NumericVector vec){
double res =
Rcpp::sum(Rcpp::gamma(vec)) + // Rcpp sugar sum() and gamma() on vector
::tgamma(3.0); // math library tgamma of double
return res;
}
/*** R
v <- 1:5
fool(v)
sum(gamma(v)) + gamma(3)
*/
Output
R> sourceCpp("/tmp/shuang.cpp")
R> v <- 1:5
R> fool(v)
[1] 36
R> sum(gamma(v)) + gamma(3)
[1] 36
R>

Using RcppArmadillo each_col with lambda function?

According to the Armadillo website, you can pass in a lambda function into .each_col, such as
X.each_col( [](vec& a){ a.print(); } );
The following Rcpp seems to have an error though, reporting "Expected Expression"
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
arma::vec colCumSum(const arma::mat& X) {
return X.each_col( [](const arma::vec& b){ b.cumsum(); } );
}
You actually have to tell R to use C++11 in order to have lambda support. The magic line is [[Rcpp::plugins("cpp11")]] which makes it all work:
But once I do that I get issues on the cumsum(). You also had too many const in there.
So here is a simpler version which does work with another lambda from the documentation -- which just prints. I also turned to ivec and imat for consistency:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::plugins("cpp11")]]
// [[Rcpp::export]]
arma::ivec colCumSum(arma::imat& X) {
X.each_col( [](arma::ivec& a){ a.print(); } );
return X.col(0);
}
/*** R
M <- matrix(1:16, 4, 4)
colCumSum(M)
*/
When you source this, it builds and runs. You will need to work out the lambda use case for the reduction that cumsum() does.
> sourceCpp("/tmp/foo.cpp")
> M <- matrix(1:16, 4, 4)
> colCumSum(M)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
>

Rcpp sum over multiple indexes

I want to compute a function of the form:
$m_{jl}(x) = x + \gamma[j]*zeta[j,l] + sum_{k \neq j} zeta[j,k]$
using Rcpp. My problem is about the sum_{k \neq j} zeta[j,k]$.. I would like to be able to do something zeta[j,-j]. Is it possible? I tried zeta(j,-)-zeta(j,j), but the Rcpp does not like zeta(j,-).
You can use sugar functions:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
double myFun(NumericMatrix x) {
return sum(x)-sum(diag(x));
}
R:
A <- matrix(1:9,3)
sum(A)-sum(diag(A))
#[1] 26
myFun(A)
#[1] 26
I suspect this could be made faster with RcppEigen.

Resources