Given functions
set.seed(171111)
gen.mat <- function(dim, min = 0, max = 1) {
mat <- matrix(sample(min:max, dim^2, replace=TRUE), dim)
rownames(mat) <- LETTERS[1:dim]
colnames(mat) <- LETTERS[1:dim]
mat
}
adjmat <- gen.mat(dim = 5)
adjmat
## A B C D E
## A 0 1 1 1 0
## B 0 0 1 1 1
## C 1 1 1 0 0
## D 0 0 0 0 0
## E 1 0 1 1 1
Test
Rcpp::sourceCpp("leadingone.cpp")
leading.one <- leading_one
leading.num <- leading_one
leading.one(adjmat, 1)
## A B C D E
## A 0 1 0 0 0
## B 0 0 1 0 0
## C 1 0 0 0 0
## D 0 0 0 0 0
## E 1 0 0 0 0
leading.one(adjmat, 2)
## A B C D E
## A 0 1 1 1 0
## B 0 0 0 0 1
## C 1 0 0 0 0
## D 0 0 0 0 0
## E 0 0 0 0 0
adjmat <- gen.mat(5, 0, 2)
leading.num(adjmat, 1)
## A B C D E
## A 2 0 0 0 0
## B 0 2 0 0 0
## C 1 0 0 0 0
## D 2 0 0 0 0
## E 2 0 0 0 0
leading.num(adjmat, 2)
## A B C D E
## A 2 2 2 1 1
## B 0 0 0 0 0
## C 0 0 0 0 0
## D 0 0 0 0 0
## E 0 0 0 0 0
Full Source Code
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp1z)]]
// [[Rcpp::export]]
NumericVector find_first_nonzero(const NumericVector& v) {
NumericVector ret(v.size(), 0);
for (auto i = 0; i < v.size(); ++i) {
if (v[i] != 0) {
// non-zero found
ret[i] = v[i];
return ret;
}
}
return ret;
}
// [[Rcpp::export]]
NumericMatrix leading_one(const NumericMatrix& m, int dim) {
NumericMatrix ret(m);
int n_count = dim == 1 ? m.nrow() : m.ncol();
for (auto i = 0; i < n_count; ++i) {
if (dim == 1) {
// row by row
auto row = ret(i, _);
row = find_first_nonzero(row);
} else {
// col by col
auto col = ret(_, i);
col = find_first_nonzero(col);
}
}
return ret;
}
Benchmark
library(microbenchmark)
microbenchmark(
leading.one(adjmat, 1),
leading.one(adjmat, 2)
)
## Unit: microseconds
## expr min lq mean median uq max neval
## leading.one(adjmat, 1) 1.390 1.5435 1.81087 1.684 1.8915 9.887 100
## leading.one(adjmat, 2) 1.385 1.5025 1.67071 1.587 1.7830 2.396 100