我想将矩阵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)
回答了这个问题答案 0 :(得分:2)
您至少有以下选项:
(v.*A')'
(OP的建议)v'.*A
(最短路)mapslices(row->v.*row, A, 2)
即
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)