creating a triangular matrix

后端 未结 4 691
有刺的猬
有刺的猬 2020-12-15 08:04

There must an elegant way to do this but I can\'t figure out so:

Columns are probabilities from 1 to 0 going right

Rows are probabilities from 0 to 1 going d

4条回答
  •  忘掉有多难
    2020-12-15 08:38

    A slightly different solution, close in style to @DWin's:

    Create a matrix with the appropriate lower triangle (I don't think the rounding is strictly necessary, but otherwise the floating point error makes it look awful):

    mat <- round(outer(seq(-0.5, 0.5, 0.1), seq(-0.5, 0.5, 0.1), `+`), 1)
    mat
    
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
     [1,] -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2  -0.1   0.0
     [2,] -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1   0.0   0.1
     [3,] -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1  0.0   0.1   0.2
     [4,] -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1  0.0  0.1   0.2   0.3
     [5,] -0.6 -0.5 -0.4 -0.3 -0.2 -0.1  0.0  0.1  0.2   0.3   0.4
     [6,] -0.5 -0.4 -0.3 -0.2 -0.1  0.0  0.1  0.2  0.3   0.4   0.5
     [7,] -0.4 -0.3 -0.2 -0.1  0.0  0.1  0.2  0.3  0.4   0.5   0.6
     [8,] -0.3 -0.2 -0.1  0.0  0.1  0.2  0.3  0.4  0.5   0.6   0.7
     [9,] -0.2 -0.1  0.0  0.1  0.2  0.3  0.4  0.5  0.6   0.7   0.8
    [10,] -0.1  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7   0.8   0.9
    [11,]  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8   0.9   1.0
    

    Reverse the columns

    mat <- mat[,rev(seq.int(ncol(mat)))]
    

    Remove the upper triangle:

    mat[upper.tri(mat)] <- NA
    

    Re-reverse the columns:

    mat <- mat[,rev(seq_len(ncol(mat)))]
    mat
    
          [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
     [1,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA   0.0
     [2,]   NA   NA   NA   NA   NA   NA   NA   NA   NA   0.0   0.1
     [3,]   NA   NA   NA   NA   NA   NA   NA   NA  0.0   0.1   0.2
     [4,]   NA   NA   NA   NA   NA   NA   NA  0.0  0.1   0.2   0.3
     [5,]   NA   NA   NA   NA   NA   NA  0.0  0.1  0.2   0.3   0.4
     [6,]   NA   NA   NA   NA   NA  0.0  0.1  0.2  0.3   0.4   0.5
     [7,]   NA   NA   NA   NA  0.0  0.1  0.2  0.3  0.4   0.5   0.6
     [8,]   NA   NA   NA  0.0  0.1  0.2  0.3  0.4  0.5   0.6   0.7
     [9,]   NA   NA  0.0  0.1  0.2  0.3  0.4  0.5  0.6   0.7   0.8
    [10,]   NA  0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7   0.8   0.9
    [11,]    0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8   0.9   1.0
    

    You can change the rownames from there.

    EDIT: Given there are so many solutions, you may be interested to see how they benchmark. Using microbenchmark:

    Unit: microseconds
       expr       min         lq     median         uq       max
    1 AGS()   682.491   738.9370   838.0955   892.8815  4518.740
    2  DW()    23.244    27.1680    31.3930    34.8650    70.937
    3 MvG() 15469.664 15920.4820 17352.3215 17827.4380 18989.270
    4  SC()   118.629   131.4575   144.1360   157.7190   631.779
    

    @DWin's solution appears to be the fastest by quite a margin.

提交回复
热议问题