如果Vector
表示v
而Matrix
表示为M
,那么在Julia中计算矩阵二次型的最快方法是什么,即v'Mv
?那最优雅的呢?
注意:我希望返回值为标量。有趣的是,如果v = rand(3)
和M = rand(3, 3)
,则v'*M*v
会返回包含一个元素而不是标量的向量。我并没有期待这种行为,虽然已经阅读了足够多的github问题页面,怀疑这种行为有充分的理由让我觉得不够聪明。所以,显然(v'*M*v)[1]
会完成这项工作,只是想知道是否有更好的方法......
答案 0 :(得分:6)
返回标量的一个选项是dot(v, M*v)
。
答案 1 :(得分:3)
双for
怎么样?将保存中间向量的分配。
为了完整起见,在代码中:
vMv{T}(v::Vector{T},M::Matrix{T}) = begin
size(M) == (size(v,1),size(v,1)) || throw("Vector/Matrix size mismatch")
res = zero(T)
for i = 1:size(v,1)
for j = 1:size(v,1)
res += v[i]*v[j]*M[i,j]
end
end
res
end
添加一些@inbounds
和@simd
可以优化。
答案 2 :(得分:0)
仅需说明一下,n(n-1)/2
操作在上述双循环中是多余的;如果v
是n个元素上的向量,并且M
是nxn矩阵,则二次形式v'Mv的计算仅需要以下操作:
sum_i=1:n(v[i]^2 * M[i, i]) + sum_j=1:n-1, i=j+1:n(2 * (v[i] * v[j] * M[i, j]))