如何纠正 matlab 中的 "Valid indices for 'variable' are restricted in PARFOR loops" 错误

How to correct "Valid indices for 'variable' are restricted in PARFOR loops" error in matlab

我正在尝试在 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 超过 40,000 行,v 超过 8,000 行?变量 tol 为 0.0959.

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 并行工人中)
所以你可以使用一个临时变量并在 parfor 循环之后收集结果,

注意 1:最好在旧版本中对代码进行矢量化处理,因为循环在 R2017 中不像现在那样好()。

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

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

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(:);

(或类似的东西,我没有 运行 这个代码...如果有错别字或其他错误,请告诉我,或修复 post。)