假设我有以下矩阵。
x <- matrix(seq(1:4), 2, 2)
y <- matrix(seq(1:4), 2, 2)
我想做以下事情。
for(i in 1:5)
{
x <- x %*% y
}
然而,这是一个简单的例子。我通常有X和Y的大矩阵,我也是一个很大的数字。因此,使用for循环可能太耗时。
是否有人知道使用lapply或应用这些类型的函数。
感谢。
答案 0 :(得分:4)
library(expm)
x %*% (y %^% 5)
# [,1] [,2]
#[1,] 5743 12555
#[2,] 8370 18298
set.seed(42)
x <- matrix(rnorm(1e4), 1e2, 1e2)
y <- matrix(rnorm(1e4), 1e2, 1e2)
fun1 <- function(x, y, j) {
for(i in 1:j)
{
x <- x %*% y
}
x
}
fun2 <- function(x, y, i) {
x %*% (y %^% i)
}
fun3 <- function(x, y, i) {
Reduce("%*%", c(list(x), rep(list(y), i)))
}
library(expm)
all.equal(fun1(x,y,5), fun2(x,y,5))
#[1] TRUE
all.equal(fun1(x,y,5), fun3(x,y,5))
#[1] TRUE
library(microbenchmark)
microbenchmark(fun1(x,y,30),
fun2(x,y,30),
fun3(x,y,30), times=10)
#Unit: milliseconds
# expr min lq median uq max neval
#fun1(x, y, 30) 21.317917 21.908592 22.103380 22.182989 141.933427 10
#fun2(x, y, 30) 5.899368 6.068441 6.235974 6.345301 6.477417 10
#fun3(x, y, 30) 21.385668 21.896274 22.023001 22.086904 22.269527 10
答案 1 :(得分:1)
Reduce("%*%", c(list(x), rep(list(y), 5)))
# [,1] [,2]
# [1,] 5743 12555
# [2,] 8370 18298
会做到这一点。
答案 2 :(得分:1)
只是为了好玩,这是一个使用RcppEigen的解决方案:
C ++代码:
// [[Rcpp::depends(RcppEigen)]]
#include <RcppEigen.h>
using namespace Rcpp;
using Eigen::Map;
using Eigen::MatrixXd;
typedef Map<MatrixXd> MapMatd;
// [[Rcpp::export]]
NumericMatrix XYpow(NumericMatrix A, NumericMatrix B, const int j) {
const MapMatd X(as<MapMatd>(A)), Y(as<MapMatd>(B));
MatrixXd X1(X);
for (int i = 0; i < j; ++i) X1 = X1 * Y;
return wrap(X1);
}
然后在R:
all.equal(fun2(x,y,5), XYpow(x,y,5))
#[1] TRUE
microbenchmark(fun2(x,y,30),
XYpow(x,y,30), times=10)
#Unit: milliseconds
# expr min lq median uq max neval
# fun2(x, y, 30) 5.726292 5.768792 5.948027 6.041340 6.276624 10
# XYpow(x, y, 30) 6.926737 7.032061 7.232238 7.512486 7.617502 10