2016-08-11 3 views
1

Я хотел бы использовать parfor для вложенного цикла, я привел пример, показывающий свою структуру:классификация-ошибка решена путем изменения индекса, почему?

temp_vars = 1:10; 
global_arr = zeros(10,10); 

parfor i=0:9 
    for j=0:9 
     constant_var = temp_vars(i+1); 
     global_arr(i+1, j+1) = i*j*constant_var; 
    end 
end 

MATLAB дает мне ошибку: Error: The variable global_arr in a parfor cannot be classified..

Однако, если изменить значение i и j к 1..10 вместо 0..9, то магическим образом работает хорошо. Почему это?

ответ

1

Проблема заключается в том, что вы ссылаетесь на global_arr с использованием относительных индексов вместо абсолютных единиц (т. Е. i+1 вместо i). Когда вы используете параллельный for, каждый «срез» global_arr вычисляется независимо от его положения в цикле, а относительные индексы подразумевают зависимое положение, которое запрещено.

Попробуйте вместо этого:

parfor i = 1:10; 
    for j = 1:10; 
     constant_var = temp_vars(i); 
     global_arr(i, j) = (i-1)*(j-1)*constant_var; 
    end 
end 

Точнее, только первый индекс в пределах цикла parfor может зависеть от итератора петли, все остальные рассматриваются как константы. Таким образом, вы можете использовать i в относительном пути, но не j:

parfor i = 0:9; 
    for j = 1:10; 
     constant_var = temp_vars(i+1); 
     global_arr(i+1,j) = i*(j-1)*constant_var; 
    end 
end 

From MATLAB doc:

When you use other variables along with the loop variable to index an array, you cannot set these variables inside the loop. In effect, such variables are constant over the execution of the entire parfor statement. You cannot combine the loop variable with itself to form an index expression.

+0

Say моя переменная 'temp_vars' гораздо больше, и мне нужно использовать более сложные indicices, которые не могут быть решены просто переходя от «0..9' к« 1..10 », например 'constant_var = temp_vars (10 + 100 * j + 200 * i);'. Означает ли это, что я не могу использовать 'parfor'? – BillyJean

+1

Вы можете использовать его, но создайте список индексов, которые должны быть заданы 'temp_vars' как функция' i' и 'j' перед циклом, а затем сделайте абсолютную ссылку на них. Что-то вроде 'temp_vars_ind (i, j) = 10 + 100 * j + 200 * i' вне цикла, а затем' temp_vars (temp_vars_ind (i, j)) 'в цикле. – EBH

+0

Будет ли это решение ОК или альтернативно сделать автономную функцию 'ind = @ (i, j) 10 + 100 * j + 200 * i', а затем вызвать' temp_vars (ind (i, j)) '? – BillyJean