Can views function on diag?

Diagonal vector is a central vector that can be sliced from a Matrix, can it be viewed?

julia> using LinearAlgebra

julia> A = rand(-9:9, 2, 2)
2×2 Matrix{Int64}:
 -1   6
  6  -9

julia> @views d = diag(A)
2-element Vector{Int64}:
 -1
 -9

julia> d .= 0 # set the diagonals to zero
2-element Vector{Int64}:
 0
 0

julia> A # it doesn't work
2×2 Matrix{Int64}:
 -1   6
  6  -9

If it functions, it could also be used to, e.g. make a matrix become diagonally dominant, become posdef etc.

julia>  A = rand(-9:9, 2, 2)
2×2 Matrix{Int64}:
 -5  -2
 -1   0

julia> diagidx=[CartesianIndex(i,i) for i=1:2]
2-element Vector{CartesianIndex{2}}:
 CartesianIndex(1, 1)
 CartesianIndex(2, 2)

julia> view(A,diagidx)
2-element view(::Matrix{Int64}, CartesianIndex{2}[CartesianIndex(1, 1), CartesianIndex(2, 2)]) with eltype Int64:
 -5
  0

The diag function creates a new vector, so that method won’t work.

LinearAlgebra.jl provides the diagind function so you don’t have to build diagidx yourself, and it returns a unit range instead of a vector if possible such that you get a manifestly strided view:

julia> using LinearAlgebra

julia> A = rand(-9:9, 2, 2)
2×2 Matrix{Int64}:
  4  -4
 -4   0

julia> @view A[diagind(A)]
2-element view(::Vector{Int64}, 1:3:4) with eltype Int64:
 4
 0
2 Likes

Julia 1.12 also has diagview, which is basically @view A[diagind(A)].

7 Likes