In fondo a questa risposta c'è un codice di benchmarking, poiché hai chiarito che sei interessato alle prestazioni piuttosto che evitare arbitrariamente i forloop.
In effetti, penso che i forloop siano probabilmente l'opzione più performante qui. Da quando è stato introdotto il "nuovo" motore (2015b) JIT, i loop (di origine ) fornon sono intrinsecamente lenti - in realtà sono ottimizzati internamente.
Dal benchmark puoi vedere che l' mat2cellopzione offerta da ThomasIsCoding qui è molto lenta ...

Se ci liberiamo di quella linea per rendere più chiara la scala, allora il mio splitapplymetodo è abbastanza lento, l' opzione accumarray di obchardon è un po 'migliore, ma le opzioni più veloci (e comparabili) stanno usando arrayfun(come suggerito anche da Thomas) o un forloop. Si noti che arrayfunè praticamente un forcircuito nascosto sotto mentite spoglie per la maggior parte dei casi d'uso, quindi non è un legame sorprendente!

Consiglierei di utilizzare un forloop per una maggiore leggibilità del codice e le migliori prestazioni.
Modifica :
Se assumiamo che il looping sia l'approccio più veloce, possiamo fare alcune ottimizzazioni attorno al findcomando.
In particolare
Rendi Mlogico. Come mostra la trama sotto, questo può essere più veloce per relativamente piccoli M, ma più lento con il compromesso della conversione del tipo per grandi M.
Utilizzare un logico Mper indicizzare un array 1:size(M,2)invece di utilizzare find. Ciò evita la parte più lenta del ciclo (il findcomando) e supera il sovraccarico di conversione del tipo, rendendolo l'opzione più rapida.
Ecco la mia raccomandazione per le migliori prestazioni:
function A = f_forlooplogicalindexing( M )
M = logical(M);
k = 1:size(M,2);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = k(M(r,:));
end
end
Ho aggiunto questo al benchmark di seguito, ecco il confronto degli approcci in stile loop:
Codice di benchmarking:
rng(904); % Gives OP example for randi([0,1],3)
p = 2:12;
T = NaN( numel(p), 7 );
for ii = p
N = 2^ii;
M = randi([0,1],N);
fprintf( 'N = 2^%.0f = %.0f\n', log2(N), N );
f1 = @()f_arrayfun( M );
f2 = @()f_mat2cell( M );
f3 = @()f_accumarray( M );
f4 = @()f_splitapply( M );
f5 = @()f_forloop( M );
f6 = @()f_forlooplogical( M );
f7 = @()f_forlooplogicalindexing( M );
T(ii, 1) = timeit( f1 );
T(ii, 2) = timeit( f2 );
T(ii, 3) = timeit( f3 );
T(ii, 4) = timeit( f4 );
T(ii, 5) = timeit( f5 );
T(ii, 6) = timeit( f6 );
T(ii, 7) = timeit( f7 );
end
plot( (2.^p).', T(2:end,:) );
legend( {'arrayfun','mat2cell','accumarray','splitapply','for loop',...
'for loop logical', 'for loop logical + indexing'} );
grid on;
xlabel( 'N, where M = random N*N matrix of 1 or 0' );
ylabel( 'Execution time (s)' );
disp( 'Done' );
function A = f_arrayfun( M )
A = arrayfun(@(r) find(M(r,:)),1:size(M,1),'UniformOutput',false);
end
function A = f_mat2cell( M )
[i,j] = find(M.');
A = mat2cell(i,arrayfun(@(r) sum(j==r),min(j):max(j)));
end
function A = f_accumarray( M )
[val,ind] = ind2sub(size(M),find(M.'));
A = accumarray(ind,val,[],@(x) {x});
end
function A = f_splitapply( M )
[r,c] = find(M);
A = splitapply( @(x) {x}, c, r );
end
function A = f_forloop( M )
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = find(M(r,:));
end
end
function A = f_forlooplogical( M )
M = logical(M);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = find(M(r,:));
end
end
function A = f_forlooplogicalindexing( M )
M = logical(M);
k = 1:size(M,2);
N = size(M,1);
A = cell(N,1);
for r = 1:N
A{r} = k(M(r,:));
end
end
forloop? Per questo problema, con le versioni moderne di MATLAB, sospetto fortemente che unforloop sia la soluzione più veloce. Se hai un problema di prestazioni, sospetto che tu stia cercando la soluzione sbagliata in base a consigli obsoleti.