Reputation: 8097
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
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