Question

With the following simplified code I wish to simulate from the N(0,1) distribution and return a list with the simulated values as well as a vector which depends on the simulated normals (see the code below). The problem is that the if-else statement is not working at all! Please, could somebody help me understand where is the problem?

#include <RcppArmadillo.h>
#include <Rcpp.h>
using namespace Rcpp;

//[[Rcpp::depends(RcppArmadillo)]]

//[[Rcpp::export]]

List cond(arma::vec epsilon, IntegerVector Nsim) {
int iNsim = Nsim[0];
arma::vec ans(1);
arma::vec epsil(epsilon);
arma::vec vans  = arma::zeros(iNsim);
arma::vec vcond = arma::zeros(iNsim);
LogicalVector cond;
RNGScope scope;

for (int i=0; i<iNsim; i++) {

  ans = Rcpp::rnorm(1, 0.0, 1.0);
  vans.row(i) = ans[0];
  cond = abs(ans) >= epsil;
  if (cond) {
    vcond.row(i) = 10;
  } else {
    vcond.row(i) = -10;
  }
}

return List::create(
    _["sim"] = vans,
    _["cond"] = vcond);  
}

I run it in R by saving it to file.cpp and then by sourceCpp("file.cpp").

Was it helpful?

Solution

The original code is confused about where to use a vector, and where to use a scalar.

He is shorter and repaired version:

#include <Rcpp.h>

using namespace Rcpp;

//[[Rcpp::export]]
DataFrame cond(double epsil, int iNsim) {
  double ans;
  NumericVector vans(iNsim);
  NumericVector vcond(iNsim);
  RNGScope scope;

  for (int i=0; i<iNsim; i++) {
    ans = R::rnorm(0.0, 1.0);
    vans[i] = ans;
    if (fabs(ans) >= epsil) {
      vcond[i] = 10;
    } else {
      vcond[i] = -10;
    }
  }

  return DataFrame::create(_["sim"] = vans,
                           _["cond"] = vcond);  
}

Besides using (and passing) scalars where scalars were meant to be used, it also corrects abs() to fabs() -- a common C/C++ problem. I also reverted to Rcpp vectors - as much as I like to use Armadillo, it wasn't needed here.

Here is example output given a random seed:

 R> sourceCpp("/tmp/erlis.cpp")
 R> set.seed(1)
 R> cond(1.0, 6)   
         sim cond              
 1 -0.626454  -10
 2  0.183643  -10
 3 -0.835629  -10 
 4  1.595281   10
 5  0.329508  -10
 6 -0.820468  -10
 R> 

OTHER TIPS

Here is the solution:

#include <RcppArmadillo.h>
#include <Rcpp.h>
using namespace Rcpp;

//[[Rcpp::depends(RcppArmadillo)]]

//[[Rcpp::export]]

List cond(arma::vec epsilon, IntegerVector Nsim) {
int iNsim = Nsim[0];
arma::vec ans(1);
arma::vec epsil(epsilon);
arma::vec vans  = arma::zeros(iNsim);
arma::vec vcond = arma::zeros(iNsim);
LogicalVector cond;
RNGScope scope;

for (int i=0; i<iNsim; i++) {

  ans = Rcpp::rnorm(1, 0.0, 1.0);
  vans.row(i) = ans[0];
    bool go_ = true;
    for(int i = 0; i < ans.size(); i++)
        if(abs(ans[i]) < epsil[0])
            go_ = false;

  if (go_) {
    vcond.row(i) = 10;
  } else {
    vcond.row(i) = -10;
  }
}

return List::create(
    _["sim"] = vans,
    _["cond"] = vcond);  
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top