Załóżmy, że moja matryca A jest wyjściem funkcji porównawczej I.e. Matryca logiczna ma tylko wartości 0 i 1. Dla małej matrycy o rozmiarze 3 * 4 możemy mieć coś w rodzaju:

A =

     1     1     0     0
     0     0     1     0
     0     0     1     1

Teraz generuję kolejną matrycę B, która jest z tego samego rozmiaru, a jego wiersze są wypełnione indeksami a, a wszelkie pozostałe wartości w każdym wierszu są ustawione na zero.

B =

     1     2     0     0
     3     0     0     0
     3     4     0     0

Obecnie używam funkcji Znajdź w każdym wierszu A, aby uzyskać Matrix B. Kompletny kod można napisać jako:

A=[1,1,0,0;0,0,1,0;0,0,1,1];
[rows,columns]=size(A);
B=zeros(rows,columns);

for i=1:rows
    currRow=find(A(i,:));
    B(i,1:length(currRow))=currRow;
end

W przypadku dużych Martixes, funkcja "Znajdź" zajmuje czas w obliczeniach, zgodnie z profilerem Matlab. Czy jest jakiś sposób, aby generować Matrix B szybciej?

Uwaga: Matrix A ma więcej niż 1000 kolumn w każdym wierszu, ale elementy niezerowe nigdy nie są więcej niż 50. Tutaj przyjmuję matrycę B w tej samej wielkości, ale Matrix B może być znacznie mniejsza wielkościowa kolumna.

3
lonstud 1 styczeń 2020, 18:03

1 odpowiedź

Najlepsza odpowiedź

Sugerowałbym użycie parfor, ale nad głową jest tutaj za dużo, a jest więcej problemów z nim, więc nie jest to dobre rozwiązanie.

rows = 5e5;
cols = 1000;
A = rand(rows, cols) < 0.050;
I = uint16(1:cols);
B = zeros(size(A), 'uint16');
% [r,c] = find(A);
tic
for i=1:rows
%     currRow = find(A(i,:));
    currRow = I(A(i,:));
    B(i,1:length(currRow)) = currRow;
end
toc

@Cris sugeruje wymianę find za pomocą operacji indeksowania. Zwiększa wydajność o około 10%.

Najwyraźniej nie ma lepszej optymalizacji, chyba że wymagana jest B, aby być w tym konkretnym formularzu, który mówisz. Proponuję użycie [r,c] = find(A);, jeśli indeksy nie są wymagane w formie macierzy.

1
Burak 1 styczeń 2020, 17:00