我正在尝试在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循环中受到限制。有没有什么方法可以纠正这个问题,因为数组A
和v
相当大,A
和{8} v
超过40,000行?变量tol
为0.0959。
答案 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
。解决方案应该是分别使用in
和i
索引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(:);
(或类似的东西,我没有运行此代码......如果有错字或其他错误,请告诉我,或修改帖子。)