Home > Enterprise >  How to convert R to C for Rcpp
How to convert R to C for Rcpp

Time:10-10

The following R code chunk is very inefficient in terms of speed and I need it to be significantly faster as in the original problem the length(dt) is quite large.

Can you help me convert the following R code chunk to C in order to utilize RCPP function in R? My knowledge of C is very close to 0 and can't figure out how to do the conversion.

inity <- 0
cumy <- rep(0,length = length(dt))
dec.index <- 1
startingPoint <- 2
temp <- numeric()
repFlag <- F

for (i in 2:length(dt)){
  cumy[i] <- inity   rgamma(n = 1, shape = a*timedt, scale = b)
  inity <- cumy[i]
  
  if (dt[i] %in% decPoints){
    if (dt[i] %in% LTset){
      repFlag <- ifelse(cumy[i] >= LP, T, F)
    } else if (dt[i] %in% MainMDset && repFlag == T){
      genRanProb <- rbinom(1,1,(1-p1))
      cumy[i] <- inity*genRanProb
      inity <- cumy[i]
    } else if (dt[i] %in% ProbMDset && repFlag == T){
      genRanProb <- rbinom(1,1,pA)
      cumy[i] <- inity*genRanProb
      inity <- cumy[i]
    }
  }
}

If you want to run the code, you can use following values:

a <- 0.2
b <- 1
ph <- 1000
timedt <- 1
oppInt <- 90
dt <- seq(0,ph,timedt) 
LT <- 30
MainMDset <- seq(oppInt, ph, oppInt)
ProbMDset <- c(0,seq((oppInt   oppInt/2), ph, oppInt)) 
LTset <- sort(c(ProbMDset, MainMDset))
LTset <- LTset - LT
decPoints <- sort(c(LTset, ProbMDset, MainMDset))
decPoints <- decPoints[-which(decPoints < 0)]
decPoints[1] <- 1

p1 <- 0
pA <- 0.5
LP <- 40

Update: My attempt so far which ends up in error as shown in the figure.

NumericVector cumyRes(double a, double b, double timedt, NumericVector dt, NumericVector ProbMDset, NumericVector MainMDset, NumericVector decPoints, double LP, double LT){
  bool repFlag = false;
  int n = dt.size();
  double inity = 0;
  NumericVector out(n);
  unordered_set<double> sampleSetMd(MainMDset.begin(), MainMDset.end());
  unordered_set<double> sampleSetProb(ProbMDset.begin(), ProbMDset.end());
  unordered_set<double> sampleSetDec(decPoints.begin(), decPoints.end());

for (int i = 1; i < n;   i){
    out[i] <- inity   rgamma(1, a*timedt, 1/b)[0];
    inity <- out[i];
    if (sampleSetDec.find(dt[i])){
      if (out[i] >= LP){
        repFlag = true;
      } else {
        repFlag = false;
      }
    } 
    return out;
  }
}

  /*** R
  cumyRes(0.2, 1, 1, c(50,100,150,200), c(25,75,125,175), c(20, 45, 70, 95, 120, 145, 170, 195), 40, 30)
  */

enter image description here

CodePudding user response:

There are several errors in your C code, probably too many to list in a concise answer. However, the following corrections seem to follow your logic, and compiles to give similar answers to your R loop in less time:

Rcpp::cppFunction("
 NumericVector cumyRes(double a, double b, double timedt, NumericVector dt, 
                       NumericVector ProbMDset, NumericVector MainMDset, 
                       NumericVector decPoints, double LP, double LT,
                       double p1, double pA){
  bool repFlag = false;
  int n = dt.size();
  double inity = 0;
  NumericVector out(n);
  std::unordered_set<double> sampleSetMd(MainMDset.begin(), MainMDset.end());
  std::unordered_set<double> sampleSetProb(ProbMDset.begin(), ProbMDset.end());
  std::unordered_set<double> sampleSetDec(decPoints.begin(), decPoints.end());
  
  for (int i = 1; i < n;   i){
    double d = dt[i];
    out[i] = inity   rgamma(1, a * timedt, b)[0];
    inity = out[i];
    
    if (sampleSetDec.find(d) != sampleSetDec.end()) {
        if (sampleSetProb.find(d   LT) != sampleSetProb.end() ||
            sampleSetMd.find(d   LT) != sampleSetMd.end()) {
          repFlag = inity >= LP;
        } else if (sampleSetMd.find(d) != sampleSetMd.end() && repFlag) {
          double genRanProb = rbinom(1, 1, (1 - p1))[0];
          out[i] = inity * genRanProb;
          inity = out[i];
        } else if (sampleSetProb.find(d) != sampleSetProb.end() && repFlag) {
          double genRanProb = rbinom(1, 1, pA)[0];
          out[i] = inity * genRanProb;
          inity = out[i];
        }}}
  return out;
}")

You could test it with:

cumyRes(a, b, timedt, dt, ProbMDset, MainMDset, decPoints, LP, LT, p1, pA)
  • Related