Мне интересно, если можно использовать двойной bsxfun или что-то подобное. У меня этот кусок кода:Могу ли я избежать двойного forcycle by bsxfun?
N = 5;
prob = [0.1 0.2 0 0.1; 0 0 0.05 0.1; 0.2 0.2 0 0.1];
r = rand(size(prob,1),N);
P = zeros(N, size(prob,1));
csm = cumsum(normP([zeros(size(prob,1),1),prob]),2);
for i = 1:N
P(i,:) = sum(bsxfun(@ge,r(:,i),csm),2);
end
Проб матрица содержит строки с элементами между 0 и 1, каждая строка распределения вероятностей (после нормализации, проводимой normP). Первая строка матрицы вероятностей используется для генерации первого элемента вектора P (значения 1,2 или 4), второй строки для второго элемента (значения 3 или 4) и т. Д.
e.g.: P =
2 4 2
4 4 1
2 4 2
2 4 4
2 3 1
Я уже векторизовал генерирующие элементы для одного вектора P, но мне нужно сгенерировать несколько (N) векторов. Должен быть способ избежать цикла for.
В приложении, есть функция normP. Я буду рад за помощь, спасибо.
Michal Roubalik
P.S. Кодекс normP здесь:
function nP = normP(P)
%
% Probability matrix normalization to hold sum of rows be equal to one
% i.e. sum(nP,2) = ones(N,1)
%
% No dependencies
srowP = sum(P,2);
good = srowP>0;
bad = ~good;
nP = zeros(size(P));
% good case
if any(good)
nP(good,:) = bsxfun(@rdivide, P(good,:), srowP(good));
end
% bad case
if any(bad)
nP(bad,:) = nan(size(P(bad,:)));
end
Перед тем, как коснуться каких-либо продвинутых материалов, таких как 'bsxfun', сделайте простые оптимизации. 'cumsum (normP ([zeros (size (prob, 1), 1), prob]), 2))' - выражение, которое вы снова и снова оцениваете в своем цикле, предварительно вычислите его за пределами своего цикла. – Daniel
И замените 'nP = нули (размер (P));' с 'nP = nan (size (P));', тогда вы можете удалить '% bad case' – Daniel
спасибо, я изменил код, также Я редактировал код в вопросе. Это примерно на 30% быстрее. :) –