0

I am trying to assign values to specific rows and columns of a matrix using Rcpp and Armadillo.

This is the sort of subsetting and assignments that I am trying to do:

mat = matrix(1:15, nr=3)
r = i = 1; j = 3

mat[r, i:j] = mat[r, j:i]
mat[r, c(i,j)] = mat[r, c(j,i)]

I have read the nice Rcpp tutorial here and the arma docs here but have failed to understand adequately and my attempts result in errors. How can I do this please?

Rcpp code:

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;


//[[Rcpp::export]]
arma::mat fun() {

  arma::mat myMat = randu<mat>(3,5);
  int r = 1; int i = 1; int j = 3;

  // get indices to subset:
  // i:j and j:i
  arma::uvec v = regspace<arma::uvec>(i, 1, j);
  arma::uvec rv = reverse(v);
  // create c(i,j)  
  std::vector<int> ij;
  ij.push_back(i); 
  ij.push_back(j);

  // Try to update selected rows and columns
  // The following gives the error: 
  // ": no matching function for call to ‘arma::Mat<double>::submat(int&, arma::uvec&)’"
  //myMat.submat(r, v) = myMat.submat(r, rv); 

  // So try to coerce int r to uvec:
  // The following gives the error:
  // "no matching function for call to ‘arma::conv_to<arma::Col<unsigned int> >::from(int&)’"
  //arma::uvec kk = arma::conv_to<arma::uvec>::from(r);

  // Also tried the following with error: 
  // "no match for call to ‘(arma::mat {aka arma::Mat<double>}) (int&, arma::uvec&)’"
  // myMat(r, v) = myMat(r, rv); 

  return myMat;
}

Edit: I have something working -- by converting the integer r to an arma::uvec using r + arma::zeros<arma::uvec>(1). I assume there is a proper way to approach this.

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;


//[[Rcpp::export]]
arma::mat fun(arma::mat myMat) {

  int r = 0; int i = 0; int j = 2;

  // get indices to subset:
  // i:j and j:i
  arma::uvec v = regspace<arma::uvec>(i, 1, j);
  arma::uvec rv = reverse(v);

  arma::uvec row_idx = r + arma::zeros<arma::uvec>(1);
  myMat.submat(row_idx, v) = myMat.submat(row_idx, rv); 

  return myMat;
}

4

0 回答 0