I'm trying to sum the elements along the antidiagonal (secondary diagonal, minor diagonal) of a matrix.
So, if I have a matrix m:
m <- matrix(c(2, 3, 1, 4, 2, 5, 1, 3, 7), 3)
m
[,1] [,2] [,3]
[1,] 2 4 1
[2,] 3 2 3
[3,] 1 5 7
I'm looking for the sum m[3, 1] + m[2, 2] + m[1, 3]
, i.e. 1 + 2 + 1
I can't figure out how to set up an iteration. As far as I know there is no function for this (like diag()
for the other diagonal).
This is sometimes called the "secondary diagonal" or "minor diagonal".
Another short solution:
You could index out the elements you want to sum
Here is a simple way without using a loop, assuming that your matrix is m:
Using
1) Reverse the rows as shown (or the columns - not shown), take the diagonal and sum:
2) or use
row
andcol
like this:This generalizes to other anti-diagonals since
row(m) + col(m) - nrow(m)
is contant along all anti-diagonals. For such a generalization it might be more convenient to write the part withinc(...)
asrow(m) + col(m) - nrow(m) - 1 == 0
since then replacing 0 with -1 uses the superdiagonal and with +1 uses the subdiagonal. -2 and 2 use the second superdiagonal and subdiagonal respectively and so on.3) or use this sequence of indexes:
4) or use
outer
like this:This one generalizes nicely to other anti-diagonals too as
outer(1:n, n:1, "-")
is constant along anti-diagonals. We can write the part within [...] asouter(1:n, n:1) == 0
and if we replace 0 with -1 we get the super anti-diagonal and with +1 we get the sub anti-diagonal. -2 and 2 give the super super and sub sub antidiagonals. For examplesum(m[c(outer(1:n, n:1, "-") == 1)])
is the sum of the sub anti-diagonal.