cumsum
ベクトル化されたアプローチの 1 つは、との組み合わせを使用する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;
ベクトル化されたソリューションの利点を実際に確認するには、元のルーピー コードで多くの反復が行われている場合に使用する必要があることに注意してください。そうしないと、ベクトル化されたアプローチをセットアップするための準備作業に関連するオーバーヘッドが無駄になります。したがって、実際のケースには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)