Julia中的矢量矩阵元素明智乘法(按行),有效

时间:2018-01-26 11:54:05

标签: julia

我想将矩阵A的每一行乘以相同的向量v。例如

A =[1.0 3.0; 1.0 1.0]
v = [1.0, 2.0]

我想输出

 [1.0 6.0; 1.0 2.0]

到目前为止,我正在做:

(v.*A')'

但我怀疑这是计算效率,因为我将矩阵转置两次。

作为备注,Matlab(https://uk.mathworks.com/matlabcentral/answers/243307-vector-matrix-multiplication-row-wise

回答了这个问题

2 个答案:

答案 0 :(得分:2)

您至少有以下选项:

  • (v.*A')'(OP的建议)
  • v'.*A最短路
  • mapslices(row->v.*row, A, 2)
  • @ AborAmmar的帖子手动实施(最快的方式

function tt(v, A)
    r = similar(A)
    @inbounds for j = 1:size(A,2) 
        @simd for i = 1:size(A,1) 
            r[i,j] = v[j] * A[i,j] # fixed a typo here!
        end
    end 
    r
end 

速度比较(按升序排列)

julia> @btime tt($v,$A); # @AborAmmar's answer
  38.826 ns (1 allocation: 112 bytes)

julia> @btime ($v)'.*$A;               
  49.920 ns (1 allocation: 112 bytes)

julia> @btime (($v).*($A)')';           
  123.797 ns (3 allocations: 336 bytes)                           

julia> @btime mapslices(row->($v).*row, $A, 2);
  25.174 μs (106 allocations: 5.16 KiB)
编辑:从@ AborAmmar的帖子(更换旧版本)和更新的速度比较中进行更仔细,更快速的手动实现。

答案 1 :(得分:2)

Julia真正令人敬畏的是,您可以创建自己的功能,其性能与高度优化的内置功能相同。这是另一种与(v' .* A)具有相同性能(或略好)的实现:

function tt1(v, A)
    v'.*A
end

function tt(v, A)
    r = similar(A)
    @inbounds for j = 1:size(A,2) 
        @simd for i = 1:size(A,1) 
            r[i,j] = v[j] * A[i,j]
        end
    end 
    r
end   

const n = 10^4
const A = rand(n,n)
const v = rand(n)

@time tt1(v, A);
@time tt(v, A);

  0.283537 seconds (6 allocations: 762.940 MiB, 19.70% gc time)
  0.235699 seconds (6 allocations: 762.940 MiB, 0.44% gc time)