Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Rcpp中的矩阵乘法

Rcpp中的矩阵乘法
EN

Stack Overflow用户
提问于 2016-05-12 15:43:03
回答 3查看 7.4K关注 0票数 14

首先,我是一个新手,所以忘记我一般的无知吧。我正在寻找一个更快的替代R中的%*%运算符的方法。尽管以前的帖子建议使用RcppArmadillo,但我已经尝试了2个小时,试图让RcppArmadillo工作,但没有成功。我总是遇到词汇问题,产生“意想不到的.”错误。我在Rcpp中找到了以下函数,我做的这些函数可以工作:

代码语言:javascript
运行
AI代码解释
复制
library(Rcpp)
func <- '
NumericMatrix mmult( NumericMatrix m , NumericMatrix v, bool  byrow=true )
{
  if( ! m.nrow() == v.nrow() ) stop("Non-conformable arrays") ;
  if( ! m.ncol() == v.ncol() ) stop("Non-conformable arrays") ;

  NumericMatrix out(m) ;

  for (int i = 0; i < m.nrow(); i++) 
  {
  for (int j = 0; j < m.ncol(); j++) 
  {
  out(i,j)=m(i,j) * v(i,j) ;
  }
  }
  return out ;
}
'

但是,此函数执行逐个元素的乘法,其行为与%*%不同。有没有一种简单的方法来修改上面的代码来达到预期的结果?

编辑:

我想出了一个使用RcppEigen的函数,它似乎比%*%更快:

代码语言:javascript
运行
AI代码解释
复制
etest <- cxxfunction(signature(tm="NumericMatrix",
                           tm2="NumericMatrix"),
                 plugin="RcppEigen",
                 body="
NumericMatrix tm22(tm2);
NumericMatrix tmm(tm);

const Eigen::Map<Eigen::MatrixXd> ttm(as<Eigen::Map<Eigen::MatrixXd> >(tmm));
const Eigen::Map<Eigen::MatrixXd> ttm2(as<Eigen::Map<Eigen::MatrixXd> >(tm22));

Eigen::MatrixXd prod = ttm*ttm2;
return(wrap(prod));
                 ")

set.seed(123)
M1 <- matrix(sample(1e3),ncol=50)
M2 <- matrix(sample(1e3),nrow=50)

identical(etest(M1,M2), M1 %*% M2)
[1] TRUE
res <- microbenchmark(
+   etest(M1,M2),
+   M1 %*% M2,
+   times=10000L)

res

Unit: microseconds
         expr    min    lq      mean median     uq    max neval
 etest(M1, M2)  5.709  6.61  7.414607  6.611  7.211 49.879 10000
     M1 %*% M2 11.718 12.32 13.505272 12.621 13.221 58.592 10000
EN

回答 3

Stack Overflow用户

发布于 2016-05-13 10:48:38

有充分的理由依赖现有的库/包来执行标准任务。库中的例程是

  • optimized
  • thoroughly测试了
  • 是一种保持代码紧凑、人类可读和易于维护的好方法。

因此,我认为在这里使用RcppArmadillo或RcppEigen应该更好。然而,为了回答你的问题,下面是一个执行矩阵乘法的可能的Rcpp代码:

代码语言:javascript
运行
AI代码解释
复制
library(Rcpp)
cppFunction('NumericMatrix mmult(const NumericMatrix& m1, const NumericMatrix& m2){
if (m1.ncol() != m2.nrow()) stop ("Incompatible matrix dimensions");
NumericMatrix out(m1.nrow(),m2.ncol());
NumericVector rm1, cm2;
for (size_t i = 0; i < m1.nrow(); ++i) {
    rm1 = m1(i,_);
    for (size_t j = 0; j < m2.ncol(); ++j) {
      cm2 = m2(_,j);
      out(i,j) = std::inner_product(rm1.begin(), rm1.end(), cm2.begin(), 0.);              
    }
  }
return out;
}')

让我们测试一下:

代码语言:javascript
运行
AI代码解释
复制
A <- matrix(c(1:6),ncol=2)
B <- matrix(c(0:7),nrow=2)
mmult(A,B)
#     [,1] [,2] [,3] [,4]
#[1,]    4   14   24   34
#[2,]    5   19   33   47
#[3,]    6   24   42   60
identical(mmult(A,B), A %*% B)
#[1] TRUE

希望这能有所帮助。

正如基准测试所显示的,上面的Rcpp代码比R的内置%*%操作符要慢。我假设,虽然我的Rcpp代码肯定可以改进,但在性能方面很难击败%*%背后的优化代码:

代码语言:javascript
运行
AI代码解释
复制
library(microbenchmark)
set.seed(123)    
M1 <- matrix(rnorm(1e4),ncol=100)
M2 <- matrix(rnorm(1e4),nrow=100)
identical(M1 %*% M2, mmult(M1,M2))
#[1] TRUE
res <- microbenchmark(
             mmult(M1,M2),
             M1 %*% M2,
             times=1000L)
#> res 
#Unit: microseconds
#          expr      min        lq      mean    median        uq      max neval cld
# mmult(M1, M2) 1466.855 1484.8535 1584.9509 1494.0655 1517.5105 2699.643  1000   b
#     M1 %*% M2  602.053  617.9685  687.6863  621.4335  633.7675 2774.954  1000  a
票数 12
EN

Stack Overflow用户

发布于 2016-05-12 16:15:13

我鼓励你尝试用RcppArmadillo解决你的问题。使用它与此示例一样简单,也是通过调用RcppArmadillo.package.skeleton()创建的

代码语言:javascript
运行
AI代码解释
复制
// another simple example: outer product of a vector, 
// returning a matrix
//
// [[Rcpp::export]]
arma::mat rcpparma_outerproduct(const arma::colvec & x) {
    arma::mat m = x * x.t();
    return m;
}

// and the inner product returns a scalar
//
// [[Rcpp::export]]
double rcpparma_innerproduct(const arma::colvec & x) {
    double v = arma::as_scalar(x.t() * x);
    return v;
}

示例中实际上有更多的代码,但这应该会让您有所了解。

票数 5
EN

Stack Overflow用户

发布于 2020-12-21 15:33:02

也可以使用以下方法:

代码语言:javascript
运行
AI代码解释
复制
NumericMatrix mmult(NumericMatrix m, NumericMatrix v)
{
  Environment base("package:base");
  Function mat_Mult = base["%*%"];
  return(mat_Mult(m, v));
}

在这种方法中,我们使用R的运算符%*%。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37191673

复制
相关文章
根据获取内部元素的高度,设置iframe的高度
iframe 是一个非常迷得一个元素,很难直接获取其内部元素的高度。 下面分享一个方法,可以获取 iframe 内部元素的高度: function setIframeHeight(id){     try{         var iframe = document.getElementById(id);         if(iframe.attachEvent){             iframe.attachEvent("onload", function(){                 i
德顺
2019/11/13
9.5K0
jquery中获取元素的几种方式小结
1 从集合中通过指定的序号获取元素 <div> <p>0</p> <p>1</p> <p>2</p> <p>3</p> <p>4</p> <p>5</p> <p>6</p> <p>7</p> </div> <script type="text/javascript"> jQuery(function(){ $("p").eq(2).css("color","red"); $("p").eq(3).css("color","red"); }) </script> 2
用户7657330
2020/08/14
2K0
jquery获取元素绑定的事件
一个简单的记录,在调试jquery的事件绑定时会用到。查看某元素是否绑定上了事件。
the5fire
2019/02/28
4.4K0
JavaScript、Jquery获取屏幕的宽度和高度
在日常的项目中经常需要获取屏幕的宽度或者高度,简单记录一下: Javascript方法获取: document.body.clientWidth //网页可见区域宽 document.body.clientHeight //网页可见区域高 document.body.offsetWidth //网页可见区域宽(包括边线的宽) document.body.offsetHeight //网页可见区域高(包括边线的高) document.body.scrollWidth //网页正文全文宽 document.b
德顺
2019/11/13
5.5K0
jquery获取第几个子元素_js获取元素的指定子元素
通过children方法,children(“input:first-child”)
全栈程序员站长
2022/08/03
27.5K0
jquery 获取鼠标和元素的坐标点
2,获取对象元素的位置(offset()方法) var offset = obj.offset(); 获取对象元素的位置,分别是元素的top和left,调用方法是:offset.left和offset.top,可知当前对象的左部和顶部位置。
Yiiven
2022/12/15
2.5K0
jquery获取元素到页面顶部的距离
在前端开发过程中,经常会遇到要求滚动条滚动到某位置时某按钮固定在页面上,否则悬浮于页面上。这时就会用到获取需要固定在页面位置的元素距离页面顶部的距离,通过比较文档滚动条到顶部的距离和页面元素到顶部距离的大小便可确定。
OECOM
2020/07/01
5.4K0
jQuery中不同元素的作用
removeClass() - 从被选元素删除一个或多个类 toggleClass() - 对被选元素进行添加/删除类的切换操作 css() - 设置或返回样式属性
用户7718188
2021/10/07
1.8K0
jquery获取第几个元素的方法总结
使用jquery时经常会遇到,选择器选择一组元素后,需要在这组元素中找到第几个元素。
江一铭
2022/06/17
1.1K0
jquery获取紧邻的上一个元素
本章节分享一段代码实例,它实现了获取紧邻的上一个同级元素的功能。 代码实例如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.pipipi.net/" /> <title>犀牛前端部落</title> <style type="text/css"> #box li { width: 350px; height: 25px; line-height: 25
IT工作者
2021/12/28
1.4K0
jquery 与javascript 获取元素尺寸大小的对比
jquery获取尺寸的方法 width() 方法设置或返回元素的宽度(不包括内边距、边框或外边距)。 height() 方法设置或返回元素的高度(不包括内边距、边框或外边距)。
tianyawhl
2019/04/04
1.9K0
jQuery获取和设置元素属性
之前使用css方法可以给标签设置样式属性,那么设置标签的其它属性可以使用prop方法了。
落雨
2022/03/01
31K0
jQuery获取和设置元素内容
1. html方法的使用 jquery中的html方法可以获取和设置标签的html内容 示例代码: <script> $(function(){ var $div = $("#div1"); // 获取标签的html内容 var result = $div.html(); alert(result); // 设置标签的html内容,之前的内容会清除 $div.html("<span style='c
落雨
2022/03/01
31.2K0
伪元素的作用_获取iframe中的元素
获取网页源代码也获取不了这些动态渲染的数据 所以用简单的,但是有点麻烦的方法 使用selenium执行js,或者直接在浏览器里面执行js
全栈程序员站长
2022/11/04
7.3K0
伪元素的作用_获取iframe中的元素
jquery实现的倒数获取li元素简单介绍
大家eq()的参数为0的时候就是获取第一个元素,为1的时候就是第二个元素,以此类推。
IT工作者
2022/02/22
1.9K0
js、jQuery 获取文档、窗口、元素的各种值
浏览器当前窗口文档body的宽度: document.body.clientWidth;(仅仅是body的width) 浏览器当前窗口文档body的高度: document.body.clientHeight;(仅仅是body的height)
Krry
2018/09/10
14.5K0
jQuery 替换元素中class的方法
实现方法: ① 使用removeClass()删除旧的class ② 使用addClass()添加新的class ③ 使用attr 直接替换原class ④ 使用 toggleClass 有就移除,没有就添加
青梅煮码
2023/01/16
2.5K0
JavaScript与jQuery获取元素的宽、高和位置
今天汇总整理了 JavaScript 和 jQuery 获取元素宽高和位置的方法,比较全面,方便自己和需要并搜到此文章的朋友们查看。
德顺
2019/11/13
3.2K0
ie8和chrome获取上传图片的宽度和高度等尺寸
测试后可用 <html> <head>     <title>测试</title>     <meta charset="utf-8"/>     <link rel="styleshee
汤高
2018/03/28
1.8K0
JQuery如何获取ID含有特殊字符的DOM元素
为业务需要,DOM元素的ID被命名为“c-order.range”,执行JQuery的DOM查询时,提示如下错误
黄啊码
2021/09/26
11K0

相似问题

IE jQuery返回auto而不是元素宽度

37

获取元素的自动高度,而不将高度设置为auto

22

使用jquery获取元素的可视高度,而不是其实际高度

30

jQuery获取高度(像素)

70

获取计算的高度- Javascript -而不是jQuery

21
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档