提高四个嵌套循环的性能 - MATLAB

时间:2016-06-08 07:56:22

标签: performance matlab vectorization

我是MATLAB矩阵计算的新手,当我有许多for循环时,我不知道如何提高性能。我试图通过查看类似的问题来解决这个问题,但我仍然感到困惑。

这是我的代码:

pred = zeros(n_test,1) % vector saving all prediction results
for d = 1:n_test  % n_test test data
    u = user(d); 
    p_locations = zeros(n_location,1); 
    for i = 1:n_location
        for z = 1:n_topic
            for r = 1:n_region
                p_locations(i) = p_locations(i)+para.Pzu(z,u)*para.Pru(r,u)*para.Piz(i,z)*para.Pir(i,r);  % calculate the probability of the location i      
            end
        end
    end
    [val, pos] = max(p_locations); % find the location of the largest probability
    pred(d) = pos;
end

根据评论,基本上,我想预测每个测试数据的位置。然后我将与实际情况进行比较。

我有近80000个测试数据,计算速度很慢。它已经13个小时了,而且还在运行。你能告诉我如何重新编写代码吗?非常感谢!

2 个答案:

答案 0 :(得分:3)

使用bsxfun和高效matrix-multiplication在部分中执行广播操作,这是一个完全向量化的方法 -

p1 = bsxfun(@times,Pzu(:,user).',permute(Pru(:,user),[2,3,1]));
p2 = bsxfun(@times,Piz,permute(Pir,[1,3,2]));

[~,m,n] = size(p1);
sums = reshape(p2,[],m*n)*(reshape(p1,[],m*n).');
[~, pred_out] = max(sums,[],1);

基准

基准代码 -

% Setup inputs
n_topic = 70;
n_test = 70;
n_region = 70;
n_location = 70;
user = randi(n_test,n_test,1);

Pzu = rand(n_topic,n_test);
Pru = rand(n_region,n_test);
Piz = rand(n_location,n_topic);
Pir = rand(n_location,n_region);

disp('----------- With original loopy approach')
tic
% ... Original code
toc

disp('----------- With vectorized approach')
tic
% ... Proposed code
toc

max_error = max(abs(pred(:)-pred_out(:)))

输出 -

----------- With original loopy approach
Elapsed time is 1.157094 seconds.
----------- With vectorized approach
Elapsed time is 0.016201 seconds.
max_error =
     0

答案 1 :(得分:0)

如何为此问题编写关联的矩阵运算。然后,通过直接使用矩阵运算而非元素运算来计算每个位置的概率。 Matlab使用矩阵运算要快得多,因为它们使用CPU的向量指令。 与您的用例,bsxfun和潜在的稀疏矩阵相关,如果您找不到一个很好的密集矩阵公式。