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



我对 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 个小时了,它仍在运行。那么你能教我如何重写代码吗?多谢!

使用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

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

最新更新