I have this simple "for loop" written in R which I have to convert in to C++. Following is the reproducible example of R code:
# Parameters required
a <- 1.8
b <- 1
time.dt <- 0.1
yp <- 40
insp.int <- 7
ph <- 2000
dt <- seq(0,ph,time.dt) # Time sequence
MD.set <- c(seq(insp.int, ph, insp.int), ph) # Decision points to check and set next inspection date
# Initialization
cum.y <- rep(0,length = length(dt))
init.y <- 0
flag <- FALSE
# At each iteration, the following loop generates a gamma distributed random number and cum.y keeps taking cumulative sum
# The objective is to return a vector cum.y with a conditional cumulative sum of previous iteration
# When dt[i] matches any values in MD.Set AND corresponding cum.y[i] is also >= yp it changes the flag to true (the last if)
# At the start of the loop it checks if dt[i] matches any values in MD.Set AND flag is also true. If yes, then cum.y is reset to 0.
for (i in 2:length(dt)){
if (dt[i] %in% MD.set && flag == TRUE){
cum.y[i] <- 0
init.y <- 0
flag <- FALSE
next
} else {
cum.y[i] <- init.y + rgamma(n = 1, shape = a*time.dt, scale = b)
init.y <- cum.y[i]
if (dt[i] %in% MD.set && cum.y[i] >= yp){
flag <- TRUE
}
}
}
res <- cbind(dt, cum.y)
Having no prior experience with C++, I am running into numerous problems when trying to do so. I need to do this conversion only to be able to use it in Rcpp package in R. Because the code runs slowly in R, specially when time.dt becomes smaller and I am guessing C++ would do the job faster. Can you help with this?
UPDATE 2:
This is my proposal for the conversion with the help in comments and answer. However, I am not sure what is the equivalent of next in C++. If I use continue it keeps going through the rest of the codes (and execute the ones after else. If I use break then it comes out of the loop after the condition is true.
NumericVector cumy(double a, double b, double timedt, NumericVector dt, NumericVector MDSet, double yp){
bool flag = false;
int n = dt.size();
double total = 0;
NumericVector out(n);
unordered_set<int> sampleSet(MDSet.begin(), MDSet.end());
for (int i = 0; i < n; ++i){
if (sampleSet.find(dt[i]) != sampleSet.end() && flag == true){
out[i] = 0;
total = 0;
flag = false;
continue;
} else {
out[i] = total + rgamma(1, a*timedt, b)[0];
total = out[i];
if (sampleSet.find(dt[i]) != sampleSet.end() && out[i] >= yp){
flag = true;
}
}
}
return out;
}
NumericVectoris just a vector of ints, then you'd do:unordered_set<int> sampleSet(MDSet.begin(), MDSet.end());sampleSet.find(dt[i]) == sampleSet.begin()as the order inunordered_setis not preserved (hence the name) so you do not know which one is the first. Didn't you meansampleSet.end()? (possibly with!=)sampleSet.begin()is an iterator to an existing item of theunordered_setwhilesampleSet.end()is an iterator to a non-existing item returned by functions that does not find things in the container. Note that there are likely other items in between the two iterators, so not being the first does not mean that the item is not found (the returned iterator could besampleSet.begin()+1for example.