2

我想从我的代码中删除嵌套的 for 循环?我无法删除它们。

k = 3;    
Data = rand(100,5);    
m = zeros(size(Data));    
N = size(Data,2); % number of features
M = size(Data,1); % number of objects
bound = zeros(N,k+1);

MAX = max(Data);
MIN = min(Data);


for ii = 1:N
    bound(ii,:) = linspace(MIN(ii), MAX(ii), k+1);
end

bound(:,end) = bound(:,end)+eps;

tic;
for ii = 1:M
    for jj=1:N
        for kk=1:k
            if bound(jj,kk)<=Data(ii,jj) && Data(ii,jj)<bound(jj,kk+1)
                m(ii,jj) = kk;
            end
        end
    end
end
4

3 回答 3

0

另一种选择是histc(),它是专门为装箱而设计的:

for jj = 1:N
   [~, m(:,jj)] =  histc(Data(:,jj),bound(jj,:));
end

该解决方案与此解决方案相当,bsxfun()但它不是一个非常有意义的比较,因为这里的循环是跨列的,而 bsxfun 是跨界的。因此,根据经验,histc()如果我的列数少于边界,我会选择,否则bsxfun().

于 2013-04-20T17:38:38.857 回答
0

您可以取消嵌套达到一定的限制。

乍一看,由于jj索引在嵌套循环内的操作中似乎是统一的,您可以替换

for ii = 1:M
    for jj=1:N
        for kk=1:k
            if bound(jj,kk)<=Data(ii,jj) && Data(ii,jj)<bound(jj,kk+1)
                m(ii,jj) = kk;
            end
        end
    end
end

通过简单

for ii = 1:M
    for kk=1:k
        m(ii,(bound(:,kk)<=Data(ii,:)' & Data(ii,:)'<bound(:,kk+1))) = kk;
    end
end

这将为您提供与以前完全相同的结果。

于 2013-04-20T08:20:21.307 回答
0

由于您最长的循环结束了ii=1:M,我们应该优先考虑将这个向量化为其他循环。最小的循环已经结束,kk=1:k所以这个循环可能会留下来而不用担心太多。您可以bsxfun在这种矢量化中使用到很好的效果:

for kk = 1:k
    ind = bsxfun(@le, bound(:, kk)', Data) & bsxfun(@gt, bound(:, kk+1)', Data);
    m(ind) = kk;
end

这给出了与上述代码相同的结果。

于 2013-04-20T13:27:51.153 回答