Search code examples
c++rrcpparmadillo

(c++, armadillo) Replace a part of column vector from a matrix


I'm using Rcpp with Armadillo library. My algorithm has a for-loop where I updates j-th column without j-th element at every step. Therefore, after a cycle, the input matrix will have all off-diagonal elements replaced with new values. To this end, I write Rcpp code like below.

arma::mat submatrix(
        arma::mat A,
        arma::uvec rowid){
  for(int j = 0; j < A.n_rows; j++){
    A.submat(rowid, "j") = randu(A.n_rows - 1);
  }
  return A;
}

However, I'm not sure how the submatrix view will work in the for-loop.

If you replace "j" in the above code with any of below, then this toy example submatrix(matrix(rnorm(3 * 4), nrow = 3, ncol = 4), c(1:2)) will return an error message.

  • (uvec) j : error: Mat::elem(): incompatible matrix dimensions: 2x0 and 2x1

  • j or (unsigned int) j : no matching member function for call to 'submat'

How could I handle this issue? Any comment would be very appreciated!


Solution

  • I have to confess that you do not fully understand your question -- though I think I get the idea of replace 'all but one' elements of a given row or column.

    But your code has a number of problems. The following code is simpliefied (as I replace the full row), but it assigns row by row. You probably want something like this X.submat( first_row, first_col, last_row, last_col ), possibly in two chunks (assign above diagonal, then below). There is a bit more in the Armadillo documentation about indexing, and there is more too at the Rcpp Gallery.

    #include <RcppArmadillo.h>
    
    // [[Rcpp::depends(RcppArmadillo)]]
    
    // [[Rcpp::export]] 
    arma::mat submatrix(arma::mat A, arma::uvec rowid, int k) {
      for (arma::uword j = 0; j < A.n_rows; j++) {
        A.row(j) = arma::randu(A.n_rows).t();
      }
      return A;
    }
    
    /*** R 
    M <- matrix(1:16,4,4)
    submatrix(M, 1, 1)  
    */