1 What is this?

Short answer: various things I can never remember.

2 Vectors, row vectors, column vectors etc

A numeric vector (type vec) is a column vector (same as type colvec): Likewise, an integer vector (type ivec) is a column vector (same as type icolvec), and an unsigned vector (type uvec) is a column vector (same as type ucolvec):

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
//[[Rcpp::export]]
void foo (arma::vec  v1_, arma::colvec  v2_, arma::rowvec  v3_,
          arma::ivec v4_, arma::icolvec v5_, arma::irowvec v6_,
          arma::uvec v7_, arma::ucolvec v8_, arma::urowvec v9_){
    Rprintf("v1_:\n"); v1_.print();
    Rprintf("v2_:\n"); v2_.print();
    Rprintf("v3_:\n"); v3_.print();
    Rprintf("v4_:\n"); v4_.print();
    Rprintf("v5_:\n"); v5_.print();
    Rprintf("v6_:\n"); v6_.print();
    Rprintf("v7_:\n"); v7_.print();
    Rprintf("v8_:\n"); v8_.print();
    Rprintf("v9_:\n"); v9_.print();
}
v_num <- c(1, 2)
v_int <- c(1L, -2L)
v_uns <- c(1L, 2L)
foo(v_num, v_num, v_num, v_int, v_int, v_int, v_uns, v_uns, v_uns)
## v1_:
##    1.0000
##    2.0000
## v2_:
##    1.0000
##    2.0000
## v3_:
##    1.0000   2.0000
## v4_:
##         1
##        -2
## v5_:
##         1
##        -2
## v6_:
##         1       -2
## v7_:
##         1
##         2
## v8_:
##         1
##         2
## v9_:
##         1        2

3 Coercion and printing

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
// [[Rcpp::export]]
void coerce_and_print(int a, double b){

    // arma::vec  a1 = {a};              // OK but throws warning
    arma::vec  a1 = {(double) a};
    arma::ivec a2 = {a};
    // arma::uvec a3 = {a};              // OK but throws warning
    arma::uvec a3 = {(unsigned int) a};
    
    arma::vec  b1 = {b};
    // arma::ivec b2 = {b};              // OK but throws warning
    arma::ivec b2 = {(int) b};
    arma::uvec b3 = {(unsigned int) b};

    // Rcpp::NumericVector v1 = {a, b};  // OK but throws warning
    Rcpp::NumericVector v1 = {(double) a, b};
    Rcpp::IntegerVector v2 = {a, (int) b};

    // int c2 = {v1(0)};                 // OK but throws warning
    int c1 = {(int) v1(0)};
    double c2 = {v1(0)};

    // Rprintf can print standard C types 
    Rprintf("Rprintf Input: a=%d, b=%f\n", a, b);
    
    Rcpp::Rcout << "Rcout for a\n" << a1 << a2 << a3 << "\n";
    Rcpp::Rcout << "Rcout for b\n" << b1 << b2 << b3 << "\n";
    Rcpp::Rcout << "Rcout for v\n" << "v1: " << v1 << " v2: " << v2 << "\n";
    Rcpp::Rcout << "Rcout for c\n" << "c1: " << c1 << " c2: " << c2 << "\n";
    Rprintf("Rprintf: c1=%d, c2=%f\n", c1, c2);
    Rprintf("Rf_PrintValue v1 \n"); Rf_PrintValue(v1);
    Rprintf("Rf_PrintValue a1 \n"); Rf_PrintValue(Rcpp::wrap(a1));
}
coerce_and_print(10L, 4.1)
## Rprintf Input: a=10, b=4.100000
## Rcout for a
##    10.0000
##         10
##         10
## 
## Rcout for b
##    4.1000
##         4
##         4
## 
## Rcout for v
## v1: 10 4.1 v2: 10 4
## Rcout for c
## c1: 10 c2: 10
## Rprintf: c1=10, c2=10.000000
## Rf_PrintValue v1 
## [1] 10.0  4.1
## Rf_PrintValue a1 
##      [,1]
## [1,]   10

4 Call-by-reference and call-by-value

The ampersand (&) dicatates call-by-reference, but this only applies when the input type is as expected; otherwise a copying operation takes place (so that the call is effectively call-by-value):

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
//[[Rcpp::export]]
void foo (arma::vec& v1_, arma::vec& v2_, arma::ivec& v3_, arma::ivec& v4_){
    v1_(0) = 10000;
    v2_(0) = 10000;
    v3_(0) = 10000;
    v4_(0) = 10000;
}
v1_num <- c(1, -2)
v2_int <- c(1L, -2L)
v3_num <- c(1, -2)
v4_int <- c(1L, -2L)
foo(v1_num, v2_int, v3_num, v4_int)
v1_num ## Input argument is modified
## [1] 10000    -2
v2_int ## Input argument is not modified; a copy has been made
## [1]  1 -2
v3_num ## Input argument is not modified; a copy has been made
## [1]  1 -2
v4_int ## Input argument is modified
## [1] 10000    -2

5 Various utilities

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

// [[Rcpp::export]]
arma::uvec setdiff_(arma::uvec x, arma::uvec y){    
    x = arma::unique(x);
    y = arma::unique(y);    
    for (size_t j = 0; j < y.n_elem; j++) {
        arma::uvec q1 = arma::find(x == y[j]);
        if (!q1.empty()) {
            x.shed_row(q1(0));
        }
    }
    return x;
}

// [[Rcpp::export]]
arma::vec rep_nout(vec x, int nout){
    vec x_(nout);
    int k = 0;
    for (int i=0; i<nout; i++){
        x_(i) = x(k++);
        if (k == x.n_elem)
            k = 0;
    }
    return(x_);    
}

// [[Rcpp::export]]
arma::mat vec2mat(arma::vec x, int nrow, int ncol) {
    arma::vec x_ = rep_nout(x, nrow * ncol);
    arma::mat y(x_);
    y.set_size(nrow, ncol);
    return y;
}
setdiff_(rev(1:10), 5:8)  |> as.numeric()
## [1]  1  2  3  4  9 10
rep_nout(1:5, 15) |> as.numeric()
##  [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
vec2mat(1:5, 3, 5)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    2    5    3
## [2,]    2    5    3    1    4
## [3,]    3    1    4    2    5

6 Remove, extract and replace elements from vectors and matrices

6.1 Remove, extract and replace elements from vectors

// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>

// [[Rcpp::export]]
arma::vec remove_elem(arma::vec X, arma::uvec ent_, int shift=1) {
  X.shed_rows(ent_ - shift); // remove elements
  return(X);
}

// [[Rcpp::export]]
arma::vec extract_elem(arma::vec X, arma::uvec ent_, int shift=1) {
    return X.rows(ent_ - shift);
}

// [[Rcpp::export]]
arma::vec replace_elem(arma::vec X, arma::uvec ent_, arma::vec value_, int shift=1) {
    X.rows(ent_ - shift) = value_;
    return(X);
}

6.1.1 Results:

vec <- c(9, 6, 7, 4, 5, 8, 1, 2, 3)
ent <- c(3, 5, 8, 9)     ## Entries
vls <- c(-7, -5, -2, -3) ## Replacement values
## Remove elements
vec[-ent]
## [1] 9 6 4 8 1
remove_elem(vec, ent) |> as.numeric()
## [1] 9 6 4 8 1
## Extract elements
vec[ent]
## [1] 7 5 2 3
extract_elem(vec, ent)  |> as.numeric()
## [1] 7 5 2 3
## Replace elements
vec2 <- vec; vec2[ent] <- vls; vec2
## [1]  9  6 -7  4 -5  8  1 -2 -3
replace_elem(vec, ent, vls)  |> as.numeric()
## [1]  9  6 -7  4 -5  8  1 -2 -3

6.2 Remove, extract and replace elements from matrices

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

// [[Rcpp::export]]
arma::uvec setdiff_(arma::uvec x, arma::uvec y){    
    x = arma::unique(x);
    y = arma::unique(y);    
    for (size_t j = 0; j < y.n_elem; j++) {
        arma::uvec q1 = arma::find(x == y[j]);
        if (!q1.empty()) {
            x.shed_row(q1(0));
        }
    }
    return x;
}

// [[Rcpp::export]]
arma::vec rep_nout(vec x, int nout){
    vec x_(nout);
    int k = 0;
    for (int i=0; i<nout; i++){
        x_(i) = x(k++);
        if (k == x.n_elem)
            k = 0;
    }
    return(x_);    
}

// [[Rcpp::export]]
arma::mat vec2mat(arma::vec x, int nrow, int ncol) {
    arma::vec x_ = rep_nout(x, nrow * ncol);
    arma::mat y(x_);
    y.set_size(nrow, ncol);
    return y;
}

// [[Rcpp::export]]
arma::mat remove_rows(arma::mat X, arma::uvec row_ent_, int shift=1) {
    X.shed_rows(row_ent_ - shift); // remove rows
    return(X);
}

// [[Rcpp::export]]
arma::mat extract_rows(arma::mat X, arma::uvec row_ent_, int shift=1) {
    return (X.rows(row_ent_ - shift));
}

// [[Rcpp::export]]
arma::mat replace_rows(arma::mat X, arma::uvec row, arma::vec value, int shift=1){
    arma::mat value_ = vec2mat(value, row.n_elem, X.n_cols);    
    X.rows(row - shift) = value_;
    return(X);
}

6.2.1 Results:

M <- matrix(1:15, nrow=3)
M
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,]    2    5    8   11   14
## [3,]    3    6    9   12   15
rr <- 1
cc <- c(4, 3)

## Remove rows 
remove_rows(M, rr)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    2    5    8   11   14
## [2,]    3    6    9   12   15
## Extract rows 
extract_rows(M, rr)
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## Replace rows 
replace_rows(M, c(1, 3), c(-10, -20, -30))
##      [,1] [,2] [,3] [,4] [,5]
## [1,]  -10  -30  -20  -10  -30
## [2,]    2    5    8   11   14
## [3,]  -20  -10  -30  -20  -10

7 Replacing elements in vectors and matrices

7.1 Replacing elements in matrices

M <- matrix(1:15, nrow=3)
u <- 2
cvals <- c(-100, -100)
rvals <- c(-300, -300, -300, -300)

M2 <- M
M2[-u, u] <- cvals
M2[u, -u] <- rvals
M2[-u, -u] <- c(rvals, 2*rvals)
M2
##      [,1] [,2] [,3] [,4] [,5]
## [1,] -300 -100 -300 -600 -600
## [2,] -300    5 -300 -300 -300
## [3,] -300 -100 -300 -600 -600
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace arma;
using namespace Rcpp;

// [[Rcpp::export]]
arma::uvec setdiff_(arma::uvec x, arma::uvec y){    
    x = arma::unique(x);
    y = arma::unique(y);    
    for (size_t j = 0; j < y.n_elem; j++) {
        arma::uvec q1 = arma::find(x == y[j]);
        if (!q1.empty()) {
            x.shed_row(q1(0));
        }
    }
    return x;
}

// [[Rcpp::export]]
arma::vec rep_nout(vec x, int nout){
    vec x_(nout);
    int k = 0;
    for (int i=0; i<nout; i++){
        x_(i) = x(k++);
        if (k == x.n_elem)
            k = 0;
    }
    return(x_);    
}

// [[Rcpp::export]]
arma::mat vec2mat(arma::vec x, int nrow, int ncol) {
    arma::vec x_ = rep_nout(x, nrow * ncol);
    arma::mat y(x_);
    y.set_size(nrow, ncol);
    return y;
}
#include <RcppArmadillo.h>
using namespace arma;
using namespace Rcpp;

// [[Rcpp::export]]
arma::mat replace_u_vc(arma::mat M, arma::uvec u, arma::uvec v, arma::vec value, int shift=1){
    arma::uvec vc_  = arma::linspace<arma::uvec>(1, M.n_cols, M.n_cols);
    arma::uvec vc  = setdiff_(vc_, v);
    arma::mat value_ = vec2mat(value, u.n_elem, vc.n_elem);    
    // Rprintf("u, uc:\n"); u.t().print(), uc.t().print();
    M.submat(u - shift, vc - shift) = value_;
    return(M);
}

// M[-u, u] <- value
// [[Rcpp::export]]
arma::mat replace_uc_v(arma::mat M, arma::uvec u, arma::uvec v, arma::vec value, int shift=1){
    arma::uvec vr_  = arma::linspace<arma::uvec>(1, M.n_rows, M.n_rows);
    arma::uvec uc  = setdiff_(vr_, u);
    arma::mat value_ = vec2mat(value, uc.n_elem, u.n_elem);
    // Rprintf("u, uc:\n"); u.t().print(), uc.t().print();
    M.submat(uc - shift, v - shift) = value_; 
    return(M);
}


// [[Rcpp::export]]
arma::mat replace_uc_vc(arma::mat M, arma::uvec u, arma::uvec v, arma::vec value, int shift=1){
    arma::uvec vr_  = arma::linspace<arma::uvec>(1, M.n_rows, M.n_rows);
    arma::uvec vc_  = arma::linspace<arma::uvec>(1, M.n_cols, M.n_cols);
    arma::uvec uc  = setdiff_(vr_, u);
    arma::uvec vc  = setdiff_(vc_, v);
    arma::mat value_ = vec2mat(value, uc.n_elem, vc.n_elem);
    // Rprintf("u, uc:\n"); u.t().print(), uc.t().print();
    M.submat(uc - shift, vc - shift) = value_; 
    return(M);
}

// [[Rcpp::export]]
arma::mat replace_u_v(arma::mat M, arma::uvec u, arma::uvec v, arma::vec value, int shift=1){
    arma::mat value_ = vec2mat(value, u.n_elem, v.n_elem);    
    // Rprintf("u, uc:\n"); u.t().print(), uc.t().print();
    M.submat(u - shift, v - shift) = value_;
    return(M);
}

7.1.1 Results:

## Case 1
u <- 2
v <- 4
rvls <- c(-100, -100, -100, -100)
cvls <- c(-300, -300)
rcvls <- rep(rvls, 2)

## M2 <- M; M2[u, -v] <- rvls; M2
replace_u_vc(M, u, v, rvls) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,] -100 -100 -100   11 -100
## [3,]    3    6    9   12   15
## M2 <- M; M2[-u, v] <- cvls; M2
replace_uc_v(M, u, v, cvls) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7 -300   13
## [2,]    2    5    8   11   14
## [3,]    3    6    9 -300   15
## M2 <- M; M2[-u, -v] <- rcvls; M2
replace_uc_vc(M, u, v, rcvls)
##      [,1] [,2] [,3] [,4] [,5]
## [1,] -100 -100 -100   10 -100
## [2,]    2    5    8   11   14
## [3,] -100 -100 -100   12 -100
## Case2
u <- c(2, 3)
v <- c(3, 4)
rvls <- c(-100, -100, -100)
rvls2 <- rep(rvls, 2)
cvls <- -700
cvls2 <- rep(cvls, 2)

## M2 <- M; M2[u, -v] <- rvls; M2
replace_u_vc(M, u, v, rvls2) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,] -100 -100    8   11 -100
## [3,] -100 -100    9   12 -100
## M2 <- M; M2[-u, v] <- cvls2; M2
replace_uc_v(M, u, v, cvls2) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4 -700 -700   13
## [2,]    2    5    8   11   14
## [3,]    3    6    9   12   15
## M2 <- M; M2[-u, -v] <- rvls; M2
replace_uc_vc(M, u, v, rvls2) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,] -100 -100    7   10 -100
## [2,]    2    5    8   11   14
## [3,]    3    6    9   12   15
M2 <- M; M2[u, v] <- rvls2[1:4]; M2
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,]    2    5 -100 -100   14
## [3,]    3    6 -100 -100   15
replace_u_v(M, u, v, rvls2) 
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    4    7   10   13
## [2,]    2    5 -100 -100   14
## [3,]    3    6 -100 -100   15