KEN
KEN

Reputation: 77

Trying to move numbers in NumericMatrix

I am created a double for loop in Rcpp to move up one cell all 1's in a column that has 5 in the next available cell. When I compile the code I don't get any error but the code does move 1's in the matrix, it just returns the same matrix. Let's take an original matrix, say named t:

5    1    1    1    1
1    5    5    5    1
5    5    1    5    5
5    0    0    5    1
5    5    0    1    1

after running the code up_rcpp(t,5,5), I should get the following results

    1    5    1    1    1
    5    5    1    5    1
    5    5    5    5    1
    5    0    0    5    5
    5    1    0    1    1

Below is my rcpp code:

 #include <Rcpp.h>

using namespace Rcpp;

//[[Rcpp::export]]

Rcpp::NumericMatrix up_rcpp(Rcpp::NumericMatrix main, int r, int c) {
  

 Rcpp::NumericMatrix t = clone(main);

  
  for (int j=0; j <= c-1; ++j) {
for (int i=0; i <= r-2; ++i){
  
  if ((t(i,j) == 5) & (t(i+1, j) == 1))
  {
    
    main(i, j)  = 1;
    main(i + 1, j) = 5;
  }
}

for (int i= r-1; i == r-1; ++i){
  if ((t(i, j) == 5) & (t(1, j) == 1))
  {
   
    main(i, j) = 1;
    main(1, j) = 5;
  }
}
  }

  return main;

}

Upvotes: 0

Views: 89

Answers (1)

Brian Montgomery
Brian Montgomery

Reputation: 2414

Maybe I'm a bit paranoid when I pass values to Rcpp, but I never allow my function to change what I pass either. But the clone(main) is necessary here to avoid changes to main changing t. The last piece was to change the 1 indicies to 0 for the top row.

#include <Rcpp.h>

using namespace Rcpp;

//[[Rcpp::export]]

Rcpp::NumericMatrix up_rcpp(Rcpp::NumericMatrix main, int r, int c) {
  
  
  Rcpp::NumericMatrix ans = clone(main);
  Rcpp::NumericMatrix t = clone(main);

  
  for (int j=0; j <= c-1; ++j) {
    for (int i=0; i <= r-2; ++i){
 
      if ((t(i,j) == 5) && (t(i+1, j) == 1))
      {
        
        ans(i, j)  = 1;
        ans(i + 1, j) = 5;
        
      }
    }
    for (int i= r-1; i <= r-1; ++i){
      if ((t(i, j) == 5) && (t(0, j) == 1))
      {
        ans(i, j) = 1;
        ans(0, j) = 5;
      }
    }
  }
  
  return ans;
  
}

Which gives:

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    5    1    1    1
[2,]    5    5    1    5    1
[3,]    5    5    5    5    1
[4,]    5    0    0    1    5
[5,]    5    1    0    5    1

This is different than your solution in column 4, but the way I understand the logic, this is correct.

Upvotes: 1

Related Questions