在 Rcpp 中使用 NumericMatrix 和 NumericVector 进行矩阵乘法
Matrix Multiplication Using NumericMatrix and NumericVector in Rcpp
我想知道有没有一种方法可以使用 NumericMatrix 和 NumericVector class 来计算矩阵乘法。我想知道有没有简单的方法
帮助我避免以下循环来进行此计算。我只想计算 X%*%beta。
// assume X and beta are initialized and X is of dimension (nsites, p),
// beta is a NumericVector with p elements.
for(int j = 0; j < nsites; j++)
{
temp = 0;
for(int l = 0; l < p; l++) temp = temp + X(j,l) * beta[l];
}
非常感谢您!
根据 Dirk 的评论,这里有几个案例通过重载的 *
运算符演示 Armadillo 库的矩阵乘法:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export(".mm")]]
arma::mat mm_mult(const arma::mat& lhs,
const arma::mat& rhs)
{
return lhs * rhs;
}
// [[Rcpp::export(".vm")]]
arma::mat vm_mult(const arma::vec& lhs,
const arma::mat& rhs)
{
return lhs.t() * rhs;
}
// [[Rcpp::export(".mv")]]
arma::mat mv_mult(const arma::mat& lhs,
const arma::vec& rhs)
{
return lhs * rhs;
}
// [[Rcpp::export(".vv")]]
arma::mat vv_mult(const arma::vec& lhs,
const arma::vec& rhs)
{
return lhs.t() * rhs;
}
然后您可以定义一个 R 函数来分派适当的 C++ 函数:
`%a*%` <- function(x,y) {
if (is.matrix(x) && is.matrix(y)) {
return(.mm(x,y))
} else if (!is.matrix(x) && is.matrix(y)) {
return(.vm(x,y))
} else if (is.matrix(x) && !is.matrix(y)) {
return(.mv(x,y))
} else {
return(.vv(x,y))
}
}
##
mx <- matrix(1,nrow=3,ncol=3)
vx <- rep(1,3)
my <- matrix(.5,nrow=3,ncol=3)
vy <- rep(.5,3)
与 R 的 %*%
函数相比:
R> mx %a*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
[2,] 1.5 1.5 1.5
[3,] 1.5 1.5 1.5
R> mx %*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
[2,] 1.5 1.5 1.5
[3,] 1.5 1.5 1.5
##
R> vx %a*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
R> vx %*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
##
R> mx %a*% vy
[,1]
[1,] 1.5
[2,] 1.5
[3,] 1.5
R> mx %*% vy
[,1]
[1,] 1.5
[2,] 1.5
[3,] 1.5
##
R> vx %a*% vy
[,1]
[1,] 1.5
R> vx %*% vy
[,1]
[1,] 1.5
我想知道有没有一种方法可以使用 NumericMatrix 和 NumericVector class 来计算矩阵乘法。我想知道有没有简单的方法 帮助我避免以下循环来进行此计算。我只想计算 X%*%beta。
// assume X and beta are initialized and X is of dimension (nsites, p),
// beta is a NumericVector with p elements.
for(int j = 0; j < nsites; j++)
{
temp = 0;
for(int l = 0; l < p; l++) temp = temp + X(j,l) * beta[l];
}
非常感谢您!
根据 Dirk 的评论,这里有几个案例通过重载的 *
运算符演示 Armadillo 库的矩阵乘法:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export(".mm")]]
arma::mat mm_mult(const arma::mat& lhs,
const arma::mat& rhs)
{
return lhs * rhs;
}
// [[Rcpp::export(".vm")]]
arma::mat vm_mult(const arma::vec& lhs,
const arma::mat& rhs)
{
return lhs.t() * rhs;
}
// [[Rcpp::export(".mv")]]
arma::mat mv_mult(const arma::mat& lhs,
const arma::vec& rhs)
{
return lhs * rhs;
}
// [[Rcpp::export(".vv")]]
arma::mat vv_mult(const arma::vec& lhs,
const arma::vec& rhs)
{
return lhs.t() * rhs;
}
然后您可以定义一个 R 函数来分派适当的 C++ 函数:
`%a*%` <- function(x,y) {
if (is.matrix(x) && is.matrix(y)) {
return(.mm(x,y))
} else if (!is.matrix(x) && is.matrix(y)) {
return(.vm(x,y))
} else if (is.matrix(x) && !is.matrix(y)) {
return(.mv(x,y))
} else {
return(.vv(x,y))
}
}
##
mx <- matrix(1,nrow=3,ncol=3)
vx <- rep(1,3)
my <- matrix(.5,nrow=3,ncol=3)
vy <- rep(.5,3)
与 R 的 %*%
函数相比:
R> mx %a*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
[2,] 1.5 1.5 1.5
[3,] 1.5 1.5 1.5
R> mx %*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
[2,] 1.5 1.5 1.5
[3,] 1.5 1.5 1.5
##
R> vx %a*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
R> vx %*% my
[,1] [,2] [,3]
[1,] 1.5 1.5 1.5
##
R> mx %a*% vy
[,1]
[1,] 1.5
[2,] 1.5
[3,] 1.5
R> mx %*% vy
[,1]
[1,] 1.5
[2,] 1.5
[3,] 1.5
##
R> vx %a*% vy
[,1]
[1,] 1.5
R> vx %*% vy
[,1]
[1,] 1.5