Ilya V. Schurov
Ilya V. Schurov

Reputation: 8097

Matrix multiplication on list of two-dimensional arrays in R

I have a list of three two-dimensional arrays that contains x, y and z coordinates of some points (to draw a surface from them, I store them in two-dimensional arrays, like surface plots in MATLAB).

Example:

points <- list(x=matrix(c(1, 2, 3, 4), nrow=2), 
               y=matrix(c(5, 6, 1, 4), nrow=2), 
               z=matrix(c(1, 9, 2, 3), nrow=2))

This is a representation of points with coordinates (1, 5, 1), (2, 6, 9) and so on (4 points total).

Now I have to multiply every (x, y, z) point with some fixed matrix C (to rotate my surface) and return the result in the same form of list of two-dimensional matrixes.

I can do it in this way with loops:

apply_matrix <- function(C, points) {
  x <- points$x
  y <- points$y
  z <- points$z
  n <- nrow(x)
  m <- ncol(x)
  outx <- matrix(rep(0, n*m), nrow = n)
  outy <- matrix(rep(0, n*m), nrow = n)
  outz <- matrix(rep(0, n*m), nrow = n)

  for (i in 1:nrow(x)) {
    for (j in 1:ncol(x)) {
      out <- C %*% c(x[i, j], y[i, j], z[i, j])
      outx[i,j] <- out[1,]
      outy[i,j] <- out[2,]
      outz[i,j] <- out[3,]
    }
  }
  list(x=outx,y=outy,z=outz)
}

However, I'm looking for more efficient loop-free solution.

I believe it is possible to convert the list to three-dimensional matrix and then ask R to multiply my matrix C to this three-dimensional matrix using appropriate dimensions, but cannot figure out how to do it.

Upvotes: 1

Views: 158

Answers (1)

Julius Vainora
Julius Vainora

Reputation: 48251

Here I first convert the list to a three-dimensional array and then also return one:

C <- matrix(rnorm(3 * 3), 3)
ar <- array(unlist(points), c(dim(points[[1]]), 3))
aperm(apply(ar, 1:2, `%*%`, x = t(C)), c(2, 3, 1))

Upvotes: 1

Related Questions