我正在尝试在Matlab中模拟一个大维Markov链。转换矩阵约为[6000,6000]。
我尽可能地对代码进行了矢量化,但它仍然非常慢(大约4秒)。罪魁祸首是大矩阵的索引 - 65%的时间用在第37行(t2 = cum_transition(value(t-1,:),:);
)。
我有什么办法可以加快速度吗?实际问题的尺寸甚至更大,并且在优化更大功能期间需要调用很多次。
clear
clc
% dimension of transition matrix
dim = 6000;
% goal: simulate n_year periods, for n_ppl individuals
n_ppl = 1000;
n_year = 100;
% transition matrix: prob_ij = prob_j given i. \sum_j prob_ij = 1
transition = rand(dim);
transition = transition./repmat(sum(transition,2),1,dim); %so that probabiltiies sum to 1
cum_transition = cumsum(transition,2); % cumulative (along the row) probabitliy
% generate random numbers to use as simulate the chain
rand_numbers = rand(n_year, n_ppl);
% value = which index of the matrix they are. Start by assuming ppl spread evenly along i dimension
value = zeros(n_year, n_ppl);
value(1,:) = randi([1 dim], [1,n_ppl]);
% initialize t1/t2
t1 = zeros(n_ppl, dim);
t2 = zeros(n_ppl, dim);
% METHOD 1: USING REPMAT
% with n_ppl = 1000, takes: 4.16 seconds
tic
% now simulate out the chain
for t = 2:n_year
t1 = repmat(rand_numbers(t,:)', 1,dim);
t2 = cum_transition(value(t-1,:),:);
value(t,:) = 1+sum(t1>t2,2)';
end
toc
% METHOD 2: USING BSXFUN
% with n_ppl = 1000, takes: 7.3 seconds
tic
t1 = zeros(n_ppl, 1);
for t= 2:n_year
t1 = rand_numbers(t,:);
t2 = cum_transition(value(t-1,:),:);
value(t,:) = 1 + sum(bsxfun(@gt, t1,t2'));
end
toc