Ускорьте код matlab

В моем коде есть строка, в которой я вычисляю совокупную сумму вектора A, используя функцию cumsum () в MATLAB (R2017b). Однако между каждой итерацией изменяется только один элемент в векторе A, поэтому на самом деле меняются только значения, начиная с этой точки. Мне было интересно, есть ли более быстрый способ сделать это? Я пробовал A (elementNumber: end) = A (elementNumber: end) - oldValue + newValue, но это не быстрее.

Кроме того, я затем использую функцию find () на каждой итерации, чтобы найти первый индекс в этой совокупной матрице сумм, где значение сначала превышает определенное значение.

Мне было интересно, есть ли более быстрый способ выполнить любое из них в MATLAB?

Пример кода, который я использую, приведен ниже:

beta = 0.05;
S = randi(130, 15000, 1); I = randi(130, 15000, 1);
tmax = 10000; n=1; t(1) = 0; t1=0;
rates = (beta.*S.*I); cums = cumsum(rates); numI = sum(I);
Rtot = cums(end);
n=1; t(1) = 0; t1=0;
while t1<tmax
    if n>1
        newRate = beta*S(eventHouseNum)*I(eventHouseNum);
%         rates(eventHouseNum) = beta*S(eventHouseNum)*I(eventHouseNum);
        cums(eventHouseNum:end) = cums(eventHouseNum:end) - rates(eventHouseNum) + newRate;
        rates(eventHouseNum) = newRate
    end       
    Rtot = cums(end);
    if Rtot==0
        return
    end
    randNums = rand(2,1);
    dt=-log(randNums(1))/Rtot;
    P=randNums(2)*Rtot; 
    eventHouseNum = find(cums>=P,1);
    S(eventHouseNum) = S(eventHouseNum)-1;
    I(eventHouseNum) = S(eventHouseNum)+1;
    numI = numI+1; n=n+1;
    t(n)=t(n-1)+dt; t1=t(n);
    Iarray1(n) = numI;
end

@Wolfie Я добавил сокращенный пример кода. Это нормально, или их все еще слишком много?

user112495 10.08.2018 16:26

Профилируйте свой код, а затем проверьте, что делает его медленным.

Ander Biguri 10.08.2018 17:05

@AnderBiguri Я знаю, что большую часть времени занимают именно кончи и находки (наряду с генерацией случайных чисел - но я ничего не могу с этим поделать).

user112495 10.08.2018 17:12

@ user112495, тогда вы, вероятно, сможете создать код значительно меньшего размера, чтобы мы его протестировали.

Ander Biguri 10.08.2018 17:14

@AnderBiguri Я сделал что-то попроще. В приведенном выше примере около 50% времени тратится на cumsum () и около 40% - на find ().

user112495 10.08.2018 17:35

@Wolfie Достаточно ли вышеперечисленного?

user112495 10.08.2018 17:37

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

Ander Biguri 10.08.2018 17:39

@AnderBiguri Полагаю, я просто подумал о том, что cumsum состоит в том, что только один элемент в ставках фактически изменяет каждую итерацию, поэтому есть некоторая часть совокупной суммы, которая вообще не изменится. Но я не знаю, есть ли способ написать, который ускорит работу.

user112495 10.08.2018 17:42

Звучит как простой цикл, почему бы вам не попробовать?

Ander Biguri 10.08.2018 17:44

@AnderBiguri В контексте вышеизложенного я попробовал cums (eventHouseNum: end) = cums (eventHouseNum: end) - previousRate + newRate, но это было не быстрее. Я не уверен, есть ли более быстрый способ сделать что-то подобное в MATLAB

user112495 10.08.2018 17:46

Нет, вы не можете заменить встроенный MATLAB для более быстрого кода. Они продают свой товар дорого, потому что он и так быстро

Ander Biguri 10.08.2018 17:50

Этот пример намного лучше, спасибо! Похоже, то, что делает это медленным, - это ваш случайный и потенциально очень маленький временной шаг ... оптимизируйте функциональность, а не отдельные строки, когда вы находитесь на этапе, когда встроенные модули низкого уровня являются вашим узким местом. Подобно пересмотру того, является ли ваша структура лучшей, часто, когда задействован цикл while, ответ - «Это не так».

Wolfie 10.08.2018 18:19
1
12
79
0

Другие вопросы по теме