I am currently trying to efficiently implement a new square matrix, M, as a function of two square matrices of the same dimension, W and V, as follows: Fij = Wii·Vji. I.e., the ith row of F is the ith diagonal element of W times the ith column of V.
There is a function in R, sweep
, that allows one to sweep a statistic across a margin of an array. I.e., doing
mean.att <- apply(attitude, 2, mean)
sweep(data.matrix(attitude), 2, mean.att)
will de-mean the columns (2nd dimension) of the attitude
matrix (taken from the help). Also, one can supply a function, like FUN="*"
. In this case, the columns of attitude
matrix will be multiplied by their respective medians.
So the intended code to produce the matrix F would be
Fij <- matrix(NA, ncol=N, nrow=N)
for (i in 1:N) {
Fij[i, ] <- w[i, i] * v[, i]
}
Apparently, since the forte of R is vectorisation, this can be done with a sweep operation: I want to multiply the columns (FUN="*"
) of V by the diagonal of W, i.e.
Fij2 <- sweep(v, 2, diag(w), FUN="*")
However, whenever I check if Fij==Fij2
, they are not!
MWE:
set.seed(1)
w <- matrix(rnorm(16), nrow=4)
v <- matrix(rnorm(16), nrow=4)
Fij <- matrix(NA, ncol=4, nrow=4)
for (i in 1:4) { # This loop can and should be vectorised
Fij[i, ] <- w[i, i] * v[, i]
}
Fij2 <- sweep(v, 2, diag(w), FUN="*")
Fij
Fij2
The diagonal elements are equal, but the off-diagonal ones are not.
I should be very grateful if someone clarified which of the implementations of Fij is false!