2015-11-10 2 views
12

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

Так что, если у меня есть матрица М:

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() для другой диагонали).

+2

Это называется "вторичным" или "незначительные" диагонали. – Benjamin

ответ

15

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

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) является Contant по всем анти-диагоналей. Для такого обобщения было бы удобнее записать часть в пределах 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)]) - это сумма поддиапазона.

+0

Спасибо за это. Некоторые из синтаксиса находятся вне меня, поэтому мне нужно будет проделать через вас очень тщательные и хорошо продуманные примеры. – Windstorm1981

4

Вы могли бы индекс из элементов, которые вы хотите, чтобы подвести

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

Спасибо. Это на самом деле то, что я представлял, но не мог понять, как его написать. Я возился с вложенным циклом «за», который, очевидно, не дал мне то, что я хотел. – Windstorm1981

2

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

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

Спасибо.Это очень просто и понятно. – Windstorm1981

2

Это иногда называют «вторичной диагональю» или «второстепенной диагональю».

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

sum(diag(apply(m,2,rev))) 
Смежные вопросы