我想将A维度为ntimes 的矩阵中的所有元素相加n。该矩阵是对称的并且对角线上有 0。我发现最快的方法很简单
sum(A)。然而,这似乎很浪费,因为它没有利用我只需要计算矩阵的下三角形的事实。然而,sum(tril(A, -1))速度明显慢得多,甚至sum(A[i, j] for i = 1:n-1 for j = i+1:n)更慢。有没有更有效的方法来求和矩阵?
编辑:@AboAmmar 的解决方案表现良好。下面是要比较的代码(分别对对角线求和,如果对角线上只有零,则可以删除某些内容):
using BenchmarkTools
using LinearAlgebra
function sum_triu(A)
m, n = size(A)
@assert m == n
s = zero(eltype(A))
for j = 2:n
@simd for i = 1:j-1
s += @inbounds A[i,j]
end
end
s *= 2
for i = 1:n
s += A[i, i]
end
return s
end
N = 1000
A = Symmetric(rand(0:9,N,N))
A -= diagm(diag(A))
@btime sum(A)
@btime 2 * sum(tril(A))
@btime sum_triu(A)
Run Code Online (Sandbox Code Playgroud)
这比sumn = 1000 矩阵快 2.7 倍。确保添加一个@simd在循环之前添加 a 并使用@inbounds. 另外,使用正确的循环顺序来实现快速内存访问。
function sum_triu(A)\n m, n = size(A)\n @assert m == n\n s = zero(eltype(A))\n for j = 1:n\n @simd for i = 1:j \n s += @inbounds A[i,j]\n end\n end\n return 2 * s\nend\nRun Code Online (Sandbox Code Playgroud)\n在我的电脑上运行的示例:
\nsum_triu(A) = 499268.7328022966\nsum(A) = 499268.73280229873\n 93.000 \xce\xbcs (0 allocations: 0 bytes)\n 249.900 \xce\xbcs (0 allocations: 0 bytes)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
171 次 |
| 最近记录: |