diff --git a/src/LinearAlgebra.jl b/src/LinearAlgebra.jl index 30aa23d0..a2f9e39b 100644 --- a/src/LinearAlgebra.jl +++ b/src/LinearAlgebra.jl @@ -15,7 +15,7 @@ import Base: USE_BLAS64, abs, acos, acosh, acot, acoth, acsc, acsch, adjoint, as IndexStyle, kron, kron!, length, log, map, ndims, one, oneunit, parent, permutecols!, permutedims, permuterows!, power_by_squaring, promote_rule, real, isreal, sec, sech, setindex!, show, similar, sin, sincos, sinh, size, sqrt, strides, stride, tan, tanh, transpose, trunc, - typed_hcat, vec, view, zero + typed_hcat, vec, view, zero, CartesianIndex import Base: AbstractArray, AbstractMatrix, Array, Matrix using Base: IndexLinear, promote_eltype, promote_op, print_matrix, @propagate_inbounds, reduce, typed_hvcat, typed_vcat, require_one_based_indexing, @@ -508,21 +508,29 @@ struct BandIndex band :: Int index :: Int end -function _cartinds(b::BandIndex) +function _torowcol(b::BandIndex) (; band, index) = b - bandg0 = max(band,0) - row = index - band + bandg0 - col = index + bandg0 - CartesianIndex(row, col) + minband0, maxband0 = minmax(band,0) + row = index - minband0 + col = index + maxband0 + row, col end -function Base.to_indices(A, inds, t::Tuple{BandIndex, Vararg{Any}}) - to_indices(A, inds, (_cartinds(first(t)), Base.tail(t)...)) +CartesianIndex(b::BandIndex) = CartesianIndex{2}(b) +CartesianIndex{2}(b::BandIndex) = CartesianIndex{2}(_torowcol(b)) +function BandIndex(c::CartesianIndex{2}) + row, col = Tuple(c) + band = col - row + index = min(row, col) + BandIndex(band, index) +end +function Base.to_indices(A, inds, t::Tuple{BandIndex, Vararg}) + to_indices(A, inds, (_torowcol(first(t))..., Base.tail(t)...)) end function Base.checkbounds(::Type{Bool}, A::AbstractMatrix, b::BandIndex) - checkbounds(Bool, A, _cartinds(b)) + checkbounds(Bool, A, _torowcol(b)...) end function Base.checkbounds(A::Broadcasted, b::BandIndex) - checkbounds(A, _cartinds(b)) + checkbounds(A, CartesianIndex(b)) end include("adjtrans.jl") diff --git a/src/structuredbroadcast.jl b/src/structuredbroadcast.jl index 2c1e7bfa..f2cfc74a 100644 --- a/src/structuredbroadcast.jl +++ b/src/structuredbroadcast.jl @@ -194,7 +194,7 @@ isvalidstructbc(dest::Bidiagonal, bc::Broadcasted{StructuredMatrixStyle{Bidiagon @inbounds Broadcast._broadcast_getindex(bc, b) end -Broadcast.newindex(A, b::BandIndex) = Broadcast.newindex(A, _cartinds(b)) +Broadcast.newindex(A, b::BandIndex) = Broadcast.newindex(A, CartesianIndex(b)) function Broadcast.newindex(A::StructuredMatrix, b::BandIndex) # we use the fact that a StructuredMatrix is square, # and we apply newindex to both the axes at once to obtain the result diff --git a/test/special.jl b/test/special.jl index a337983c..aaad97b3 100644 --- a/test/special.jl +++ b/test/special.jl @@ -764,6 +764,12 @@ end end @test_throws BoundsError D[BandIndex(size(D,1),1)] end + @testset "BandIndex to CartesianIndex" begin + b = BandIndex(1, 2) + c = CartesianIndex(b) + @test c == CartesianIndex(2, 3) + @test BandIndex(c) == b + end end @testset "Partly filled Hermitian and Diagonal algebra" begin