This question already has an answer here:
- Rcpp pass by reference vs. by value 1 answer
I use Rcpp to outsource a nested loop from R (the time improvements are huge!). But I have encountered a strange behavior now. The first function testrun
takes as argument a matrix X
and loops over every row of that matrix. The row is passed to another function testfun
which runs another loop and performs some computations. For every computation a value is returned and stored and eventually returned by the testrun
function:
// [[Rcpp::export]]
Rcpp::NumericVector testrun(Rcpp::NumericMatrix X, Rcpp::NumericVector wal)
{
Rcpp::NumericVector c;
for(int i = 0; i != X.rows(); ++i)
{
c.push_back(testfun(X.row(i), wal));
}
return c;
}
The function testfun
works on every row of X
:
// [[Rcpp::export]]
int testfun(Rcpp::NumericVector x, Rcpp::NumericVector val)
{
int t = 0;
Rcpp::NumericVector val2 = val;
while(1)
{
std::vector<double> a;
std::vector<double> b;
for(int j = 0; j != x.length(); ++j)
{
a.push_back(std::sin(x.at(j)));
b.push_back(R::rnorm(1.0, 1.0));
}
for(int j = 0; j != x.length(); ++j)
{
if(a.at(j) > b.at(j))
{
val2[j] = 1;
}
}
if(Rcpp::sum(val2) == x.length())
{
break;
}
++t;
}
return t;
}
The second argument of testrun
and testfun
is a vector of "modifier" values which are used in the computation. The values of this vector get updated depending on the computation and thus serve as exit condition for the loop.
I call testrun
from R
X = expand.grid(replicate(2, list(seq(-3,3,length.out=10))))
wal = c(0.4, 0.2)
testrun(X, wal)
Both values in wal
are < 1. But apparently the values in wal
(in R!) get updated when updating val2
in testfun
. That is, the first time the exit condition is satisfied, it is satisfied for all subsequent steps. Why is this the case? And how do I prevent this behavior? If I use a single double
for wal
(and val2
) it works as intended.