矢量化矩阵乘法

时间:2013-04-15 23:59:06

标签: matlab matrix octave vectorization

我有一个关于在Octave上运行SOR算法的学校项目,但我的效率非常低。所以我有这段代码:

for ii=1:n
    r = 1/A(ii,ii);
    for jj=1:n
        if (ii!=jj)
            A(ii,jj) = A(ii,jj)*r;
        end;
    end;
    b(ii,1) = b(ii,1)*r;
    x(ii,1) = b(ii,1);
end;

我该如何对此进行矢量化?我的第一次尝试是这样的:

for ii=1:n
    r = 1/A(ii,ii);
    A(find(eye(length(A))!=1)) = A(find(eye(length(A))!=1))*r;
    b(ii,1) = b(ii,1)*r;
    x(ii,1) = b(ii,1);
end;

但我不确定它有多大帮助。是否有更好和/或更有效的方法来做到这一点?

谢谢!

3 个答案:

答案 0 :(得分:4)

你完全可以避免我认为的循环。你必须看到你作为A的对角元素的倒数,那你为什么要使用循环。直接做。这是第一步。移除Inf,现在您想将r乘以相应行的相应非对角元素,对吗?

因此,使用repmat构造这样一个矩阵,它将沿着列复制元素,因为你将r乘以(1,2),(1,3),... ,(1,n)。但是R具有非零对角线元素。因此,将它们归零。现在你将得到你的A,除了对角元素将为零。因此,您只需将其从原始A添加回来。这可以通过A=A.*R+A.*eye(size(A,1))来完成。

矢量化来自经验,最重要的是分析您的代码。想想在每一步是否要使用循环,如果没有用等效命令替换该步骤,其他代码将遵循(例如,我构造了一个矩阵R,而你构建了单独的元素{{1}所以我只考虑转换r - > r,然后其余的代码就会到位。

代码如下:

R

答案 1 :(得分:2)

我想有矩阵:

A (NxN)
b (Nx1)

代码:

d = diag(A);
A = diag(1 ./ d) * A + diag(d - 1);
b = b ./ d;
x = b;

答案 2 :(得分:2)

随着问题被标记为vectorization问题,随机地碰到了这个问题并且乍一看看起来很有趣。

我能够提出一个基于bsxfun的矢量化解决方案,该解决方案也使用diagonal indexing。这个解决方案似乎给我一个3-4x加速循环代码加上适当大小的输入。

假设你仍然有兴趣看到这个问题的加速改进,我会急切地想知道你会得到的那种加速。这是代码 -

diag_ind = 1:size(A,1)+1:numel(A);
diag_A = A(diag_ind(:));
A = bsxfun(@rdivide,A,diag_A);
A(diag_ind) = diag_A;
b(:,1) = b(:,1)./diag_A;
x(:,1) = b(:,1);

让我知道!