如何纠正“PARFOR循环中的'变量'的有效索引在matlab中的限制”错误

时间:2018-06-08 16:43:40

标签: matlab parfor

我正在尝试在MatLab R2016a中设置一个parfor嵌套循环,如下所示。

N = size(A,1);
M = size(v,1);
in = zeros(N*M,1);
parfor i=1:N
   for j=1:M
      k = (i-1)*M+j;
      if sqrt(sum((A(i,:)-v(j,:)).^2))<=tol
        in(k) = i;          
      end
   end
end

但是,我收到以下错误'in'的有效索引在PARFOR循环中受到限制。有没有什么方法可以纠正这个问题,因为数组Av相当大,A和{8} v超过40,000行?变量tol为0.0959。

2 个答案:

答案 0 :(得分:1)

N = size(A,1);
M = size(v,1);
in = cell(N,1);
parfor i=1:N
    s=v;
    p=zeros(1:M,1);
   for j=1:M
      k = (i-1)*M+j;
      if sqrt(sum((A(i,:)-s(j,:)).^2))<=tol
        p(k) = i;          
      end
   end
   in{i}=single(p);
end
in=cell2mat(in);
in=reshape(in,[N*M,1]);

有时matlab不会将parfor循环中的变量识别为“切片变量” ,切片变量是一个变量,它具有parfor循环之外的参考,并且每个元素只能由一个工人访问(在parfor parallel workers中) 所以你可以使用临时变量并在parfor循环后收集结果,

注1:最好在旧版本中对代码进行矢量化,因为循环并没有像R2017中提到的那样好(this)。

注2:如果“in”的大多数元素为零,请尝试使用“稀疏矩阵”,这样可以节省大量内存;

答案 1 :(得分:1)

问题是MATLAB无法识别变量k正在切割矩阵in。解决方案应该是分别使用ini索引j

N = size(A,1);
M = size(v,1);
in = zeros(M,N);
parfor i=1:N
   for j=1:M
      if sqrt(sum((A(i,:)-v(j,:)).^2))<=tol
        in(j,i) = i;          
      end
   end
end
in = in(:); % reshape to a column vector, as the output in the question's code

另一种选择,但它需要更多的中间内存,就是在没有循环的情况下计算它:

A = reshape(A,1,N,[]);
v = reshape(v,M,1,[]);
in = sum(bsxfun(@minus,A,v).^2,3) < tol*tol;
in = in(:);

(或类似的东西,我没有运行此代码......如果有错字或其他错误,请告诉我,或修改帖子。)