Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sum of antidiagonal of a matrix

Tags:

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).

like image 377
Windstorm1981 Avatar asked Nov 10 '15 01:11

Windstorm1981


People also ask

What is the sum of diagonal elements of a matrix?

Description. b = trace( A ) calculates the sum of the diagonal elements of matrix A : tr ( A ) = ∑ i = 1 n a i i = a 11 + a 22 + ... + a n n .

How do you find the diagonal sum?

Calculate the sums across the two diagonals of a square matrix. Along the first diagonal of the matrix, row index = column index i.e mat[i][j] lies on the first diagonal if i = j. Along the other diagonal, row index = n – 1 – column index i.e mat[i][j] lies on the second diagonal if i = n-1-j.

What is the off diagonal of a matrix?

In a table of numbers that has the same number of rows as columns, the entries that are not in the Main Diagonal are referred to as the off-diagonal entries in the table. In this example, all the 0s are in the off-diagonal cells.


1 Answers

Using

m <- matrix(c(2, 3, 1, 4, 2, 5, 1, 3, 7), 3)

1) Reverse the rows as shown (or the columns - not shown), take the diagonal and sum:

sum(diag(m[nrow(m):1, ]))
## [1] 4

2) or use row and col like this:

sum(m[c(row(m) + col(m) - nrow(m) == 1)])
## [1] 4

This generalizes to other anti-diagonals since row(m) + col(m) - nrow(m) is constant along all anti-diagonals. For such a generalization it might be more convenient to write the part within c(...) as row(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:

n <- nrow(m)
sum(m[seq(n, by = n-1, length = n)])
## [1] 4

4) or use outer like this:

n <- nrow(m)
sum(m[!c(outer(1:n, n:1, "-"))])
## [1] 4

This one generalizes nicely to other anti-diagonals too as outer(1:n, n:1, "-") is constant along anti-diagonals. We can write m[outer(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 example sum(m[c(outer(1:n, n:1, "-") == 1)]) is the sum of the sub anti-diagonal.

like image 72
G. Grothendieck Avatar answered Sep 30 '22 06:09

G. Grothendieck