Эффективное индексирование массива другим массивом без использования цикла - PullRequest
0 голосов
/ 15 октября 2018

Мне нужно что-то вроде B(i,j) = f( A(i,j), i), где A(i,j) - это массив целых чисел, f(a,i) - это массив, который определяет, как должен быть преобразован элемент a в строке i массива A.

Какой эффективный способ сделать это в Matlab?Я знаю, что могу сделать это с помощью цикла i, но я хочу сделать код эффективным, поскольку этот шаг может повторяться несколько миллионов раз.

Редактировать - вот версия цикла:

B = zeros(iMax,jMax);
for i = 1:iMax
    B(i,:) = f(A(i,:),i)';
end

1 Ответ

0 голосов
/ 15 октября 2018

В этом случае вы можете использовать sub2ind.

Из документа:

sub2ind (matrixSize, rowSub, colSub) возвращает эквиваленты линейного индекса в строке и столбцеиндексы rowSub и colSub для матрицы размера matrixSize.

Давайте рассмотрим пример:

n = 3300;
m = 5000;
A = randi(m,n,4); %randi(x1,y1,z1)
f = randi(10,m,n);%randi(x2,y2,z2) where  y2 >= x1 and z2 >= y1;

%For loop version
tic
B = zeros(size(A));
for ii = 1:size(A,1)
    B1(ii,:) = f(A(ii,:),ii);
end
toc

%Linear indexing version
tic
[s1,s2] = size(A);
sub     = [1:s1].'+zeros(1,s2);  %you can also use sub = repmat(1:s1,s2,1).'
s2i     = sub2ind(size(f),A,sub); %create the index according to the subscripts
B2      = f(s2i);
toc

result:

%for loop
%Elapsed time is 0.102647 seconds.
%sub2ind
%Elapsed time is 0.00155091 seconds.

Для создания subЯ использую функцию неявного расширения, которая требует matlab 2016b или более поздней версии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...