在matlab中,在没有for循环的情况下检查数组中的成员身份



我想将此代码简化为不使用for循环。

for i=1:N
for j=1:N
if ismember(j,A)
PID(i,i)=TFP(i,j)+ PID(i,i);
end
end
end

其中CCD_ 1是包含一些标签的矩阵。我之前以N*N稀疏二重的形式存储了CCD_ 2。因此,我提出了以下解决方案,但我找不到在其中实现成员条件(由?指定(的方法。

PID = sum(TFP).*(?);

它可以在没有循环的情况下实现吗?

您的ismember(j,A)相当于只使用A的值进行索引。因此,您可以使用它并完全避免使用ismember函数(这是迄今为止代码中最慢的部分(。

因此,优化的第一步是

A2=unique(A); % just in case you do not do this already
for i=1:N
for j=A2
PID(i,i)=TFP(i,j)+ PID(i,i);
end
end

这应该已经很快了。循环在MATLAB中并不坏,JIT编译器对其进行了大量优化。

优化的下一步是将所有索引放在一起,并删除第二个循环。你可以用线性索引来做到这一点,所以

A2=unique(A); % just in case you do not do this already
for i=1:N
PID(i,i)=sum(TFP(i,A2));
end

最后,你可以通过对角化所需列的总和来消除这个问题:

A2=unique(A); % just in case you do not do this already
PID=diag(sum(TFP(:,A2),2));

您可以使用矩阵乘法,而不是对元素乘法的结果求和。它在不创建临时数组的情况下计算乘积的总和:

J = ismember(1:N, A).';
PID = diag(TFP * J);

我不确定我是否完全理解你的问题你试过这个吗?

j=1:N;
PID = sum(TFP).*ismember(j,A);

ismember将作为一个矩阵工作,当为true时,它等于"1",因此它将允许相乘。

最新更新