我有一个关于在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;

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

谢谢!

===============>>#1 票数:4 已采纳

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

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

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

代码如下:

R=1./(A.*eye(size(A,1))); %assuming matrix A is square and it does not contain 0 on the main diagonal
R=R(~isinf(R));
R=R(:);
R1=R;
R=repmat(R,[1,size(A,2)]);
R=R.*(true(size(A,1))-eye(size(A,1)));
A=A.*R+A.*eye(size(A,1)); %code verified till here since A comes out to be the same

b = b.*R1;
x=b;

===============>>#2 票数:2

我想有矩阵:

A (NxN)
b (Nx1)

编码:

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

===============>>#3 票数: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);

让我知道!

  ask by dccarmo translate from so

未解决问题?本站智能推荐: