Matlab 用矢量化求解多线性系统
很抱歉,如果这是显而易见的,但我搜索了一段时间,没有找到任何东西(或错过了它) 我试图用4x4矩阵和4x1向量来解Ax=B形式的线性系统 我知道,对于单个系统,我可以使用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保持
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多核显著降低了通信开销。