2

我正在尝试为以下迭代计算找到向导的矢量化(请查看稍后的编辑):

% A is a logical matrix of size NxN
B = false(size(A));
for k1 = 1:N, for k2 = 1:N, for k3 = 1:N
        B(k1,k2) = A(k1,k2) && ~A(k1,k3) && ~A(k3,k2);
end; end; end;

我必须强调,使用arrayfun(or structfunor cellfun) 的解决方案是不可行的,因为它们很慢,我正在寻找性能改进,而不是表现力增强。另外,我想避免明显的:

B = A & logical((1-A)^2)

因为计算它的内存占用是原始内存的 17 倍(我在最终碎片化的内存资源中使用大矩阵)。

肯定的答案(即解决方案)或否定的答案(即解释为什么这不起作用)都非常感谢。

稍后编辑

多亏了H.Muster,我才意识到我的初始代码中有一个错误。要矢量化的迭代实际上是:

% A is a logical matrix of size NxN
B = A;
for k1 = 1:N, for k2 = 1:N, for k3 = 1:N
        B(k1,k2) = B(k1,k2) && ~(A(k1,k3) && A(k3,k2));
end; end; end;

也欢迎更快的迭代(我现在正在研究这个,如果我发现一些东西我会发布为评论/编辑)。

甚至后来编辑

对于那些对代码目的感兴趣的人,它应该计算关系图的传递约简 。表示“与”有关(倒数不正确)。表示“与”有关,并且在它们之间没有其他元素,即.之后的“下一个” 。必须注意,如果这样定义,一个元素可能会受益于几个“下一个”元素,而不仅仅是一个。传递减少有助于将“非确定性迭代器”(下一个是集合,而不是单个元素)创建为由非对称二元关系“诱导”的集合结构。BAA(k1,k2)=truek1k2B(k1,k2)=truek1k2k3k2k1

4

1 回答 1

1

内部循环中的一个小向量化将是:

for k1 = 1:N, for k2 = 1:N
    B(k1,k2) = B(k1,k2) && ~all( A(k1,:) & A(:,k2)' );
end; end;

我不确定是否有一种很好的方法来矢量化外循环。

编辑

实际上很容易对两个内部循环进行矢量化:

for k1 = 1:N
    B(k1,:) = ~all( bsxfun(@and, A(k1,:), A(:,:)' ) );
end;
B = A & B;

我很确定向量化所有内容都必须涉及矩阵乘法或 3-d 矩阵,这将占用更多空间(假设 N 很大)。

于 2013-05-03T21:36:57.977 回答