setting element name Rcpp error stack usage - r

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
*/

Related

An Rcpp function argument being a List filled with default values

It's my first post here! Woohoo!
I would like to have an Rcpp function that would have an argument being a list with some specified default values of its entries. I would like this function to work similarly to the following R function:
> nicetry_R = function(sv = list( a = rep(0, 2)) ) { sv$a }
> nicetry_R()
[1] 0 0
> nicetry_R(list(a=rep(1,2)))
[1] 1 1
In this function argument sv is a list specified by default to contain vector a set to rep(0,2).
What I tried in RcppArmadillo is a solution that is working by refering to R_NilValue in the argument List specification. Here's the content of my nicetry.cpp file:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector nicetry (Nullable<List> sv = R_NilValue) {
NumericVector aux_a(2);
if (sv.isNotNull()){
List SV(sv);
aux_a = SV["a"];
}
return aux_a;
}
/*** R
nicetry()
nicetry(list(a=rep(1,2)))
*/
It does what I want it to do in the sense that it produces the desired outcome:
> nicetry()
[1] 0 0
> nicetry(list(a=rep(1,2)))
[1] 1 1
But I would prefer to have the default values of the list specified in the argument line. The example below is just one of my failed attempts:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector nicetry (
List sv = List::create(Named("a",NumericVector::create(0,0)))
) {
NumericVector aux_a = sv["a"];
return aux_a;
}
/*** R
nicetry()
*/
In this example, the argument declaration contains the list. It does not compile though. When I copy the declaration of the List from the argument declaration section leaving this section empty, and paste the line in the body of the function: List sv = List::create(Named("a",NumericVector::create(0,0))); then the list is created and the outcome provided. But that's not what I want.
Do you think it's possible to declare such a list as an argument at all?
Thanks so much! Greetings, T

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>

Sequence of Integers in Rcpp

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

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