使用 RcppArmadillo 在矩阵的列上应用函数可以工作,但在行上应用时出现 returns 错误
Applying a function over columns of matrix using RcppArmadillo works but returns error when applied over rows
我在 Rcpp
中编写了一个函数 qSelectMbycol
,该函数 returns 在 O(n) 时间内成为每列的第 k
大元素。这个功能工作正常。如果我尝试做同样的事情但处理行而不是列(函数 qSelectMbyrow
),它 returns 错误 "error: Mat::init(): requested size is not compatible with column vector layout"
。有人认为我做错了什么吗?我将此文件保存为“qselect.cpp
”:
// [[Rcpp::depends(RcppArmadillo)]]
#define RCPP_ARMADILLO_RETURN_COLVEC_AS_VECTOR
#include <RcppArmadillo.h>
using namespace arma;
// [[Rcpp::export]]
arma::vec qSelectMbycol(arma::mat& M, const int k) {
// ARGUMENTS
// M: matrix for which we want to find the k-th largest elements of each column
// k: k-th statistic to look up
arma::mat Y(M.memptr(), M.n_rows, M.n_cols);
// we apply over columns
int c = M.n_cols;
arma::vec out(c);
int i;
for (i = 0; i < c; i++) {
arma::vec y = Y.col(i);
std::nth_element(y.begin(), y.begin() + k - 1, y.end());
out(i) = y(k-1); // the k-th largest value of each column
}
return out;
}
// [[Rcpp::export]]
arma::vec qSelectMbyrow(arma::mat& M, const int k) {
// ARGUMENTS
// M: matrix for which we want to find the k-th largest elements of each row
// k: k-th statistic to look up
arma::mat Y(M.memptr(), M.n_rows, M.n_cols);
// we apply over rows
int r = M.n_rows;
arma::vec out(r);
int i;
for (i = 0; i < r; i++) {
arma::vec y = Y.row(i); // this line throws the error "error: Mat::init(): requested size is not compatible with column vector layout"
std::nth_element(y.begin(), y.begin() + k - 1, y.end());
out(i) = y(k-1); // should give k-th largest value of each row
}
return out;
}
示例:
n=500
p=100
set.seed(1)
M=matrix(rnorm(n, mean = 100, sd = 1),n,1)
library(Rcpp)
library(RcppArmadillo)
Rcpp::sourceCpp('qselect.cpp')
qSelectMbycol(M,5) # works OK
qSelectMbyrow(M,5) # throws error "error: Mat::init(): requested size is not compatible with column vector layout"
我也试过插入
typedef std::vector<double> stdvec;
并将行设置向量 y
替换为
arma::vec y = arma::conv_to<stdvec>::from(Y.row(i));
在我的 qSelectMbyrow
函数中,虽然函数然后 运行s,但它 运行s 比在列上应用慢,并且如果我 运行 100 次。
问题是 arma::vec
实际上是 arma::colvec
(参见 the docs)。所以,我们可以通过改变
来解决这个问题
arma::vec y = Y.row(i);
(这是不兼容的,因为它认为你想要一个只有一列的矩阵,但你试图给它一个只有一行的矩阵)到
arma::rowvec y = Y.row(i);
我在 Rcpp
中编写了一个函数 qSelectMbycol
,该函数 returns 在 O(n) 时间内成为每列的第 k
大元素。这个功能工作正常。如果我尝试做同样的事情但处理行而不是列(函数 qSelectMbyrow
),它 returns 错误 "error: Mat::init(): requested size is not compatible with column vector layout"
。有人认为我做错了什么吗?我将此文件保存为“qselect.cpp
”:
// [[Rcpp::depends(RcppArmadillo)]]
#define RCPP_ARMADILLO_RETURN_COLVEC_AS_VECTOR
#include <RcppArmadillo.h>
using namespace arma;
// [[Rcpp::export]]
arma::vec qSelectMbycol(arma::mat& M, const int k) {
// ARGUMENTS
// M: matrix for which we want to find the k-th largest elements of each column
// k: k-th statistic to look up
arma::mat Y(M.memptr(), M.n_rows, M.n_cols);
// we apply over columns
int c = M.n_cols;
arma::vec out(c);
int i;
for (i = 0; i < c; i++) {
arma::vec y = Y.col(i);
std::nth_element(y.begin(), y.begin() + k - 1, y.end());
out(i) = y(k-1); // the k-th largest value of each column
}
return out;
}
// [[Rcpp::export]]
arma::vec qSelectMbyrow(arma::mat& M, const int k) {
// ARGUMENTS
// M: matrix for which we want to find the k-th largest elements of each row
// k: k-th statistic to look up
arma::mat Y(M.memptr(), M.n_rows, M.n_cols);
// we apply over rows
int r = M.n_rows;
arma::vec out(r);
int i;
for (i = 0; i < r; i++) {
arma::vec y = Y.row(i); // this line throws the error "error: Mat::init(): requested size is not compatible with column vector layout"
std::nth_element(y.begin(), y.begin() + k - 1, y.end());
out(i) = y(k-1); // should give k-th largest value of each row
}
return out;
}
示例:
n=500
p=100
set.seed(1)
M=matrix(rnorm(n, mean = 100, sd = 1),n,1)
library(Rcpp)
library(RcppArmadillo)
Rcpp::sourceCpp('qselect.cpp')
qSelectMbycol(M,5) # works OK
qSelectMbyrow(M,5) # throws error "error: Mat::init(): requested size is not compatible with column vector layout"
我也试过插入
typedef std::vector<double> stdvec;
并将行设置向量 y
替换为
arma::vec y = arma::conv_to<stdvec>::from(Y.row(i));
在我的 qSelectMbyrow
函数中,虽然函数然后 运行s,但它 运行s 比在列上应用慢,并且如果我 运行 100 次。
问题是 arma::vec
实际上是 arma::colvec
(参见 the docs)。所以,我们可以通过改变
arma::vec y = Y.row(i);
(这是不兼容的,因为它认为你想要一个只有一列的矩阵,但你试图给它一个只有一行的矩阵)到
arma::rowvec y = Y.row(i);