【问题标题】:Sum of outer products multiplied by a scalar in MATLAB外积之和乘以 MATLAB 中的标量
【发布时间】:2015-08-03 07:10:02
【问题描述】:

我想在以后对乘积的总和进行矢量化,以加快我的 Matlab 代码。有可能吗?

for i=1:N
    A=A+hazard(i)*Z(i,:)'*Z(i,:);
end

其中hazard 是一个向量 (N x 1),Z 是一个矩阵 (N x p)。

谢谢!

【问题讨论】:

    标签: performance matlab vectorization product outer-join


    【解决方案1】:

    仅使用矩阵乘法:

    A = A + Z'*diag(hazard)*Z;
    

    但是请注意,这需要比Divakar's bsxfun approach 更多的操作,因为diag(hazard) 是一个主要由零组成的NxN 矩阵。

    为了节省一些时间,您可以使用spdiags 将内部矩阵定义为sparse,这样可以优化乘法:

    A = A + full(Z'*spdiags(hazard, 0, zeros(N))*Z);
    

    基准测试

    计时码:

    Z = rand(N,p);
    hazard = rand(N,1);
    timeit(@() Z'*diag(hazard)*Z)
    timeit(@() full(Z'*spdiags(hazard, 0, zeros(N))*Z))
    timeit(@() bsxfun(@times,Z,hazard)'*Z)
    

    N = 1000; p = 300;

    ans =
        0.1423
    ans =
        0.0441
    ans =
        0.0325
    

    N = 2000; p = 1000;

    ans =
        1.8889
    ans =
        0.7110
    ans =
        0.6600
    

    N = 1000; p = 2000;

    ans =
        1.8159
    ans =
        1.2471
    ans =
        1.2264
    

    可以看出,基于bsxfun 的方法始终更快。

    【讨论】:

    • 也可以!添加A 可能吗?
    • @Divakar 哎呀!谢谢。已更正
    • 更好!我尝试使用 tic/toc,你的方法快了 20%!
    • 我很高兴它对你来说很快。但是为了获得可靠的计时,您应该使用timeit。基于bsxfun 的方法在我的计算机上似乎要快得多。查看我的时间(我已经编辑了我的答案)
    • 纯矩阵乘法版本的意图很明显,这弥补了 IMO 的微小速度差异。
    【解决方案2】:

    您可以使用bsxfunmatrix-multiplication -

    A =  bsxfun(@times,Z,hazard).'*Z + A
    

    【讨论】:

    • 非常感谢!它工作得很好,但是,如果不使用 bsxfun(仅使用向量/矩阵的乘积)就无法对其进行向量化?
    • @AlessandroBeretta 你可以使用 repmat:repmat(hazard,1,p).*Z,但是bsxfun 有什么不情愿的呢?
    • 不,只是因为看起来计算时间并没有减少那么多......无论如何,再次感谢您的回答!
    • 我添加了一些基准测试。在我测试过的所有情况下,基于bsxfun 的方法都更快
    猜你喜欢
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-06
    相关资源
    最近更新 更多