【问题标题】:Can I avoid double forcycle by bsxfun?我可以通过 bsxfun 避免双循环吗?
【发布时间】:2016-03-22 11:37:15
【问题描述】:

我想知道,是否可以使用双 bsxfun 或类似的东西。我有这段代码:

N = 5;
prob = [0.1 0.2 0 0.1; 0 0 0.05 0.1; 0.2 0.2 0 0.1];
r = rand(size(prob,1),N);

P = zeros(N, size(prob,1));
csm = cumsum(normP([zeros(size(prob,1),1),prob]),2);

for i = 1:N
 P(i,:) = sum(bsxfun(@ge,r(:,i),csm),2);
end

Prob 矩阵包含元素介于 0 和 1 之间的行,每一行都是概率分布(经过 normP 进行归一化后)。概率矩阵的第一行用于生成向量 P 的第一个元素(值 1、2 或 4),第二行用于生成第二个元素(值 3 或 4),依此类推。

e.g.: P =

       2     4     2
       4     4     1
       2     4     2
       2     4     4
       2     3     1

我已经为一个向量 P 向量化了生成元素,但我需要生成几个 (N) 个向量。一定有办法避免for循环。

附件中有normP函数。我很乐意为您提供帮助,谢谢。

米哈尔·鲁巴利克

附: normP的代码在这里:

function nP = normP(P)
%
% Probability matrix normalization to hold sum of rows be equal to one
% i.e. sum(nP,2) = ones(N,1)
%
% No dependencies
srowP = sum(P,2);
good  = srowP>0;
bad   = ~good;
nP    = zeros(size(P));

% good case
if any(good)
    nP(good,:) = bsxfun(@rdivide, P(good,:), srowP(good));
end
% bad case
if any(bad)
    nP(bad,:) = nan(size(P(bad,:)));
end

【问题讨论】:

  • 在你接触像bsxfun这样的高级东西之前,先做一些简单的优化。 cumsum(normP([zeros(size(prob,1),1),prob]),2)) 是您在循环中一次又一次评估的表达式,在循环外预先计算它。
  • 并把nP = zeros(size(P));替换成nP = nan(size(P));,然后就可以删除%bad case
  • 谢谢,我已经更改了代码,我也编辑了问题中的代码。现在它快了大约 30%。 :)

标签: matlab vectorization bsxfun


【解决方案1】:

这是使用permute 完成矢量化的一种方法-

P = squeeze(sum(bsxfun(@ge,permute(r,[1 3 2]),csm),2)).'

说明

1) 将 r 的 dim-2 推到 dim-3 位置,在 dim=2 处引入 singleton-dim。因此,当与csm 配对以进行bsxfun(@ge 操作时,我们将有一个3D 数组作为输出,其:

dim-1 : r, csm 's dim-1
dim-2 : csm's dim-2
dim-3 : r's dim-2

2) 原始操作具有迭代输出,dim-2 仍然代表csm's dim-2sum-reduction。因此,在我们的 3D 数组输出中,我们还需要沿 dim-2 进行 sum-reduce。

3) 最后的步骤涉及squeeze-ing 和转置以对应于我们迭代保存输出P 的方式。

【讨论】:

    猜你喜欢
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 2011-05-05
    • 2017-08-12
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多