Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions src/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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}}`.
Expand All @@ -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}:
Expand All @@ -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.
"""
Expand All @@ -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)

Expand Down