Skip to content

Commit 2df36b9

Browse files
committed
setindex! with BandIndex
1 parent 925acef commit 2df36b9

File tree

6 files changed

+89
-1
lines changed

6 files changed

+89
-1
lines changed

src/bidiag.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,19 @@ end
178178
return A
179179
end
180180

181+
@inline function setindex!(A::Bidiagonal, x, b::BandIndex)
182+
@boundscheck checkbounds(A, b)
183+
if b.band == 0
184+
@inbounds A.dv[b.index] = x
185+
elseif b.band (-1,1) && b.band == _offdiagind(A.uplo)
186+
@inbounds A.ev[b.index] = x
187+
elseif !iszero(x)
188+
throw(ArgumentError(LazyString(lazy"cannot set entry $(to_indices(A, (b,))) off the ",
189+
A.uplo == 'U' ? "upper" : "lower", " bidiagonal band to a nonzero value ", x)))
190+
end
191+
return A
192+
end
193+
181194
Base._reverse(A::Bidiagonal, dims) = reverse!(Matrix(A); dims)
182195
Base._reverse(A::Bidiagonal, ::Colon) = Bidiagonal(reverse(A.dv), reverse(A.ev), A.uplo == 'U' ? :L : :U)
183196

src/diagonal.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ zeroslike(::Type{M}, sz::Tuple{Integer, Vararg{Integer}}) where {M<:AbstractMatr
218218
r
219219
end
220220

221-
function setindex!(D::Diagonal, v, i::Int, j::Int)
221+
@inline function setindex!(D::Diagonal, v, i::Int, j::Int)
222222
@boundscheck checkbounds(D, i, j)
223223
if i == j
224224
@inbounds D.diag[i] = v
@@ -228,6 +228,15 @@ function setindex!(D::Diagonal, v, i::Int, j::Int)
228228
return D
229229
end
230230

231+
@inline function setindex!(D::Diagonal, v, b::BandIndex)
232+
@boundscheck checkbounds(D, b)
233+
if b.band == 0
234+
@inbounds D.diag[b.index] = v
235+
elseif !iszero(v)
236+
throw(ArgumentError(lazy"cannot set off-diagonal entry $(to_indices(D, (b,))) to a nonzero value ($v)"))
237+
end
238+
return D
239+
end
231240

232241
## structured matrix methods ##
233242
function Base.replace_in_print_matrix(A::Diagonal,i::Integer,j::Integer,s::AbstractString)

src/tridiag.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,17 @@ Base._reverse!(A::SymTridiagonal, dims::Colon) = (reverse!(A.dv); reverse!(A.ev)
509509
return A
510510
end
511511

512+
@inline function setindex!(A::SymTridiagonal, x, b::BandIndex)
513+
@boundscheck checkbounds(A, b)
514+
if b.band == 0
515+
issymmetric(x) || throw(ArgumentError("cannot set a diagonal entry of a SymTridiagonal to an asymmetric value"))
516+
@inbounds A.dv[b.index] = x
517+
else
518+
throw(ArgumentError(lazy"cannot set off-diagonal entry $(to_indices(A, (b,)))"))
519+
end
520+
return A
521+
end
522+
512523
## Tridiagonal matrices ##
513524
struct Tridiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T}
514525
dl::V # sub-diagonal
@@ -771,6 +782,21 @@ end
771782
return A
772783
end
773784

785+
@inline function setindex!(A::Tridiagonal, x, b::BandIndex)
786+
@boundscheck checkbounds(A, b)
787+
if b.band == 0
788+
@inbounds A.d[b.index] = x
789+
elseif b.band == -1
790+
@inbounds A.dl[b.index] = x
791+
elseif b.band == 1
792+
@inbounds A.du[b.index] = x
793+
elseif !iszero(x)
794+
throw(ArgumentError(LazyString(lazy"cannot set entry $(to_indices(A, (b,))) off ",
795+
lazy"the tridiagonal band to a nonzero value ($x)")))
796+
end
797+
return A
798+
end
799+
774800
## structured matrix methods ##
775801
function Base.replace_in_print_matrix(A::Tridiagonal,i::Integer,j::Integer,s::AbstractString)
776802
i==j-1||i==j||i==j+1 ? s : Base.replace_with_centered_mark(s)

test/bidiag.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,4 +1172,18 @@ end
11721172
@test_throws InexactError convert(Bidiagonal, M)
11731173
end
11741174

1175+
@testset "setindex! with BandIndex" begin
1176+
B = Bidiagonal(zeros(3), zeros(2), :U)
1177+
B[LinearAlgebra.BandIndex(0,2)] = 1
1178+
@test B[2,2] == 1
1179+
B[LinearAlgebra.BandIndex(1,1)] = 2
1180+
@test B[1,2] == 2
1181+
@test_throws "cannot set entry $((1,3)) off the upper bidiagonal band" B[LinearAlgebra.BandIndex(2,1)] = 2
1182+
1183+
B = Bidiagonal(zeros(3), zeros(2), :L)
1184+
B[LinearAlgebra.BandIndex(-1,1)] = 2
1185+
@test B[2,1] == 2
1186+
@test_throws "cannot set entry $((3,1)) off the lower bidiagonal band" B[LinearAlgebra.BandIndex(-2,1)] = 2
1187+
end
1188+
11751189
end # module TestBidiagonal

test/diagonal.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,4 +1481,11 @@ end
14811481
@test ishermitian(D) == ishermitian(A)
14821482
end
14831483

1484+
@testset "setindex! with BandIndex" begin
1485+
D = Diagonal(zeros(2))
1486+
D[LinearAlgebra.BandIndex(0,2)] = 1
1487+
@test D[2,2] == 1
1488+
@test_throws "cannot set off-diagonal entry" D[LinearAlgebra.BandIndex(1,1)] = 1
1489+
end
1490+
14841491
end # module TestDiagonal

test/tridiag.jl

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,4 +1162,23 @@ end
11621162
end
11631163
end
11641164

1165+
@testset "setindex! with BandIndex" begin
1166+
T = Tridiagonal(zeros(3), zeros(4), zeros(3))
1167+
T[LinearAlgebra.BandIndex(0,2)] = 1
1168+
@test T[2,2] == 1
1169+
T[LinearAlgebra.BandIndex(1,2)] = 2
1170+
@test T[2,3] == 2
1171+
T[LinearAlgebra.BandIndex(-1,2)] = 3
1172+
@test T[3,2] == 3
1173+
1174+
@test_throws "cannot set entry $((1,3)) off the tridiagonal band" T[LinearAlgebra.BandIndex(2,1)] = 1
1175+
@test_throws "cannot set entry $((3,1)) off the tridiagonal band" T[LinearAlgebra.BandIndex(-2,1)] = 1
1176+
1177+
S = SymTridiagonal(zeros(4), zeros(3))
1178+
S[LinearAlgebra.BandIndex(0,2)] = 1
1179+
@test S[2,2] == 1
1180+
1181+
@test_throws "cannot set off-diagonal entry $((1,3))" S[LinearAlgebra.BandIndex(2,1)] = 1
1182+
end
1183+
11651184
end # module TestTridiagonal

0 commit comments

Comments
 (0)