错误 "Index exceeds matrix dimensions"

parfor error "Index exceeds matrix dimensions"

下面的代码可以工作,但是如果我把 for 改成 parfor,它会报错

Index exceeds matrix dimensions

这是我的代码

a=zeros(3,1);
for t=1:2
  ind=randsample(3,2)
  a=pf(a,ind)
end

function a=pf(a,ind)
 a(ind)=a(ind)+2;
end

我怎样才能让这段代码正常工作而不出错?

n = 2;
a=zeros(3,1);
ind=zeros(3,2,n);
for ii = 1:n
    ind(:,:,ii) = randsample(3,2);
end

for t=1:n
    a=pf(a,ind(:,:,t));
end

function a=pf(a,ind)
    a(ind)=a(ind)+2;
end

上面的代码让 randsample 脱离了循环,这可能就是这里的问题。请注意 randsample 不支持直接创建 3D 矩阵,因此我在循环中对其进行了初始化。

您看到错误是因为您在代码中误用了 parfor。您没有充分阅读相关文档,并且您似乎认为 parfor 是神奇的仙尘,可以使您的计算速度更快,而与计算无关。好吧,我有个坏消息。

让我们仔细看看你的例子:

a = zeros(3,1);
% usual for
disp('before for')
for t=1:2
  ind = randsample(3,2);
  a = pf(a,ind);
  disp(a); % add printing line
end

% parfor
disp('before parfor')
parfor t=1:2
  ind = randsample(3,2);
  a = pf(a,ind);
  disp(a); % add printing line
end

输出:

before for
     2
     2
     0

     2
     4
     2

before parfor
Error: The variable a is perhaps intended as a reduction variable, but is actually an uninitialized temporary.
See Parallel for Loops in MATLAB, "Temporary Variables Intended as Reduction Variables".

如您所见,在后一种情况下,parfor 中没有打印,因此它甚至没有得到 运行。另请参阅有关变量类型的警告。变量 a 被执行引擎错误识别,因为您对它所做的操作没有任何意义。

那么该怎么办呢?您需要以与 parfor 兼容的方式来表述您的问题。唉,这将取决于您对矩阵所做的具体操作。对于您增加随机元素的具体情况,我建议您在循环中单独收集增量,然后将它们相加:

a = zeros(3,1); % only needed for size; assumed that it exists already
numiters = 2;
increments = zeros([size(a), numiters]); % compatible with a proper 2d array too
parfor t=1:numiters
  ind = randsample(3,2);
  % create an auxiliary increment array so that we can use a full slice of 'increments'
  new_contrib = zeros(size(a));
  new_contrib(ind) = 2;
  increments(:,t) = new_contrib;
  disp(increments(:,t)); % add printing line
end

% collect increments along last axis
a = sum(increments,ndims(increments));
disp(a)

输出:

     2
     0
     2

     2
     2
     0


     4
     2
     2

注意缺少警告和有意义的答案。以这种方式重构循环 transparently 向 MATLAB 发出变量正在做什么的信号,并且 increments 正在由 parfor 循环的独立迭代填充。 parfor可以"speed up calculations"的方式,一种非常具体和可控的方式,意味着对循环内使用的物流进行限制。