Reputation: 1399
I’m trying to write a function that takes in a vector of 0's and 1's (input), and returns a vector equal to the first, but with each element overwritten by 0 if any previous element was 0 (res). The first element is 1 by default. To do this, for each i, I return the minimum of the ith element of the input vector and the previous result (prev_res).
When I run my function I get the wrong output (exactly the input), but when I include a call to std::cout
to print a blank line, I get the expected result. Which seems weird!
I’ve attached the code below.
library(Rcpp)
cppFunction(
'NumericVector any_zeroes_previously(IntegerVector input) {
// ** input is a vector of 0 and 1, indicating if timeperiod_num==lag_timeperiod_num+1 **
NumericVector res = NumericVector(input.length());
for (int i=0; i<input.length(); i++) {
int prev_res;
if (i==0) {
// first row of new group
res[i] = 1;
prev_res = 1;
} else {
// 2nd row of group onwards
res[i] = std::min(input[i], prev_res);
prev_res = res[i];
// ** when next line is commented out, produces incorrect result **
std::cout << "";
}
}
return res;
}')
test = c(1,1,0,1,0,0)
# expected result: 1 1 0 0 0 0
# result with print: 1 1 0 0 0 0
# result without print: 1 1 0 1 0 0
any_zeroes_previously(test)
Upvotes: 3
Views: 86
Reputation: 9705
You're using the variable prev_res
uninitialized, which is undefined behavior and can be anything.
Every iteration of your for loop re-declares prev_res
and if i != 0
you then take the minimum of input[i]
and prev_res
(any value). A simple fix is to take prev_res
outside of the for loop:
cppFunction(
'NumericVector any_zeroes_previously(IntegerVector input) {
// ** input is a vector of 0 and 1, indicating if timeperiod_num==lag_timeperiod_num+1 **
NumericVector res = NumericVector(input.length());
int prev_res;
for (int i=0; i<input.length(); i++) {
if (i==0) {
// first row of new group
res[i] = 1;
prev_res = 1;
} else {
// 2nd row of group onwards
res[i] = std::min(input[i], prev_res);
prev_res = res[i];
// ** when next line is commented out, produces incorrect result **
std::cout << "";
}
}
return res;
}')
Upvotes: 4