Short answer: various things I can never remember.
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
// [[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
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
// [[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
// [[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);
}
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
// [[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);
}
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
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);
}
## 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