Automatic multiplication between vector and matrix

前端 未结 4 980
挽巷
挽巷 2021-01-19 21:52

I have this R code:

> coef
[1] 1.5 2.4 3.9 4.4
> y
     [,1] [,2] [,3] [,4]
[1,]    1    2   12   45
[2,]    5    6    7    8
[3,]    9   10    2   12
         


        
相关标签:
4条回答
  • 2021-01-19 22:16

    Two more possibilities: sweep and scale (the latter only operates columnwise, and seems to me to be a bit of hack).

    coef <- c(1.5,2.4,3.9,4.4)
    y <- matrix(c(seq(1,17,by=4),
                  seq(2,18,by=4),
                  c(12,7,2,15,39,
                    45,8,12,45,7)),
                  ncol=4)
    
    t(t(y)*coef)
    t(apply(y,1,"*",coef))
    sweep(y,2,coef,"*")
    scale(y,center=FALSE,scale=1/coef)
    
    library(rbenchmark)
    
    benchmark(t(t(y)*coef),
               y %*% diag(coef),
               t(apply(y,1,"*",coef)),
               sweep(y,2,coef,"*"),
               scale(y,center=FALSE,scale=1/coef),
               replications=1e4)
    
                                          test replications elapsed relative
    5 scale(y, center = FALSE, scale = 1/coef)        10000   0.990 4.342105
    4                   sweep(y, 2, coef, "*")        10000   0.846 3.710526
    3                t(apply(y, 1, "*", coef))        10000   1.537 6.741228
    1                           t(t(y) * coef)        10000   0.228 1.000000
    2                         y %*% diag(coef)        10000   0.365 1.600877
    

    edit: added y %*% diag(coef) from @baptiste [not fastest, although it might be so for a big problem with a sufficiently optimized BLAS package ...] [and it was fastest in another trial, so I may just not have had a stable estimate]

    edit: fixed typo in t(t(y)*coef) [thanks to Timur Shtatland] (but did not update timings, so they might be slightly off ...)

    I also tried library(Matrix); y %*% Diagonal(x=coef), which is very slow for this example but might be fast for a large matrix (??). (I also tried constructing the diagonal matrix just once, but even multiplication by a predefined matrix was slow in this example (25x slower than the best, vs. 47x slower when defining the matrix on the fly.)

    I have a mild preference for sweep as I think it expresses most clearly the operation being done ("multiply the columns by the elements of coef")

    0 讨论(0)
  • 2021-01-19 22:23
     apply(y, 1, "*", coef)
    #  -- result --    
      [,1] [,2] [,3]  [,4]  [,5]
    [1,]   1.5  7.5 13.5  19.5  25.5
    [2,]   4.8 14.4 24.0  33.6  43.2
    [3,]  46.8 27.3  7.8  58.5 152.1
    [4,] 198.0 35.2 52.8 198.0  30.8
    
    0 讨论(0)
  • 2021-01-19 22:32

    This will give you what you want:

    t( t(y) * coef  )
    
    0 讨论(0)
  • 2021-01-19 22:32

    A late entry:

    coef[col(y)]*y
    

    On my system, this is the fastest.

                                          test replications elapsed relative
    6                         coef[col(y)] * y        10000   0.068    1.000
    5 scale(y, center = FALSE, scale = 1/coef)        10000   0.640    9.412
    4                   sweep(y, 2, coef, "*")        10000   0.535    7.868
    3                t(apply(y, 1, "*", coef))        10000   0.837   12.309
    1                           t(t(y) * coef)        10000   0.176    2.588
    2                         y %*% diag(coef)        10000   0.187    2.750
    
    0 讨论(0)
提交回复
热议问题