首页 > 解决方案 > 如何用 mvnpdf 向量化 Matlab 代码?

问题描述

我在 matlab 中有一些工作代码,速度至关重要。我已经对它的许多部分进行了矢量化/优化,分析器现在告诉我大部分时间都花在了一小段代码上。为了这,

我在下面制作了一个最小的工作示例:

num_params = 1000;
prob_dist_params = repmat({ [1, 2], [10, 1; 1, 5] }, num_params, 1);
saved_nu  = rand( num_params, 1 );
saved_pos = rand( num_params, 2 );
saved_total = 0;
tic()
for param_counter = 1:size(prob_dist_params)
    % Evaluate the PDF at specified points
    pdf_vals = mvnpdf( saved_pos(param_counter,:), prob_dist_params{param_counter,1}, prob_dist_params{param_counter, 2} );
    saved_total = saved_total + saved_nu(param_counter)*pdf_vals;
end % End of looping over parameters
toc()

我知道prob_dist_params在这种情况下都是一样的,但是在我的代码中,我们的每个元素都不同,这取决于上游的一些事情。我在我的完整程序中多次调用这段特定的代码,所以我想知道是否有什么我可以做的来向量化这个循环,或者如果失败了,就加速它?我不知道如何通过包含一个mvnpdf()函数来做到这一点。

标签: matlabvectorization

解决方案


是的,你可以,但是,我认为它不会给你带来巨大的性能提升。你将不得不重塑你mu的 's 和sigma's。

检查 的文档mvnpdf(X,mu,sigma),您会看到您必须提供Xmu作为n × d数字矩阵和sigma作为d × d × n

在您的情况下,d为 2,n为 1000。您必须将元胞数组拆分为两个矩阵,并按如下方式重塑:

prob_dist_mu = cell2mat(prob_dist_params(:,1));
prob_dist_sigma = cell2mat(permute(prob_dist_params(:,2),[3 2 1]));

使用permute,我将元胞数组的第一个维度设为第三个维度,因此cell2mat将生成一个 2×2×1000 矩阵。或者,您可以按如下方式定义它们,

prob_dist_mu = repmat([1 2], [num_params 1]);
prob_dist_sigma = repmat([10, 1; 1, 5], [1 1 num_params]);

mvnpdf现在打电话

pdf_vals = mvnpdf(saved_pos, prob_dist_mu, prob_dist_sigma);
saved_total = saved_nu.'*pdf_vals;     % simple dot product

推荐阅读