Один Векторизованных подход может быть комбинацией cumsum
и bsxfun
, которые могли бы быть немного памяти интенсивно, хотя -
blocksize = 250;
valid_idx = bsxfun(@le,[1:max(P)],P');
idx_mat = bsxfun(@plus,cumsum(valid_idx,2),[0:numel(P)-1]'*blocksize);
A(:,idx_mat(valid_idx)) = 1; %// You can replace this with "A(:,unique(idx_mat))=1;"
Еще несколько иной подход -
blocksize = 250;
maxP = max(P);
valid_idx = bsxfun(@le,[1:maxP],P');
idx_mat = bsxfun(@plus,[0:numel(P)-1]'*blocksize,1:maxP);
A(:,idx_mat(valid_idx))=1;
Пожалуйста, обратите внимание, чтобы действительно увидеть преимущества векторизованных решений, вам нужно использовать их, когда ваш исходный код цикла имеет много итераций goin г. В противном случае накладные расходы, связанные с подготовительной работой по настройке векторизованных подходов, будут отходами. Таким образом, я предполагаю, что ваш фактический случай включает в себя не более 4 подматриц.
Другой cumsum
подход, основанный, и это один должно быть интересно попробовать и даже может оказаться лучшим из партии -
blocksize = 250;
%//Get monotonically increasing labels within each group, defined by limits from idx
array1 = zeros(1,sum(P));
grp_starts = cumsum(P(1:end-1))+1;
array1(grp_starts) = P(1:end-1);
grp_labels = [1:numel(array1)] - cumsum(array1);
%// Get offsetted indices
array2 = zeros(1,sum(P));
array2(grp_starts) = blocksize;
offsetted_grp_labels = grp_labels + cumsum(array2);
A(:,offsetted_grp_labels)=1; %// perform the operation(s)
Любые замечания по подходам, упомянутым в единственном решении, представленном здесь ? – Divakar