Home > Software engineering >  How to find the sum of all anti-diagonals?
How to find the sum of all anti-diagonals?

Time:03-24

I have a matrix M:

n = 3    
x=c(0.85, 0.1, 0.05)
M <- matrix(NA, n, n); 

for(i in 1:n){
for(j in 1:n){
M[i,j] = x[i] * x[j]
}}

#       [,1]  [,2]   [,3]
# [1,] 0.7225 0.085 0.0425
# [2,] 0.0850 0.010 0.0050
# [3,] 0.0425 0.005 0.0025

I need to find the sum of all anti-diagonals include M[1,1] and M[n, n]. My attemp is

d <-matrix(c(0, 1, 2, 1, 2, 3, 2, 3, 4), n)
tapply(M, d, sum)

     0      1      2      3      4 
0.7225 0.1700 0.0950 0.0100 0.0025 

The result is correct for me.

Question. How to define the entries of matrix d? May be as function over col(M) and row(M).

CodePudding user response:

You could do:

sapply(seq(3), function(x) seq(3)   x - 2)
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    1    2    3
#> [3,]    2    3    4

Or more generally,

anti_diagonal <- function(n) sapply(seq(n), function(x) seq(n)   x - 2)

For example:

anti_diagonal(6)
#>      [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,]    0    1    2    3    4    5
#> [2,]    1    2    3    4    5    6
#> [3,]    2    3    4    5    6    7
#> [4,]    3    4    5    6    7    8
#> [5,]    4    5    6    7    8    9
#> [6,]    5    6    7    8    9   10

CodePudding user response:

First note that outer can produce the matrix d without explicitly listing its elements.

matrix(c(0, 1, 2, 1, 2, 3, 2, 3, 4), 3)
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    1    2    3
#> [3,]    2    3    4
outer(0:2, 0:2, ` `)
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    1    2    3
#> [3,]    2    3    4

Created on 2022-03-24 by the reprex package (v2.0.1)

And use it in a function.

sumAntiDiag <- function(M){
  nr <- nrow(M)
  nc <- ncol(M)
  d <- outer(seq.int(nr), seq.int(nc), ` `)
  tapply(M, d, sum)
}

n <- 3    
x <- c(0.85, 0.1, 0.05)
M <- matrix(NA, n, n); 

for(i in 1:n){
  for(j in 1:n){
    M[i,j] = x[i] * x[j]
  }}

sumAntiDiag(M)
#>      2      3      4      5      6 
#> 0.7225 0.1700 0.0950 0.0100 0.0025

Created on 2022-03-24 by the reprex package (v2.0.1)

CodePudding user response:

As you mention in your question, rom(M) and col(M) can be used, although they start rows/columns at 1 rather than zero, so you need to subtract 2 (1 for each) giving:

tapply(M, row(M)   col(M) - 2, sum)
#     0      1      2      3      4 
#0.7225 0.1700 0.0950 0.0100 0.0025

CodePudding user response:

You can use sequence:

function(n) matrix(sequence(rep(n, n), seq(n) - 1), nrow = n)

output

f <- function(n) matrix(sequence(rep(n, n), seq(n) - 1), nrow = n)
f(3)
     [,1] [,2] [,3]
[1,]    0    1    2
[2,]    1    2    3
[3,]    2    3    4

f(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    2    3    4
[2,]    1    2    3    4    5
[3,]    2    3    4    5    6
[4,]    3    4    5    6    7
[5,]    4    5    6    7    8

CodePudding user response:

Try the code below by defining a function f using embed from base R, i.e.,

f <- function(n) embed(seq(2 * n - 1) - 1, n)[, n:1]

such that

> f(3)
     [,1] [,2] [,3]
[1,]    0    1    2
[2,]    1    2    3
[3,]    2    3    4

> f(4)
     [,1] [,2] [,3] [,4]
[1,]    0    1    2    3
[2,]    1    2    3    4
[3,]    2    3    4    5
[4,]    3    4    5    6

> f(5)
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    2    3    4
[2,]    1    2    3    4    5
[3,]    2    3    4    5    6
[4,]    3    4    5    6    7
[5,]    4    5    6    7    8
  • Related