Julia - 如何有效地将矩阵的对角线归零?
Julia - How to efficiently turn to zero the diagonal of a matrix?
在 Julia 中,将矩阵的对角线变为零的有效方法是什么?
假设 m
是大小为 N x N
的矩阵,这可以按以下方式完成:
setindex!.(Ref(m), 0.0, 1:N, 1:N)
另一个选项:
using LinearAlgebra
m[diagind(m)] .= 0.0
以及一些性能测试:
julia> using LinearAlgebra, BenchmarkTools
julia> m=rand(20,20);
julia> @btime setindex!.(Ref($m), 0.0, 1:20, 1:20);
55.533 ns (1 allocation: 240 bytes)
julia> @btime $m[diagind($m)] .= 0.0;
75.386 ns (2 allocations: 80 bytes)
Przemyslaw Szufel 针对 1_000 x 1_000 矩阵大小进行基准测试的解决方案表明 diagind
表现最佳:
julia> @btime setindex!.(Ref($m), 0.0, 1:1_000, 1:1_000);
2.222 μs (1 allocation: 7.94 KiB)
julia> @btime $m[diagind($m)] .= 0.0;
1.280 μs (2 allocations: 80 bytes)
这是一种更通用的方法,如何通过访问自定义索引在数组上高效地使用 setindex!
:
线性索引性能最好,这就是为什么 diagind
比笛卡尔索引运行得更好。
性能方面,简单循环更快(更明确,但它取决于品味)
julia> @btime foreach(i -> $m[i, i] = 0, 1:20)
11.881 ns (0 allocations: 0 bytes)
julia> @btime setindex!.(Ref($m), 0.0, 1:20, 1:20);
50.923 ns (1 allocation: 240 bytes)
它比 diagind
版本快,但相差不大
julia> m = rand(1000, 1000);
julia> @btime foreach(i -> $m[i, i] = 0.0, 1:1000)
1.456 μs (0 allocations: 0 bytes)
julia> @btime foreach(i -> @inbounds($m[i, i] = 0.0), 1:1000)
1.338 μs (0 allocations: 0 bytes)
julia> @btime $m[diagind($m)] .= 0.0;
1.495 μs (2 allocations: 80 bytes)
在 Julia 中,将矩阵的对角线变为零的有效方法是什么?
假设 m
是大小为 N x N
的矩阵,这可以按以下方式完成:
setindex!.(Ref(m), 0.0, 1:N, 1:N)
另一个选项:
using LinearAlgebra
m[diagind(m)] .= 0.0
以及一些性能测试:
julia> using LinearAlgebra, BenchmarkTools
julia> m=rand(20,20);
julia> @btime setindex!.(Ref($m), 0.0, 1:20, 1:20);
55.533 ns (1 allocation: 240 bytes)
julia> @btime $m[diagind($m)] .= 0.0;
75.386 ns (2 allocations: 80 bytes)
Przemyslaw Szufel 针对 1_000 x 1_000 矩阵大小进行基准测试的解决方案表明 diagind
表现最佳:
julia> @btime setindex!.(Ref($m), 0.0, 1:1_000, 1:1_000);
2.222 μs (1 allocation: 7.94 KiB)
julia> @btime $m[diagind($m)] .= 0.0;
1.280 μs (2 allocations: 80 bytes)
这是一种更通用的方法,如何通过访问自定义索引在数组上高效地使用 setindex!
:
线性索引性能最好,这就是为什么 diagind
比笛卡尔索引运行得更好。
性能方面,简单循环更快(更明确,但它取决于品味)
julia> @btime foreach(i -> $m[i, i] = 0, 1:20)
11.881 ns (0 allocations: 0 bytes)
julia> @btime setindex!.(Ref($m), 0.0, 1:20, 1:20);
50.923 ns (1 allocation: 240 bytes)
它比 diagind
版本快,但相差不大
julia> m = rand(1000, 1000);
julia> @btime foreach(i -> $m[i, i] = 0.0, 1:1000)
1.456 μs (0 allocations: 0 bytes)
julia> @btime foreach(i -> @inbounds($m[i, i] = 0.0), 1:1000)
1.338 μs (0 allocations: 0 bytes)
julia> @btime $m[diagind($m)] .= 0.0;
1.495 μs (2 allocations: 80 bytes)