Search code examples
arraysrmatrixmultiplication

Array multiplied by individual rows in matrix


I have a 6,6,51 array and a 51,6 matrix. I want to multiply row 1 of matrix 1 in the array, by row 1 in the matrix and then store this as a result. I'd like to do this again for each row in each matrix contained in the array. So i'd take the second row of the 1st matrix in the array and multiply it by the first row of the matrix. Once I've cycled through all 6 rows of the first matrix in the array, I'd like to do the exact same thing on the remaining 50 matrices in the array.

To aid in the exposition of what I'm asking I'll give a shortened example using a 6,6,3 array and a 3,6 matrix. I'll make up some numbers so it's easier to look at:

array1 <- array(1:108, c(6,6,3))

 [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    7   13   19   25   31
[2,]    2    8   14   20   26   32
[3,]    3    9   15   21   27   33
[4,]    4   10   16   22   28   34
[5,]    5   11   17   23   29   35
[6,]    6   12   18   24   30   36

, , 2

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   37   43   49   55   61   67
[2,]   38   44   50   56   62   68
[3,]   39   45   51   57   63   69
[4,]   40   46   52   58   64   70
[5,]   41   47   53   59   65   71
[6,]   42   48   54   60   66   72

, , 3

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   73   79   85   91   97  103
[2,]   74   80   86   92   98  104
[3,]   75   81   87   93   99  105
[4,]   76   82   88   94  100  106
[5,]   77   83   89   95  101  107
[6,]   78   84   90   96  102  108

matrix1 <- matrix(1:18, nrow = 3, ncol = 6)

   [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    4    7   10   13   16
[2,]    2    5    8   11   14   17
[3,]    3    6    9   12   15   18

Essentially I'd like to do this:

row1 of matrix 1 in array1 x row1 of matrix1

1*1 + 7*4 + 13*7 + 19*10 +25*13 + 31*16 = result

then do row2 of matrix1 in array1 x row1 of matrix1

etc etc up until row 6 of matrix1 in array1

then repeat on matrix 2 of array1 using row2 of matrix1

Is this intelligible?

If so can someone help?

Alternatively, is there a way to split matrix1 into vectors? So I could just get 51 separate vectors to multiply against each array?

Regards


Solution

  • Ok, as I'm still not sure if you mean 6 x 3 matrix or 6 x 6 matrix, here comes a solution for both cases (similar to my comment):

    Rows <- min(dim(array1)[1], dim(matrix1)[1])
    Cols <- min(dim(array1)[2], dim(matrix1)[2])
    
    apply(array1, 3, function(x) rowSums(matrix1 * x[1:Rows,1:Cols]))
    

    Further rows and columns of array1 not fitting to matrix1 are ignored then.

    A short explanation how to get to the solution: Take the first plane of the array and experiment to get the desired solution.

    array1[ , , 1] * matrix1 #or array1[1:Rows, 1:Cols, 1] * matrix1
    

    rowSums gives, as expected by it's name, the sum of each row. So the result for the first plane in the array multiplied with the matrix and summarised is a vector.

    rowSums(array1[1:Rows, 1:Cols, 1] * matrix1)
    # 1131 1284 1449
    

    The result seems to be correct, now we can apply that solution on every matrix of the array as shown in the very top of the answer.