【问题标题】:Solve *sparse* upper triangular system求解 *sparse* 上三角系统
【发布时间】:2012-09-27 17:27:26
【问题描述】:

如果我想求解一个完整上三角系统,我可以致电linsolve(A,b,'UT')。但是,稀疏矩阵目前不支持此功能。我该如何克服这个问题?

【问题讨论】:

  • 使用full?
  • @chaohuang 一个非常糟糕的主意。他使用sparse 是有原因的。
  • 看看我更新的答案。

标签: matlab linear-algebra sparse-matrix triangular


【解决方案1】:

UT 和 LT 系统是最容易解决的系统之一。阅读on the wiki 了解它。知道了这一点,就很容易编写自己的 UT 或 LT 求解器:

%# some example data
A = sparse( triu(rand(100)) );
b = rand(100,1);

%# solve UT system by back substitution    
x = zeros(size(b));
for n = size(A,1):-1:1    
    x(n) = (b(n) - A(n,n+1:end)*x(n+1:end) ) / A(n,n);    
end

LT 系统的过程非常相似。

话虽如此,使用Matlab的反斜杠运算符通常更容易和更快:

x = A\b

这也适用于备件矩阵,正如 nate 已经指出的那样。

请注意,此运算符还解决了具有非正方形 AA 在主对角线上有一些元素等于零(或 < eps)的 UT 系统。它以最小二乘的方式解决了这些情况,这可能对您来说是可取的,也可能不是您想要的。您可以在执行求解之前检查这些情况:

if size(A,1)==size(A,2) && all(abs(diag(A)) > eps)
    x = A\b;
else
    %# error, warning, whatever you want
end

通过键入了解更多关于(反)斜杠运算符的信息

>> help \

>> help slash

在 Matlab 命令提示符下。

【讨论】:

  • 当然,我可以自己实现反向替换,我认为这很明显:) 问题是在 matlab 中通常避免使用 for 循环,因为它们非常慢。斜线操作是否保证对三角矩阵使用反向替换?
  • @noam:看看here
  • \ 是反斜杠或左除 (mldivide),而 / 是斜杠或右除 (mrdivide)。
  • 您使用单词slash 表示\,即backslash。只是为了挑剔;)
  • @angainor:你输入help backslash了吗?你会得到一个错误。输入help slash,您将获得所有(反)斜杠运算符的信息:)
【解决方案2】:

编辑由于您需要的是三角求解过程,也称为后向/前向替换,因此您可以使用普通的 MATLAB 反斜杠 \ 运算符:

x = U\b

如原始答案中所述,MATLAB 将识别出您的矩阵是三角形的事实。为了确定这一点,您可以将性能与SuiteSparse 中的cs_usolve 过程进行比较。它是一个用 C 语言实现的 mex 函数,用于计算上三角稀疏矩阵的稀疏三角求解(那里也有类似的函数:cs_lsolvecs_utsolvecs_ltsolve)。

您可以查看原生 MATLAB 的 performance comparison 和稀疏 Cholesky 分解上下文中的 cs_l(t)solve。从本质上讲,MATLAB 性能很好。唯一的陷阱是如果你想解决一个转置系统

x = U'\b

MATLAB 确实识别并显式创建U 的转置。在这种情况下,您应该明确调用 cs_utsolve

原始答案如果您的系统是对称的并且您只存储上三角矩阵部分(这就是我在您的问题中理解 full 的方式),并且如果 Cholesky 分解是适合你,chol 处理对称矩阵,如果你的矩阵是正定的。对于不定矩阵,您可以使用ldl。两者都处理稀疏存储并处理对称矩阵部分。

较新的 matlab 版本为此使用 cholmod and suitesparse。这是迄今为止我所知道的表现最好的 Cholesky 分解。在 matlab 中,它也使用并行 BALS 进行并行化。

你从上述函数中得到的因子是上三角矩阵 L 使得

A=LL'

您现在需要做的就是执行前向和后向替换,这既简单又便宜。在 matlab 中,这是在反斜杠运算符中自动完成的

x=L'\(L\b)

矩阵可以是稀疏的,matlab 会识别出它是上三角/下三角。您还可以将此调用与前向替换一起使用通过 cholesky 分解获得的因子。

【讨论】:

  • 我认为他的意思是 A = triu(...)(完整)vs A = sparse(triu(...))(稀疏)
  • @RodyOldenhuis 哦,现在我又读了一遍,我认为你是对的。但无论如何,我的答案包括有关三角求解(向后/向前替换)的信息 - 最后,这就是你在分解矩阵之后所做的事情:)
【解决方案3】:

您可以在稀疏矩阵上使用 MLDIVIDE( \ ) 或 MRDIVIDE( / ) 运算符...

【讨论】:

    猜你喜欢
    • 2013-09-07
    • 1970-01-01
    • 2018-02-13
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    相关资源
    最近更新 更多