r - 在 R 中高效使用 Choleski 分解

标签 r linear-algebra numerical-methods

此问题与 this one 相关还有这个one

我有两个满秩矩阵 A1, A2 维度为 p x p 和 p 向量 y。

这些矩阵密切相关,因为 矩阵A2是矩阵A1的一级更新。

我对向量感兴趣

β2 | (β1, y, A1, A2, A1-1})

哪里

β2 = (A2' A2)-1(A2'y)

β1 = (A1' A1)-1(A1' y)

现在,在之前的 question 中在这里我被告知 自 Choleski 方法以来,通过 Choleski 方法估计 β2 使用 R 函数(例如 chud())可以轻松更新分解 在SamplerCompare包中。

下面是 R 中求解线性系统的两个函数,第一个使用 solve() 函数和第二个 Choleski 方法 (我可以有效更新的第二个)。

fx01 <- function(ll,A,y) chol2inv(chol(crossprod(A))) %*% crossprod(A,y)

fx03 <- function(ll,A,y) solve(A,y)

p <- 5
A <- matrix(rnorm(p^2),p,p)
y <- rnorm(p)

system.time(lapply(1:1000,fx01,A=A,y=y))
system.time(lapply(1:1000,fx03,A=A,y=y))

我的问题是:对于 p 小,两个函数似乎具有可比性 (实际上 fx01 甚至更快)。但当我增加 p 时, fx01 变得越来越慢,因此对于 p = 100, fx03 的速度是 fx01 的三倍。

是什么原因导致 fx01 性能下降? 得到改进/解决(也许我对 Choleski 的实现太天真了?我是否应该使用 Choleski 星座的函数,例如 backsolve,如果是,如何实现?

  1. A %*% B 是 A 与 B 矩阵乘法的 R 语言。
  2. crossprod(A,B)A' B 的 R 术语(即 A 矩阵的转置 乘以矩阵/向量 B)。
  3. solve(A,b) 求解 x 线性方程组 A x=b。
  4. chol(A) 是 PSD 矩阵 A 的 Choleski 分解。
  5. chol2inv 根据 QR 分解的(R 部分)计算 (X' X)-1 X

最佳答案

正如您所提到的,您的“fx01”实现有些幼稚,并且比“fx03”方法执行的工作要多得多。在线性代数中(我对主 StackOverflow 不支持 LaTeX 表示歉意!),“fx01”执行:

  • B := A' A 大约需要 n^3 次失败。
  • L := chol(B) 大约需要 1/3 n^3 次失败。
  • L := inv(L) 大约需要 1/3 n^3 次失败。
  • B := L' L 大约需要 1/3 n^3 次失败。
  • z := A y 大约需要 2n^2 次失败。
  • x := B z 大约需要 2n^2 次失败。

因此,成本看起来与 2n^3 + 4n^2 非常相似,而您的 'fx03' 方法使用默认的 'solve' 例程,该例程可能会执行部分旋转的 LU 分解(2/3 n^3 flops) )和两个三角形在 2n^2 次失败中求解(加上旋转)。因此,您的“fx01”方法渐进地执行了三倍的工作,这与您的实验结果惊人地一致。请注意,如果 A 是实对称或复厄米特矩阵,则 LDL^T 或 LDL' 因式分解和求解只需要一半的工作量。

话虽如此,我认为您应该将 A' A 的 Cholesky 更新替换为 A 的更稳定的 QR 更新,正如我刚刚回答的 in your previous question 。 QR 分解大约需要 4/3 n^3 次浮点运算,而 QR 分解的秩一更新仅为 O(n^2),因此,当存在多个相关解时,这种方法仅对一般 A 有意义。只是一个一级修改。

关于r - 在 R 中高效使用 Choleski 分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8659412/

相关文章:

r - 从 data.frame 中的组中获取均值和标准差

r - 为什么 R 在学习过程中传递命令 (knn.pred=knn(train.X,test.X,train.Y,k=1)) 时抛出错误(无法找到函数 "knn")?

r - 将一列合并到另一列,并在合并列中添加上标(在表中添加 pvalue 重要性)

R图: Print text on margin in top left corner

python - 两个 3dim 矩阵的 numpy einsum 的 Theano 版本

python - python/numpy中的线性组合

algorithm - 如何仅通过张量操作将已知连通分量转换为邻接矩阵?

matrix - 仅一行不同的增量最小二乘法

c - 如何使用 GSL 库从两个复数变量中插值一个复数函数?

c++ - 使用 GNU 科学库 (GSL) 的 C/C++ 代码为 GNUPlot 提供了不同的结果 - 可能存在浮点不稳定性?