diff --git a/src/dense.jl b/src/dense.jl index 5fa28f85..25597369 100644 --- a/src/dense.jl +++ b/src/dense.jl @@ -237,22 +237,14 @@ end fillstored!(A::AbstractMatrix, v) = fill!(A, v) -diagind(m::Integer, n::Integer, k::Integer=0) = diagind(IndexLinear(), m, n, k) -diagind(::IndexLinear, m::Integer, n::Integer, k::Integer=0) = - k <= 0 ? range(1-k, step=m+1, length=min(m+k, n)) : range(k*m+1, step=m+1, length=min(m, n-k)) - -function diagind(::IndexCartesian, m::Integer, n::Integer, k::Integer=0) - Cstart = CartesianIndex(1 + max(0,-k), 1 + max(0,k)) - Cstep = CartesianIndex(1, 1) - length = max(0, k <= 0 ? min(m+k, n) : min(m, n-k)) - StepRangeLen(Cstart, Cstep, length) -end - """ diagind(M::AbstractMatrix, k::Integer = 0, indstyle::IndexStyle = IndexLinear()) diagind(M::AbstractMatrix, indstyle::IndexStyle = IndexLinear()) + diagind(::IndexStyle, m::Integer, n::Integer, k::Integer = 0) + diagind(m::Integer, n::Integer, k::Integer = 0) -An `AbstractRange` giving the indices of the `k`th diagonal of the matrix `M`. +An `AbstractRange` giving the indices of the `k`th diagonal of a matrix, +specified either by the matrix `M` itself or by its dimensions `m` and `n`. Optionally, an index style may be specified which determines the type of the range returned. If `indstyle isa IndexLinear` (default), this returns an `AbstractRange{Integer}`. On the other hand, if `indstyle isa IndexCartesian`, this returns an `AbstractRange{CartesianIndex{2}}`. @@ -262,6 +254,7 @@ If `k` is not provided, it is assumed to be `0` (corresponding to the main diago See also: [`diag`](@ref), [`diagm`](@ref), [`Diagonal`](@ref). # Examples +The matrix itself may be passed to `diagind`: ```jldoctest julia> A = [1 2 3; 4 5 6; 7 8 9] 3×3 Matrix{Int64}: @@ -276,6 +269,18 @@ julia> diagind(A, IndexCartesian()) StepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 3) ``` +Alternatively, dimensions `m` and `n` may be passed to get the diagonal of an `m×n` matrix: +```jldoctest +julia> m, n = 5, 7 +(5, 7) + +julia> diagind(m, n, 2) +11:6:35 + +julia> diagind(IndexCartesian(), m, n) +StepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 5) +``` + !!! compat "Julia 1.11" Specifying an `IndexStyle` requires at least Julia 1.11. """ @@ -286,6 +291,17 @@ end diagind(A::AbstractMatrix, indexstyle::IndexStyle) = diagind(A, 0, indexstyle) +function diagind(::IndexCartesian, m::Integer, n::Integer, k::Integer=0) + Cstart = CartesianIndex(1 + max(0,-k), 1 + max(0,k)) + Cstep = CartesianIndex(1, 1) + length = max(0, k <= 0 ? min(m+k, n) : min(m, n-k)) + StepRangeLen(Cstart, Cstep, length) +end + +diagind(::IndexLinear, m::Integer, n::Integer, k::Integer=0) = + k <= 0 ? range(1-k, step=m+1, length=min(m+k, n)) : range(k*m+1, step=m+1, length=min(m, n-k)) +diagind(m::Integer, n::Integer, k::Integer=0) = diagind(IndexLinear(), m, n, k) + """ diag(M, k::Integer=0)