F.Ответ Приве показал, что вы можете использовать uvec
для подмножества матрицы, используя .cols()
, даже если она не является непрерывным диапазоном, используя базовую функцию R seq()
для генерации последовательности.Далее я покажу, что вы можете сгенерировать последовательность, используя функцию Armadillo;Вы можете использовать arma::regspace()
- он «генерирует [s] вектор с регулярно расположенными элементами» ( Источник документации Armadillo ):
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
mat subset_armamat(mat X, int k) {
uvec IDX = regspace<uvec>(0, k, X.n_cols-1);
return X.cols(IDX);
}
Для сравнения с вызовом R seq()
(где subset_armamatR()
- функция из ответа Ф. Приве):
library("Rcpp")
sourceCpp("subset_armamat.cpp")
mat <- matrix(1:10, 2, 5, byrow = TRUE)
subset_armamat(mat, 2)
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 6 8 10
subset_armamatR(mat, 2)
#> [,1] [,2] [,3]
#> [1,] 1 3 5
#> [2,] 6 8 10
library(microbenchmark)
microbenchmark(Rseq = subset_armamatR(mat, 2),
regspace = subset_armamat(mat, 2))
#> Unit: microseconds
#> expr min lq mean median uq max neval cld
#> Rseq 235.535 239.1615 291.1954 241.9850 248.6005 4704.467 100 a
#> regspace 14.221 15.0225 520.9235 15.8165 16.6740 50408.375 100 a
Обновление: передача по ссылке
Комментарий от hbrerkere требует некоторых кратких дополнительныхобсуждение.Если вы вызываете эту функцию из C ++, вы наберете скорость, изменив mat subset_armamat(mat X, int k)
на mat subset_armamat(const mat& X, int k)
.Подобная передача по ссылке позволяет избежать ненужной копии, и когда вы не собираетесь изменять объект, переданный по ссылке, вы должны использовать const
.Однако, если вы вызываете эту функцию из R, вы не можете избежать копирования, так как arma::mat
не является собственным типом R (см., Например, этот ответ от Dirk Eddelbuettel (сопровождающий Rcpp
и RcppArmadillo
). Рассмотрим следующий пример:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
// [[Rcpp::export]]
void reference_example(arma::mat& X) {
X(0, 0) = 42;
}
// [[Rcpp::export]]
void print_reference_example(arma::mat X) {
reference_example(X);
Rcpp::Rcout << X << "\n";
}
Затем вызов из R:
library("Rcpp")
sourceCpp("reference_example.cpp")
mat <- matrix(1:4, 2, 2)
mat
#> [,1] [,2]
#> [1,] 1 3
#> [2,] 2 4
reference_example(mat)
mat
#> [,1] [,2]
#> [1,] 1 3
#> [2,] 2 4
print_reference_example(mat)
#> 42.0000 3.0000
#> 2.0000 4.0000
mat
#> [,1] [,2]
#> [1,] 1 3
#> [2,] 2 4