# How to query elements in a matrix diagonal to a given point

**URL:** <https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253>\
**Category:** Numerics\
**Tags:** linearalgebra\
**Created:** [May 11, 2020, 1:26am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253 "2020-05-11T01:26:34Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [May 11, 2020, 1:26am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/1 "2020-05-11T01:26:34Z")

</div>

I’m wondering if there’s an efficient way to return all of the elements in a matrix that are diagonal to some starting point. For example, given the following matrix:

```julia
julia> A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
4×4 Array{Int64,2}:
  1 2 3 4
  5 6 7 8
  9 10 11 12
 13 14 15 16

```

If I want to query the matrix to return all elements that are diagonal to the number 7 (so `A[2,3]`), I should get back `[2, 12, 4, 10, 13]`. If I query the matrix at point `A[4,4]` (where 16 is), I would want to get back `[1,6,11]`.

Is there a package that already does something like this or is this going to take a custom function?

EDIT: The matrices that I need this for will always be square

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 11, 2020, 1:32am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/2 "2020-05-11T01:32:58Z")

</div>

How about `Diagonal(A)`? You will need to put `using LinearAlgebra` first to bring in the package. In general, you might want to read [Linear Algebra · The Julia Language](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/index.html)

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [May 11, 2020, 1:36am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/3 "2020-05-11T01:36:48Z")

</div>

> [@Oscar\_Smith](#):
>
> How about `Diagonal(A)` ? You will need to put `using LinearAlgebra` first to bring in the package. In general, you might want to read [Linear Algebra · The Julia Language](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/index.html)

Hi Oscar. So it looks like this simply converts my matrix into a `Diagonal` matrix, keeping only the main diagonal. Am I missing something here? Can I use this to get all elements that are diagonal and anti-diagonal to some specific point?

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [May 11, 2020, 1:36am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/4 "2020-05-11T01:36:56Z")

</div>

I think you are definitely going to need to write your own function for that.

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [May 11, 2020, 1:38am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/5 "2020-05-11T01:38:04Z")

</div>

> I think you are definitely going to need to write your own function for that.

This won’t be happening at this hour on a Sunday night 😆 I’ll take a crack at it tomorrow and if I come up with something decent I’ll post here 😀

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 11, 2020, 1:38am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/6 "2020-05-11T01:38:44Z")

</div>

Oh, sorry, I misread your question.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [May 11, 2020, 1:55am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/7 "2020-05-11T01:55:21Z")

</div>

Does this work? It’s not optimized, but should be decent

```
function diagonals(A::Matrix{T},i,j) where T
       s = size(A)
       out = Vector{T}()
       for row in 1:s[1]
           if i == row
               continue
           end
           col1 = j - (i-row)
           if 1 <= col1 <= s[2]
               append!(out, A[row,col1])
           end
           col2 = j + (i-row)
           if 1 <= col2 <= s[2]
               append!(out, A[row,col2])
           end
       end
       return out
   end

```

---

<div class="post-metadata">

**Author:** ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)\
**Post date:** [May 11, 2020, 7:15am UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/8 "2020-05-11T07:15:13Z")

</div>

Might make sense to exploit the strideness:

```julia
julia> function diagonals(A, i, j)
          n = size(A,1)
          s = (j-1)*n + i
          [A[s-(n+1):-(n+1):begin]; A[s+(n+1):(n+1):end]; A[s+(n-1):(n-1):end-1]; A[s-(n-1):-(n-1):begin+1]]
       end
diagonals (generic function with 1 method)

julia> diagonals(A, 2,3)
5-element Array{Int64,1}:
  2
 12
  4
 10
 13

```

Though the code still needs to be fixed for edge cases:

```julia
julia> diagonals(A,4,4) # this is wrong
7-element Array{Int64,1}:
 11
  6
  1
  4
  7
 10
 13

```

---

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [May 11, 2020, 5:13pm UTC](https://discourse.julialang.org/t/how-to-query-elements-in-a-matrix-diagonal-to-a-given-point/39253/9 "2020-05-11T17:13:56Z")

</div>

Alright, here’s what I came up with. It performs horrendously compared to either of the solutions posted by @Oscar_Smith and @dlfivefifty and it deviates a bit from the stated objective as it returns two different vectors, both of which include the element at the query starting point. About the only thing that it has going for it is that it’s a one-liner:

```julia
diagonals(A, i, j) = diag(A,j-i), diag(reverse(A,dims=1),(i+j)-(size(A,1)+1))

julia> A = [1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
4×4 Array{Int64,2}:
  1 2 3 4
  5 6 7 8
  9 10 11 12
 13 14 15 16

julia> diagonals(A,3,4)
([2, 7, 12], [15, 12])

julia> diagonals(A,2,2)
([1, 6, 11, 16], [9, 6, 3])

```
