'RCPP and R discrepancy

I'm new to C++ programming and apologize if my solution is in plain sight. I am attempting to use RCPP to speed up a slow R function. I think I've narrowed down the issue to a nested for loop. I've simplified the function and provided one R and one RCPP version for comparison. Will someone please explain why my RCPP function yields different results? Thanks!

## Data ##

set.seed(666)
input <- rmultinom(10,2,c(.4,.5,.6)) + 1

## R ##

testR <- \(input){
  M1 <- matrix(c(0.5,0.4,0.0,0.3,0.5,0.0,0.2,0.1,1.0),3,3)
  M2 <- matrix(c(0.75,0.0,0.0,0.0,0.6,0.0,0.25,0.4,1.0),3,3)
  
  Mrows <- nrow(M1)
  tmsteps <- ncol(input)
  N <- nrow(input)
  
  alphas <- NULL; tmp <- NULL; out <- NULL
  for(i in 1:N){
    alphas = c(0,-1e6,-1e6)
    for(j in 1:tmsteps){
      for(k in 1:Mrows){
        tmp[k] = sum(alphas + M1[,k] + M2[k, input[i,j] ])
      }
      alphas <- tmp
    }
    out[i] <- sum(alphas)
  }
  sum(out)
  }

## RCPP ##

cppFunction('double testRCPP(IntegerMatrix input){
    NumericVector v1 = {0.5,0.4,0.0,0.3,0.5,0.0,0.2,0.1,1.0};
    v1.attr("dim") = Dimension(3, 3);
    NumericMatrix M1 = as<NumericMatrix>(v1);
    
    NumericVector v2 = {0.75,0.0,0.0,0.0,0.6,0.0,0.25,0.4,1.0};
    v2.attr("dim") = Dimension(3, 3);
    NumericMatrix M2 = as<NumericMatrix>(v2);
    
    int Mrows = M1.nrow();
    int tmsteps = input.ncol();
    int N = input.nrow();
    
    NumericVector alphas(3);
    NumericVector tmp(3);
    NumericVector out(N);
    
    for(int i=0; i<N; i++){
    alphas = {0,-1e6,-1e6};
      for(int j=0; j<tmsteps; j++){
        for(int k=0; k<Mrows; k++){
        tmp[k] = sum(alphas + M1(_,k) + M2(k, (input(i,j) - 1) ));
        }
      alphas = tmp;
    }
      out += alphas;
    }
    return(sum(out));
  }')

> testRCPP(input)
[1] -2.273726e+14
> testR(input)
[1] -354293536945


Solution 1:[1]

I have figured out how to get the Rcpp to behave like the R function. I think my issue has to do with C++ variable scoping.

I had previously been initializing the tmp variable outside the nested for loop.

NumericVector tmp(3);

    for(int i=0; i<N; i++){
    alphas = {0,-1e6,-1e6};
    ...

All is good when I declare the tmp variable inside the loop, although I don't understand why yet.

    for(int i=0; i<N; i++){
    alphas = {0,-1e6,-1e6};
      for(int j=0; j<tmsteps; j++){
      NumericVector tmp(3);
        for(int k=0; k<Mrows; k++){
        tmp[k] = sum(alphas + M1(_,k) + M2(k, (input(i,j) - 1) ));
        }
      alphas = tmp;
    }
...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brian Davis