# mxmult.r         common pitfall in matrix multiplication
#                  September 2008, revised September 2009
#
# clean up workspace
rm( list=ls() )
# slr design matrix X
X <- cbind( rep(1,6), (1:6) )
X
##      [,1] [,2]
## [1,]    1    1
## [2,]    1    2
## [3,]    1    3
## [4,]    1    4
## [5,]    1    5
## [6,]    1    6
# weight vector w
w <- sqrt( (1:6) )          # just so they're different
w
## [1] 1.000 1.414 1.732 2.000 2.236 2.449
# weight matrix
W <- diag(w)
# now (X'inv(W) X) four ways:
#   first          correct, but slow, W takes lots of space
W <- diag(w)
xwx1 <- t(X) %*% solve(W) %*% X      
xwx1
##       [,1]  [,2]
## [1,]  3.64 10.83
## [2,] 10.83 42.90
#   second         correct, less slow, takes lots of space 
xwx2 <- t(X) %*% diag(1/w) %*% X    
xwx2
##       [,1]  [,2]
## [1,]  3.64 10.83
## [2,] 10.83 42.90
#   third          wrong, but faster -- recycles w wrong
xwx3 <- ( t(X) / w ) %*% X           # *****wrong*****
xwx3
##        [,1]  [,2]
## [1,]  4.049 13.07
## [2,] 10.710 44.89
#   fourth         correct, but looks wrong
xwx4 <- t(X) %*% (X/w)               # uses recycling correctly, fast
xwx4
##       [,1]  [,2]
## [1,]  3.64 10.83
## [2,] 10.83 42.90
#                  looks different but same execution
crossprod(X,X/w)                     # correct, fast
##       [,1]  [,2]
## [1,]  3.64 10.83
## [2,] 10.83 42.90
# done
rm( list=ls() )
# q()