Performance 矢量化转移矩阵约化
我正在尝试为以下迭代计算找到向导的矢量化(请查看后面的编辑): 我必须强调,使用Performance 矢量化转移矩阵约化,performance,matlab,vectorization,Performance,Matlab,Vectorization,我正在尝试为以下迭代计算找到向导的矢量化(请查看后面的编辑): 我必须强调,使用arrayfun(或structfun或cellfun)的解决方案是不可行的,因为它们速度很慢,我希望的是性能改进,而不是表现力增强。此外,我想避免明显的问题: B = A & logical((1-A)^2) 因为计算的内存占用是原来的17倍(我在一个最终碎片化的内存资源中使用大矩阵) 积极的回答(即解决方案)或消极的回答(即解释为什么这不起作用)都是非常值得赞赏的 以后编辑 多亏了我意识到我的初始代
arrayfun
(或structfun
或cellfun
)的解决方案是不可行的,因为它们速度很慢,我希望的是性能改进,而不是表现力增强。此外,我想避免明显的问题:
B = A & logical((1-A)^2)
因为计算的内存占用是原来的17倍(我在一个最终碎片化的内存资源中使用大矩阵)
积极的回答(即解决方案)或消极的回答(即解释为什么这不起作用)都是非常值得赞赏的
以后编辑
多亏了我意识到我的初始代码中有一个bug。要矢量化的迭代实际上是:
% 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;
一个更快的迭代也是受欢迎的(我现在正在研究这个问题,如果我发现一些东西,我将以评论/编辑的形式发布)
以后再编辑
对于那些对代码用途感兴趣的人来说,应该计算关系图
a
的B
A(k1,k2)=true
表示k1
“与”k2
(倒数不是true)B(k1,k2)=true
表示k1
“与”k2
相关,并且它们之间没有其他元素k3
,即k2
是k1
之后的“下一个”。必须注意的是,如果这样定义,一个元素可能受益于几个“下一个”元素,而不仅仅是一个。传递性归约有助于将“非确定性迭代器”(下一个是集合,而不是单个元素)创建为集合结构,该集合结构由非对称结构“诱导”而成。内部循环中的小矢量化将是:
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;
我非常确定,矢量化所有内容都必须涉及矩阵乘法或三维矩阵,这将占用更多的空间(假设N很大)。内部循环是否会覆盖
B(k1,k2)
中的值,只会导致k3==N
的值存储在B
中?我猜ismember
会很有用....@H.Muster噢,多亏了你的评论,我刚刚在代码中发现了一个bug。我试图优化一个错误的答案…:D我将更新代码以反映我实际需要的内容。@natanismember
当所有值都是true
或false
时,很难使用。你怎么知道哪个是哪个?也许我不完全理解你的建议。请您详细说明一下您的想法好吗?您的三环解决方案可能会受益于早期退出优化(一旦B(i,j)变为false,跳到下一个元素)这看起来不错。我将测试它的速度。我相信这会比我现在拥有的更好…如果内部表达式使用eager and运算符“&”(用于数组),而不是lazy and运算符“&&”(仅适用于标量),这可能会起作用。我可以编辑答案,你也可以根据需要编辑。无论如何,这是一个新的想法,我正在测试它。感谢您花时间修补此问题。:-)另外,您可能希望使用BSXFUN而不是REPMAT@Amro你说得对,谢谢!。我以前不知道它。@Amro:是的,内置函数的工作速度几乎总是比.m函数快。一旦我了解了thrutheality的解决方案,我会尝试这个。
for k1 = 1:N
B(k1,:) = ~all( bsxfun(@and, A(k1,:), A(:,:)' ) );
end;
B = A & B;