Нарезанные переменные

Нарезанная переменная является той, значение которой может быть разбито в сегменты или срезы, на которых затем используют отдельно различные рабочие. Каждая итерация цикла работает над различным срезом массива. Используя нарезанные переменные может уменьшать связь между клиентом и рабочими. Только те срезы, необходимые рабочему, отправляются в него, когда это начинает работать над конкретной областью значений индексов.

В этом примере срез A состоит из одного элемента того массива.

parfor i = 1:length(A)
   B(i) = f(A(i));
end

Характеристики нарезанной переменной

Если переменная в parfor - цикл имеет все следующие характеристики, то переменная нарезана:

  • Тип Индексации Первого уровня — первый уровень индексации является или круглыми скобками, (), или фигурными скобками, {}.

  • Фиксированный Список Индексов — В круглых скобках первого уровня или фигурных скобках, список индексов является тем же самым для всех случаев данной переменной.

  • Форма Индексации — В рамках списка индексов для переменной, точно один индекс включает переменную цикла.

  • Форма Массива — массив поддерживает постоянную форму. В присвоении нарезанной переменной правой стороной присвоения не может быть [] или '', потому что эти операторы пытаются удалить элементы.

Тип Индексации Первого уровня. Для нарезанной переменной первый уровень индексации заключен или в круглые скобки, (), или в фигурные скобки, {}.

Вот формы для первого уровня индексации для массивов, которые нарезаны и не нарезаны.

Ссылка для переменной, не нарезаннойСсылка для нарезанной переменной
A.xA(...)
A.(...)A{...}

После первого уровня можно использовать любой тип допустимой индексации MATLAB® на вторых и последующих уровнях.

Переменная A, показанная здесь слева, не нарезана; показанный справа нарезан:

A.q{i,12}                         A{i,12}.q

Фиксированный Список Индексов. В рамках индексации первого уровня нарезанной переменной список индексов является тем же самым для всех случаев данной переменной.

Переменная A слева не нарезана, потому что A индексируется i и i+1 в различных местах. В коде справа, переменная A нарезана правильно.

Не нарезанныйНарезанный
parfor i = 1:k
   B(:) = h(A(i), A(i+1));
end
parfor i = 1:k
   B(:) = f(A(i));
   C(:) = g(A{i});
end

Пример справа показывает случаи индексации первого уровня с помощью и круглых скобок и фигурных скобок в том же цикле, который приемлем.

Следующий пример слева не нарезает A, потому что индексация A не является тем же самым во всех местах. Пример на правильных срезах и A и B. Индексация A не является тем же самым как индексацией B. Однако индексация и A и B индивидуально сопоставима.

Не нарезанныйНарезанный
parfor i=1:10
  b = A(1,i) + A(2,i)
end
A = [ 1  2  3  4  5  6  7  8  9  10; 
     10 20 30 40 50 60 70 80 90 100];
B = zeros(1,10);
parfor i=1:10
    for n=1:2
       B(i) = B(i)+A(n,i)
    end
end

Форма Индексации. В рамках первого уровня из индексации для нарезанной переменной точно одно выражение индексации имеет форму i, i+k, i-k или k+i. Индекс i является переменной цикла и k, является скалярной целочисленной константой или простой (неиндексируемой) широковещательной переменной. Любое выражение индексации является положительной целочисленной константой, простой (неиндексируемой) широковещательной переменной, вложенным for - индексная переменная цикла, двоеточие или end.

С i как переменная цикла слева не нарезаны переменные A, показанные, в то время как переменные A справа нарезаны.

Не нарезанныйНарезанный
A(i+f(k),j,:,3) % f(k) invalid for slicing
A(i,20:30,end)  % 20:30 not scalar
A(i,:,s.field1) % s.field1 not simple broadcast var
A(i+k,j,:,3)
A(i,:,end)
A(i,:,k)

Когда вы используете другие переменные наряду с переменной цикла, чтобы индексировать массив, вы не можете установить эти переменные в цикле. В действительности такие переменные являются постоянными по выполнению целого оператора parfor. Вы не можете объединить переменную цикла с собой, чтобы сформировать индексное выражение.

Форма Массива. Нарезанная переменная должна поддержать постоянную форму. Переменная A, показанная здесь на любой строке, не нарезана:

A(i,:) = [];
A(end + 1) = i;

В первом случае A не нарезан, потому что изменение формы нарезанного массива нарушило бы предположения, управляющие связью между клиентом и рабочими.

Во втором A не является нарезанный вывод, потому что он не индексируется на переменной цикла.

Нарезанные переменные ввода и вывода

Все нарезанные переменные имеют характеристики того, чтобы быть вводом или выводом. Нарезанная переменная может иногда иметь обе характеристики. MATLAB передает нарезанные входные переменные от клиента рабочим и нарезанные выходные переменные от рабочих назад клиенту. Если переменная является оба вводом и выводом, она передается в обоих направлениях.

В этом parfor - цикл, r является нарезанной входной переменной, и b является нарезанной выходной переменной.

a = 0;
z = 0;
r = rand(1,10);
parfor ii = 1:10
   a = ii;
   z = z + ii;
   b(ii) = r(ii);
end

Однако, если в каждой итерации, каждая ссылка на элемент массива установлена, прежде чем это будет использоваться, переменная не является нарезанной входной переменной. В этом примере установлены все элементы A, и затем только те фиксированные значения используются.

parfor ii = 1:n
   if someCondition
      A(ii) = 32;
   else
      A(ii) = 17;
   end
   loop code that uses A(ii)
end

Нарезанные выходные переменные могут вырасти динамически через индексируемые присвоения со значениями по умолчанию, вставленными в промежуточных индексных положениях. В этом нарезанном переменном примере вы видите, что значение по умолчанию 0 было вставлено в нескольких местах в a.

a = [];
parfor idx = 1:10
    if rand < 0.5
        a(idx) = idx;
    end
end

disp(a);
     0     2     0     4     5     0     0     8     9    10

Даже если на нарезанную переменную явным образом не ссылаются как вход, неявное использование может сделать ее так. В следующем примере не все элементы A обязательно установлены в parfor - цикл. Поэтому исходные значения массива получены, сохранены, и затем возвращены от цикла, делая A обоими нарезанной переменной ввода и вывода.

A = 1:10;
parfor ii = 1:10
    if rand < 0.5
        A(ii) = 0;
    end
end

Скалярное расширение с нарезанными Выходными параметрами

Вы не можете использовать скалярное расширение, чтобы задать множество значений, присвоенное нарезанному выходному массиву. Например, следующий код пытается расширить значение idx для присвоения на каждый элемент вектора, заданного x(:,idx); это действие генерирует ошибку.

x = zeros(10,12);
parfor idx = 1:12
  x(:,idx) = idx;
end

Следующий код предлагает предложенное обходное решение для этого ограничения.

x = zeros(10,12);
parfor idx = 1:12
   x(:,idx) = repmat(idx,10,1);
end

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте