В моем коде есть строка, в которой я вычисляю совокупную сумму вектора 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
Профилируйте свой код, а затем проверьте, что делает его медленным.
@AnderBiguri Я знаю, что большую часть времени занимают именно кончи и находки (наряду с генерацией случайных чисел - но я ничего не могу с этим поделать).
@ user112495, тогда вы, вероятно, сможете создать код значительно меньшего размера, чтобы мы его протестировали.
@AnderBiguri Я сделал что-то попроще. В приведенном выше примере около 50% времени тратится на cumsum () и около 40% - на find ().
@Wolfie Достаточно ли вышеперечисленного?
Я не уверен, что вы можете еще больше ускорить это. Причина, по которой они занимают все время, заключается в том, что все остальное - это такие фундаментальные операции, которые совсем не требуют времени, а не потому, что они по своей сути медленные.
@AnderBiguri Полагаю, я просто подумал о том, что cumsum состоит в том, что только один элемент в ставках фактически изменяет каждую итерацию, поэтому есть некоторая часть совокупной суммы, которая вообще не изменится. Но я не знаю, есть ли способ написать, который ускорит работу.
Звучит как простой цикл, почему бы вам не попробовать?
@AnderBiguri В контексте вышеизложенного я попробовал cums (eventHouseNum: end) = cums (eventHouseNum: end) - previousRate + newRate, но это было не быстрее. Я не уверен, есть ли более быстрый способ сделать что-то подобное в MATLAB
Нет, вы не можете заменить встроенный MATLAB для более быстрого кода. Они продают свой товар дорого, потому что он и так быстро
Этот пример намного лучше, спасибо! Похоже, то, что делает это медленным, - это ваш случайный и потенциально очень маленький временной шаг ... оптимизируйте функциональность, а не отдельные строки, когда вы находитесь на этапе, когда встроенные модули низкого уровня являются вашим узким местом. Подобно пересмотру того, является ли ваша структура лучшей, часто, когда задействован цикл while
, ответ - «Это не так».
@Wolfie Я добавил сокращенный пример кода. Это нормально, или их все еще слишком много?