Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 用矢量化求解多线性系统_Matlab_Linear Algebra - Fatal编程技术网

Matlab 用矢量化求解多线性系统

Matlab 用矢量化求解多线性系统,matlab,linear-algebra,Matlab,Linear Algebra,很抱歉,如果这是显而易见的,但我搜索了一段时间,没有找到任何东西(或错过了它) 我试图用4x4矩阵和4x1向量来解Ax=B形式的线性系统 我知道,对于单个系统,我可以使用mldivide获得x:x=a\B 然而,我正在尝试解决大量的系统(可能>10000),我不愿意使用for循环,因为我被告知在许多MATLAB问题中它明显比矩阵公式慢 我的问题是:有没有一种方法可以用4xn和4xn矩阵的矢量化来解Ax=B PS:我不知道这是否重要,但B向量对于所有系统都是相同的。您应该使用for循环。如果a保持

很抱歉,如果这是显而易见的,但我搜索了一段时间,没有找到任何东西(或错过了它)

我试图用4x4矩阵和4x1向量来解Ax=B形式的线性系统

我知道,对于单个系统,我可以使用
mldivide
获得x:
x=a\B

然而,我正在尝试解决大量的系统(可能>10000),我不愿意使用for循环,因为我被告知在许多MATLAB问题中它明显比矩阵公式慢

我的问题是:有没有一种方法可以用4xn和4xn矩阵的矢量化来解Ax=B


PS:我不知道这是否重要,但B向量对于所有系统都是相同的。

您应该使用for循环。如果
a
保持不变而
B
发生变化,那么预计算因式分解并重用它可能会有好处。但是对于
A
变化而
B
保持不变的问题,除了求解N个线性系统之外,别无选择

您也不必太担心循环的性能成本:这意味着循环在最新版本的MATLAB上通常可以同样快。

问题在于: 您正在尝试对3d矩阵执行2D操作()。不管你怎么看,你都需要通过索引引用矩阵,这就是时间惩罚的作用所在。。。问题不在于for循环,而在于人们如何使用它们。 如果你能以不同的方式组织你的问题,那么也许你能找到更好的选择,但现在你有几个选择:

1-mex

2-并行处理(编写parfor循环)


3-CUDA

我认为您无法进一步优化此功能。正如@Tom所解释的,由于
A
是一个不断变化的变量,因此事先将各种
A
分解没有任何好处

此外,考虑到您提到的维度,循环解决方案相当快:

A = rand(4,4,10000);
B = rand(4,1);          %# same for all linear systems

tic
X = zeros(4,size(A,3));
for i=1:size(A,3)
    X(:,i) = A(:,:,i)\B;
end
toc
运行时间为0.168101秒


我知道这篇文章已经有好几年了,但我还是会贡献我的两分钱。您可以将所有A矩阵放入一个较大的块对角矩阵中,其中在一个较大矩阵的对角线上有4x4个块。右手边将是所有的b向量一次又一次地叠加在一起。一旦你建立了这个系统,它将被表示为一个稀疏的系统,并且可以通过算法有效地解决。这些块在数值上是解耦的,因此即使其中存在奇异块,当使用mldivide时,非奇异块的答案应该是正确的。有一段代码在MATLAB Central上采用了这种方法:


我建议尝试一下,看看这种方法是否比循环更快。我怀疑它可以更有效,特别是对于大量的小型系统。特别是,如果N个矩阵中有很好的A系数公式,可以使用MATLAB向量运算(无循环)构建完整的左侧,这可以为您节省额外的成本。正如其他人所指出的,矢量化操作并不总是更快,但根据我的经验,它们通常更快。

这里有一个相当深奥的解决方案,它利用了MATLAB特有的优化功能。用对角线上的4x4块构造一个巨大的4k x 4k稀疏矩阵。然后同时解决所有问题

在我的机器上,这得到了与@Amro/Tom的for-loop解决方案相同的单精度解决方案,但速度更快

n = size(A,1);
k = size(A,3);
AS = reshape(permute(A,[1 3 2]),n*k,n);
S = sparse( ...
  repmat(1:n*k,n,1)', ...
  bsxfun(@plus,reshape(repmat(1:n:n*k,n,1),[],1),0:n-1), ...
  AS, ...
  n*k,n*k);
X = reshape(S\repmat(B,k,1),n,k);
对于随机示例:

For k = 10000
For loop: 0.122570 seconds.
Giant sparse system: 0.032287 seconds.
如果您知道您的4x4矩阵是正定的,那么您可以在S上使用
chol
,以提高精度


这太傻了。但2015年,即使采用JIT,matlab for循环的速度仍然很慢。当k不太大时,此解决方案似乎找到了一个最佳点,因此所有内容仍适合内存。

0.091238秒。。。比我预期的要快得多:)。关于A的小维度,这是一个很好的观点,因为它显著降低了问题的复杂性。在MATLAB中,通过使用矩阵来提高性能的整个概念被调用,而不像您从答案中看到的“如果它是矩阵形式->它总是更快”那么简单。@Jacob:是的,我是指矢量化,谢谢您的编辑。我知道有时你无法避免循环,但只是从我学习Matlab的方式,以及给定所有面向向量化的本地函数的方式来看,我想知道这个网站的经验丰富的人是否已经遇到过这个问题。感谢@Tom和@Amro的回答,感谢@Rasman和@eat的替代方案。@Jacob:不,
parfor
在这里实际上会慢一些。根据Amro的计时(以及评论中Rasman的计时),每个任务所用的平均时间约为10-6秒。调度器与工作人员通信所花费的时间比这要慢,或者可能是相同数量级的时间。考虑到这一点,速度会慢一些。在我的机器上,总共需要约0.1秒(不含
parfor
和约0.5秒(含
parfor
和8名工人)。@yoda如果除法是唯一的操作,那么你是对的,否则,可能是,也可能不是useful@yoda还有@Jacob:差别很小,但是如果去掉打开池的时间,我的parfor在系统中的运行速度会比for循环快一点(当您增加迭代次数时,差异会更明显,例如100000)@yoda:parfor开销严重依赖于处理器。较新的Intel多核显著降低了通信开销。