Automatic multiplication between vector and matrix

前端 未结 4 979
挽巷
挽巷 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")

提交回复
热议问题