Matrix 朱莉娅-如何有效地将矩阵的对角线变为零?

Matrix 朱莉娅-如何有效地将矩阵的对角线变为零?,matrix,julia,linear-algebra,diagonal,Matrix,Julia,Linear Algebra,Diagonal,在Julia中,什么是将矩阵的对角线变为零的有效方法?假设m是您的大小矩阵nxn,可以这样做: 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)

在Julia中,什么是将矩阵的对角线变为零的有效方法?

假设
m
是您的大小矩阵
nxn
,可以这样做:

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
比笛卡尔索引运行得更好。

性能方面,简单循环更快(更明确,但它取决于味道)

而且它比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 = 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)