Julia中的向量矩阵元素(按行)高效乘法
我想把矩阵A的每一行乘以相同的向量v。比如说Julia中的向量矩阵元素(按行)高效乘法,julia,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()回答的。您至少有以下选项: (v.*A')”(OP的建议) v.*A(最短路径) mapslices(行->v.*行,A,2) 从@AborAmmar的帖子手动执行(最快方式) i、 e
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()回答的。您至少有以下选项:
(OP的建议)(v.*A')”
(最短路径)v.*A
mapslices(行->v.*行,A,2)
- 从@AborAmmar的帖子手动执行(最快方式)
编辑:从@AborAmmar的帖子(取代了旧的帖子)和更新的速度比较中更仔细、更快地手动实现。Julia真正令人敬畏的是,您可以创建自己的函数,其性能与高度优化的内置函数相同。下面是另一个性能与
(v.*A)
相同(或稍好)的实现:
A.*v'
适用于我(Julia v0.6.3)还要注意的是,逐向量乘法有多种风格。通过示例,您将根据v
将A
的每一列乘以不同的标量。感谢您提供代码和示例来澄清问题。@DanGetz,正如一个注释,a.*v'
出乎意料地比我的机器上的(v.*a')
稍慢(与Julia版本相同)。您也可以做mapslices(row->v.*row,a,2)
,但这也比这里已经提到的要慢。@DanGetz,我的坏朋友,在基准测试中出错我在我的帖子中引用并将您的版本添加到基准测试中。我更正了一个错误,它是v[j]
而不是v[I]
。
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)
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)