如何使用 mvnpdf 向量化 Matlab 代码?
How to vectorize Matlab Code with mvnpdf in?
我在 matlab 中有一些工作代码,速度至关重要。我有 vectorized/optimized 它的许多部分,分析器现在告诉我大部分时间花在一小段代码上。为此,
我有一些参数集用于 多变量正态分布
分布.
然后我必须在某个时候从相应的 PDF 中获取值
位置,
并将其乘以存储在向量中的其他值。
我在下面制作了一个最小的工作示例:
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()
函数。
是的,您可以,但是,我认为它不会给您带来巨大的性能提升。您将不得不重塑您的 mu
和 sigma
。
检查 mvnpdf(X,mu,sigma)
的文档,您会发现必须提供 X
和 mu
作为 n-by-d 数值矩阵和 sigma
为 d-by-d-by-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
我在 matlab 中有一些工作代码,速度至关重要。我有 vectorized/optimized 它的许多部分,分析器现在告诉我大部分时间花在一小段代码上。为此,
我有一些参数集用于 多变量正态分布 分布.
然后我必须在某个时候从相应的 PDF 中获取值 位置,
并将其乘以存储在向量中的其他值。
我在下面制作了一个最小的工作示例:
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()
函数。
是的,您可以,但是,我认为它不会给您带来巨大的性能提升。您将不得不重塑您的 mu
和 sigma
。
检查 mvnpdf(X,mu,sigma)
的文档,您会发现必须提供 X
和 mu
作为 n-by-d 数值矩阵和 sigma
为 d-by-d-by-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