Home > Blockchain >  Transform Identity Matrix
Transform Identity Matrix

Time:12-24

I have identity matrix which can be generated via diag(5)

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    1    0    0    0
[3,]    0    0    1    0    0
[4,]    0    0    0    1    0
[5,]    0    0    0    0    1

I want to convert it to the matrix wherein series starts after 1. For example 1st column, values 1 through 5. Second column - values 1 through 4.

Desired Output

    [,1] [,2] [,3] [,4] [,5]
[1,]    1   0   0   0   0
[2,]    2   1   0   0   0
[3,]    3   2   1   0   0
[4,]    4   3   2   1   0
[5,]    5   4   3   2   1

CodePudding user response:

Try the code below (given m <- diag(5))

> (row(m) - col(m)   1)*lower.tri(m,diag = TRUE)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    2    1    0    0    0
[3,]    3    2    1    0    0
[4,]    4    3    2    1    0
[5,]    5    4    3    2    1

Another option is using apply cumsum

> apply(lower.tri(m, diag = TRUE), 2, cumsum)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    2    1    0    0    0
[3,]    3    2    1    0    0
[4,]    4    3    2    1    0
[5,]    5    4    3    2    1

CodePudding user response:

One option could be:

x <- 1:5
embed(c(rep(0, length(x) - 1), x), length(x))

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    2    1    0    0    0
[3,]    3    2    1    0    0
[4,]    4    3    2    1    0
[5,]    5    4    3    2    1

CodePudding user response:

1) If d <- diag(5) is the identity matrix then:

pmax(row(d) - col(d)   1, 0)

giving:

     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    2    1    0    0    0
[3,]    3    2    1    0    0
[4,]    4    3    2    1    0
[5,]    5    4    3    2    1

2) This alternative is longer but also works if the columns of d are rearranged. For example,

dd <- d[, 5:1] # test data 
pmax(row(dd) - rep(max.col(t(dd)), each = nrow(dd))   1, 0)

giving the same result for d and this for dd:

     V1 V2 V3 V4 V5
[1,]  0  0  0  0  1
[2,]  0  0  0  1  2
[3,]  0  0  1  2  3
[4,]  0  1  2  3  4
[5,]  1  2  3  4  5

CodePudding user response:

A solution based on nested cumsum:

n <- 5
m <- diag(n)

apply(m, 2, function(x) cumsum(cumsum(x)))

#>      [,1] [,2] [,3] [,4] [,5]
#> [1,]    1    0    0    0    0
#> [2,]    2    1    0    0    0
#> [3,]    3    2    1    0    0
#> [4,]    4    3    2    1    0
#> [5,]    5    4    3    2    1
  • Related