Search code examples
rapplydimensionsscanning

Multiply each dimension of an array by a different value


I have an array of 3 dimensions (a), the length of the 3rd dimension being equals to 2. I also have a vector (MU.A) of length 2.

> dx <- dy <- 0.25
> nx=ny=1/dx
> nz=2

> a <- array(rep(c(3,4,0,1),each=nx*ny/2), dim=c(nx,ny,nz))
> a
, , 1
     [,1] [,2] [,3] [,4]
[1,]    3    3    4    4
[2,]    3    3    4    4
[3,]    3    3    4    4
[4,]    3    3    4    4

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

> MU.A=seq(from=0.2,to=0.8,by=0.6/(nz-1))
> MU.A
[1] 0.2 0.8

I would like to multiply a[ , ,1] by MU.A[1] ; a[ , ,2] by MU.A[2] ; and so on if my objects are bigger. I have found a way to do it but I'm not sure it's the best/fastest way:

> array(mapply('*',a,rep(MU.A,each=nx*ny)),dim=c(nx,ny,nz))
, , 1

     [,1] [,2] [,3] [,4]
[1,]  0.6  0.6  0.8  0.8
[2,]  0.6  0.6  0.8  0.8
[3,]  0.6  0.6  0.8  0.8
[4,]  0.6  0.6  0.8  0.8

, , 2

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

Is there a simplest way to do that ?


Solution

  • The probably most efficient (this depends on the size of the problem) way uses vector recycling. For this you only need to permute the array dimensions so that the third dimension becomes the first, multiply, and then permute the dimensions back:

    aperm(aperm(a, c(3, 1, 2)) * MU.A, c(2, 3, 1))