Сумма антидиагональной матрицы

Я пытаюсь суммировать элементы по антидиагональной (вторичной диагонали, малой диагонали) матрицы.

Итак, если у меня есть матрица 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

Я ищу сумму m[3, 1] + m[2, 2] + m[1, 3], т.е. 1 + 2 + 1

Я не могу понять, как настроить итерацию. Насколько я знаю, для этой функции нет функции (например, diag() для другой диагонали).

Ответ 1

Использование

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

1) Переверните строки, как показано (или столбцы - не показаны), возьмите диагональ и сумму:

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

2) или используйте row и col так:

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

Это обобщает для других антидиагоналей, поскольку row(m) + col(m) - nrow(m) является постоянным по всем антидиагоналам. Для такого обобщения было бы удобнее записать деталь в c(...) как row(m) + col(m) - nrow(m) - 1 == 0, так как тогда замена 0 на -1 использует супердиагональ, а с +1 использует субдиагональ. -2 и 2 используют второй супердиагональный и субдиагональный соответственно и т.д.

3) или используйте эту последовательность индексов:

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

4) или используйте outer следующим образом:

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

Этот принцип хорошо подходит и для других антидиагоналей, так как outer(1:n, n:1, "-") постоянен вдоль антидиагоналей. Мы можем записать часть в [...] как outer(1:n, n:1) == 0, и если мы заменим 0 на -1, мы получим супер-антидиагональ, а с +1 мы получим суб-антидиагональ. -2 и 2 дают супер-супер и суб-субдиагидоналы. Например, sum(m[c(outer(1:n, n:1, "-") == 1)]) является суммой субдиагонализы.

Ответ 2

Вы можете индексировать элементы, которые вы хотите суммировать

sum(m[cbind(3:1, 1:3)])

Ответ 3

Вот простой способ без использования цикла, предполагая, что ваша матрица равна m:

sum(diag(matrix(c(m[,3],m[,2],m[,1]), nrow=3)))

Ответ 4

Это иногда называют "вторичной диагональю" или "малой диагональю".

Еще одно короткое решение:

sum(diag(apply(m,2,rev)))