R 如何建立;存储这个大的下三角矩阵用于矩阵向量乘法?

R 如何建立;存储这个大的下三角矩阵用于矩阵向量乘法?,r,performance,matrix,out-of-memory,matrix-multiplication,R,Performance,Matrix,Out Of Memory,Matrix Multiplication,我需要创建一个具有特殊结构的下三角矩阵,然后进行矩阵向量乘法 矩阵由值k参数化。它的主对角线是k^0的向量,即1;第一个子对角线是k^1的向量,而i-第四个子对角线保持k^i 下面是一个5 x 5的示例,其中k=0.9: structure(c(1, 0.9, 0.81, 0.729, 0.6561, 0, 1, 0.9, 0.81, 0.729, 0, 0, 1, 0.9, 0.81, 0, 0, 0, 1, 0.9, 0, 0, 0, 0, 1), .Dim = c(5L, 5L)) #

我需要创建一个具有特殊结构的下三角矩阵,然后进行矩阵向量乘法

矩阵由值
k
参数化。它的主对角线是
k^0
的向量,即1;第一个子对角线是
k^1
的向量,而
i
-第四个子对角线保持
k^i

下面是一个5 x 5的示例,其中
k=0.9

structure(c(1, 0.9, 0.81, 0.729, 0.6561, 0, 1, 0.9, 0.81, 0.729, 
0, 0, 1, 0.9, 0.81, 0, 0, 0, 1, 0.9, 0, 0, 0, 0, 1), .Dim = c(5L, 5L))
#       [,1]  [,2] [,3] [,4] [,5]
#[1,] 1.0000 0.000 0.00  0.0    0
#[2,] 0.9000 1.000 0.00  0.0    0
#[3,] 0.8100 0.900 1.00  0.0    0
#[4,] 0.7290 0.810 0.90  1.0    0
#[5,] 0.6561 0.729 0.81  0.9    1
我需要构造一个大到
100000 x 100000
的矩阵,并将其用于计算。我需要最有效的存储方法。有什么想法吗

试试这个:

k <- 0.9
n <- 5

d <- diag(n)
replace(k ^ (row(d) - col(d)), upper.tri(d), 0)
试试这个:

k <- 0.9
n <- 5

d <- diag(n)
replace(k ^ (row(d) - col(d)), upper.tri(d), 0)

您不必总是显式地形成矩阵来进行矩阵向量或矩阵乘法。例如,没有人真正形成对角矩阵并将其用于此类计算

矩阵和对角矩阵之间没有实质性的区别

所以你把运算简化为一系列向量加法。这里是一个简单的R级实现

MatVecMul <- function (y, k) {
  n <- length(y)
  z <- numeric(n)
  for (i in 1:n) z[i:n] <- z[i:n] + k ^ (i - 1) * y[1:(n - i + 1)]
  z
  }

MatVecMul执行矩阵向量或矩阵乘法并不总是需要显式地形成矩阵。例如,没有人真正形成对角矩阵并将其用于此类计算

矩阵和对角矩阵之间没有实质性的区别

所以你把运算简化为一系列向量加法。这里是一个简单的R级实现

MatVecMul <- function (y, k) {
  n <- length(y)
  z <- numeric(n)
  for (i in 1:n) z[i:n] <- z[i:n] + k ^ (i - 1) * y[1:(n - i + 1)]
  z
  }

MatVecMul谢谢。但是我希望有一种更好的方法,调用
diag(100000)
会导致错误
错误:无法分配大小为74.5 Gb的向量
即使使用稀疏矩阵,结果也超过该大小的一半,因此如果无法存储,则不太可能在内存中存储所需的矩阵。谢谢。但是我希望有一种更好的方法,调用
diag(100000)
会导致错误
错误:无法分配大小为74.5 Gb的向量
即使使用稀疏矩阵,结果也超过该大小的一半,因此如果无法存储,则不太可能将所需的矩阵存储在内存中。更准确地说,我需要将向量
v
从左侧乘以该矩阵(即
M%*%v
),更准确地说,我需要将向量
v
从左侧乘以该矩阵(即
M%*%v
),非常感谢!这真的很有帮助。如果你有一两分钟的时间,也许你可以在这里看看我的相关问题:。我现在必须对你的
Rcpp
函数做一些调整。非常感谢!这真的很有帮助。如果你有一两分钟的时间,也许你可以在这里看看我的相关问题:。我现在必须对你的
Rcpp
函数做一些调整。
library(Rcpp)
cppFunction("NumericVector MatVecMul_cpp (NumericVector y, double k) {
  int n = y.size();
  NumericVector z(n);
  int i; double *p1, *p2, *end = &z[n];
  double tmp = 1.0;
  for (i = 0; i < n; i++) {
    for (p1 = &z[i], p2 = &y[0]; p1 < end; p1++, p2++) *p1 += tmp * (*p2);
    tmp *= k;
    }
  return z;
  }")

MatVecMul_cpp(y, 0.9)
#[1] 0.8966972 1.0725361 1.3374064 1.7765191 2.5070750
v <- runif(1e4)
system.time(MatVecMul(y, 0.9))
#   user  system elapsed 
#  3.196   0.000   3.198 
system.time(MatVecMul_cpp(y, 0.9))
#   user  system elapsed 
#  0.840   0.000   0.841