如何在R中使用RcppArmadillo正确传入行向量执行矩阵乘法?
问题描述
我正在用Rcpp为R编写一个向量矩阵乘法函数,原本在R中执行的操作是:
t(v)%*%v
对应的RcppArmadillo函数如下,能正常运行:
arma_code <- "arma::mat arma_vv(const arma::vec& v1, const arma::vec& v2) { return v1.t() * v2; };" arma_vv = cppFunction(code = arma_code, depends = "RcppArmadillo")
后来我想在R中处理转置(因为有时v1传入前已经被转置),于是修改了函数:
arma_code <- "arma::mat arma_vv(const arma::vec& v1, const arma::vec& v2) { return v1 * v2; };" arma_vv = cppFunction(code = arma_code, depends = "RcppArmadillo")
但发现即使传入行向量,v1还是会被转换成列向量,导致报错:
Error: matrix multiplication: incompatible matrix dimensions: 1000x1 and 1000x1
解决方案
核心问题是Armadillo的arma::vec仅对应列向量,无论R传入的是行还是列向量,都会被强制转为列向量,直接执行v1 * v2必然维度不匹配。以下是两种可行解决方法:
方法一:重载函数适配行/列向量
为arma::vec(列向量)和arma::rowvec(行向量)分别定义函数版本,让R根据输入自动匹配:
arma_code <- "// 列向量 × 列向量(对应R中t(v1)%*%v2) arma::mat arma_vv(const arma::vec& v1, const arma::vec& v2) { return v1.t() * v2; } // 行向量 × 列向量(对应R中v1%*%v2) arma::mat arma_vv(const arma::rowvec& v1, const arma::vec& v2) { return v1 * v2; } // 列向量 × 行向量(对应R中v1%*%t(v2)) arma::mat arma_vv(const arma::vec& v1, const arma::rowvec& v2) { return v1 * v2; } // 行向量 × 行向量(对应R中v1%*%t(v2)) arma::mat arma_vv(const arma::rowvec& v1, const arma::rowvec& v2) { return v1 * v2.t(); };" arma_vv = cppFunction(code = arma_code, depends = "RcppArmadillo")
这样不管传入行还是列向量,函数都会自动选择正确的乘法逻辑,避免维度错误。
方法二:改用矩阵类型作为参数
如果不想写重载函数,直接用arma::mat接收参数,保留原始维度信息:
arma_code <- "arma::mat arma_vv(const arma::mat& m1, const arma::mat& m2) { return m1 * m2; };" arma_vv = cppFunction(code = arma_code, depends = "RcppArmadillo")
R中的行向量(本质是1×N矩阵)和列向量(N×1矩阵)会被正确映射为Armadillo矩阵,乘法逻辑和R完全一致,无需额外处理转置。
额外优化:使用Armadillo内置函数
如果只是计算内积或外积,可直接用Armadillo的内置函数,更高效:
- 内积(对应R中
t(v1)%*%v2):arma::dot(v1, v2),返回标量 - 外积(对应R中
v1%*%t(v2)):arma::outer(v1, v2),返回矩阵
内容的提问来源于stack exchange,提问作者user19904
相关产品推荐
相关产品推荐

