Использование вектора вместо цикла - PullRequest
0 голосов
/ 19 мая 2018

У меня огромная матрица.Мне только что дали пример матрицы с размером (1*1000000).

Я использую простой Loop (я не предпочитаю использовать Loop), чтобы найти k.где

k= k(ii)=(abs(a(ii+1)-2*a(ii)+a(ii-1)))/(a(ii+1)+2*a(ii)+a(ii-1))

Однако это хорошо для небольших матриц.Если у меня есть огромные данные, это займет много времени.Есть ли способ использовать вектор вместо Loop, чтобы найти k?

clear;
clc;
a=rand(1,1000000);

for ii=2:size(a,2)-1
    k(ii)=(abs(a(ii+1)-2*a(ii)+a(ii-1)))/(a(ii+1)+2*a(ii)+a(ii-1));
end

1 Ответ

0 голосов
/ 19 мая 2018

Если вы хотите векторизовать его, вам нужно знать, какие индексы a вы будете использовать на каждой итерации.Например, термин a(ii+1) с ii итерацией от 2 до 999999 означает, что вы используете элементы a от индексов 3 до последнего и аналогичным образом выясняете это для других терминов.Затем просто выполните поэлементное деление ./.0 добавляется вручную в начале, так как в вашем коде вы ничего не хранили явно при первом индексе, и ноль - это то, что автоматически сохраняется при пропуске индекса.

k = [0 abs(a(3:end)-2*a(2:end-1)+a(1:end-2)) ./ (a(3:end)+2*a(2:end-1)+a(1:end-2))];

Производительностьприуроченный к timeit в моей системе с R2017a и a=rand(1,1e8);:

Orig_Post = 14.3219
Orig_Post_with_Preallocation = 1.7764
Vectorised = 5.3292

Таким образом, можно видеть, что циклы были значительно улучшены в более новых версиях.Оказывается, что решение с циклом с правильно выделенной памятью для k намного быстрее, чем векторизованное.Причиной снижения производительности является отсутствие предраспределения (как Cris Luengo уже предлагается ).Для предварительного выделения напишите k = zeros(1, size(a,2)-1); перед циклом.

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