Skip to content

Commit

Permalink
Define Base.isstored for Diagonals and Triangular matrices (#50391)
Browse files Browse the repository at this point in the history
X-ref #50377
  • Loading branch information
longemen3000 authored Jul 6, 2023
1 parent c14d4bb commit b6bfe98
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
13 changes: 13 additions & 0 deletions stdlib/LinearAlgebra/src/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,19 @@ end
end
end

@inline function Base.isstored(A::Bidiagonal, i::Int, j::Int)
@boundscheck checkbounds(A, i, j)
if i == j
return @inbounds Base.isstored(A.dv, i)
elseif A.uplo == 'U' && (i == j - 1)
return @inbounds Base.isstored(A.ev, i)
elseif A.uplo == 'L' && (i == j + 1)
return @inbounds Base.isstored(A.ev, j)
else
return false
end
end

@inline function getindex(A::Bidiagonal{T}, i::Integer, j::Integer) where T
@boundscheck checkbounds(A, i, j)
if i == j
Expand Down
10 changes: 10 additions & 0 deletions stdlib/LinearAlgebra/src/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ end
r
end

@inline function Base.isstored(D::Diagonal, i::Int, j::Int)
@boundscheck checkbounds(D, i, j)
if i == j
@inbounds r = Base.isstored(D.diag, i)
else
r = false
end
r
end

@inline function getindex(D::Diagonal, i::Int, j::Int)
@boundscheck checkbounds(D, i, j)
if i == j
Expand Down
9 changes: 9 additions & 0 deletions stdlib/LinearAlgebra/src/triangular.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ Base.isassigned(A::UnitUpperTriangular, i::Int, j::Int) =
Base.isassigned(A::UpperTriangular, i::Int, j::Int) =
i <= j ? isassigned(A.data, i, j) : true

Base.isstored(A::UnitLowerTriangular, i::Int, j::Int) =
i > j ? Base.isstored(A.data, i, j) : false
Base.isstored(A::LowerTriangular, i::Int, j::Int) =
i >= j ? Base.isstored(A.data, i, j) : false
Base.isstored(A::UnitUpperTriangular, i::Int, j::Int) =
i < j ? Base.isstored(A.data, i, j) : false
Base.isstored(A::UpperTriangular, i::Int, j::Int) =
i <= j ? Base.isstored(A.data, i, j) : false

getindex(A::UnitLowerTriangular{T}, i::Integer, j::Integer) where {T} =
i > j ? A.data[i,j] : ifelse(i == j, oneunit(T), zero(T))
getindex(A::LowerTriangular, i::Integer, j::Integer) =
Expand Down
26 changes: 26 additions & 0 deletions stdlib/LinearAlgebra/src/tridiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,19 @@ logabsdet(A::SymTridiagonal; shift::Number=false) = logabsdet(ldlt(A; shift=shif
end
end

@inline function Base.isstored(A::SymTridiagonal, i::Int, j::Int)
@boundscheck checkbounds(A, i, j)
if i == j
return @inbounds Base.isstored(A.dv, i)
elseif i == j + 1
return @inbounds Base.isstored(A.ev, j)
elseif i + 1 == j
return @inbounds Base.isstored(A.ev, i)
else
return false
end
end

@inline function getindex(A::SymTridiagonal{T}, i::Integer, j::Integer) where T
@boundscheck checkbounds(A, i, j)
if i == j
Expand Down Expand Up @@ -632,6 +645,19 @@ end
end
end

@inline function Base.isstored(A::Tridiagonal, i::Int, j::Int)
@boundscheck checkbounds(A, i, j)
if i == j
return @inbounds Base.isstored(A.d, i)
elseif i == j + 1
return @inbounds Base.isstored(A.dl, j)
elseif i + 1 == j
return @inbounds Base.isstored(A.du, i)
else
return false
end
end

@inline function getindex(A::Tridiagonal{T}, i::Integer, j::Integer) where T
@boundscheck checkbounds(A, i, j)
if i == j
Expand Down
15 changes: 15 additions & 0 deletions stdlib/LinearAlgebra/test/bidiag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,21 @@ Random.seed!(1)
@test_throws ArgumentError Bl[4, 5] = 1
end

@testset "isstored" begin
ubd = Bidiagonal(dv, ev, :U)
lbd = Bidiagonal(dv, ev, :L)
# bidiagonal isstored / upper & lower
@test_throws BoundsError Base.isstored(ubd, n + 1, 1)
@test_throws BoundsError Base.isstored(ubd, 1, n + 1)
@test Base.isstored(ubd, 2, 2)
# bidiagonal isstored / upper
@test Base.isstored(ubd, 2, 3)
@test !Base.isstored(ubd, 3, 2)
# bidiagonal isstored / lower
@test Base.isstored(lbd, 3, 2)
@test !Base.isstored(lbd, 2, 3)
end

@testset "show" begin
BD = Bidiagonal(dv, ev, :U)
dstring = sprint(Base.print_matrix,BD.dv')
Expand Down
3 changes: 3 additions & 0 deletions stdlib/LinearAlgebra/test/diagonal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ Random.seed!(1)
@test !istril(D, -1)
@test istril(D, 1)
@test istril(Diagonal(zero(diag(D))), -1)
@test Base.isstored(D,1,1)
@test !Base.isstored(D,1,2)
@test_throws BoundsError Base.isstored(D, n + 1, 1)
if elty <: Real
@test ishermitian(D)
end
Expand Down

0 comments on commit b6bfe98

Please sign in to comment.