[R] eliminate t() and %*% using crossprod() and solve(A,b)

Robin Hankin r.hankin at noc.soton.ac.uk
Wed Oct 5 15:08:05 CEST 2005


On 5 Oct 2005, at 12:15, Dimitris Rizopoulos wrote:

> Hi Robin,
>
> I've been playing with your question, but I think these two lines  
> are not equivalent:
>
> N <- 1000
> n <- 4
> Ainv <- matrix(rnorm(N * N), N, N)
> H <- matrix(rnorm(N * n), N, n)
> d <- rnorm(N)
> quad.form <- function (M, x){
>         jj <- crossprod(M, x)
>         return(drop(crossprod(jj, jj)))
> }
>
>
> X0 <- solve(t(H) %*% Ainv %*% H) %*% t(H) %*% Ainv %*% d
> X1 <- solve(quad.form(Ainv, H), crossprod(crossprod(Ainv, H), d))
> all.equal(X0, X1) # not TRUE
>
>
> which is the one you want to compute?
>


These are not exactly equivalent, but:


Ainv <- matrix(rnorm(1e6),1e3,1e3)
H <- matrix(rnorm(4000),ncol=4)
d <- rnorm(1000)

X0 <- solve(t(H) %*% Ainv %*% H) %*% t(H) %*% Ainv %*% d
X1 <- solve(quad.form(Ainv, H), crossprod(crossprod(Ainv, H), d))
X0 - X1
               [,1]
[1,]  4.884981e-15
[2,]  3.663736e-15
[3,] -5.107026e-15
[4,]  5.717649e-15

which is pretty close.



On 5 Oct 2005, at 12:50, Prof Brian Ripley wrote:
>
>> QUESTION:
>>
>> how  to calculate
>>
>> H %*% X
>>
>> in the recommended crossprod way?  (I don't want to take a transpose
>> because t() is expensive, and I know that %*% is slow).
>>
>
> Have you some data to support your claims?  Here I find (for random
> matrices of the dimensions given on a machine with a fast BLAS)
>
>

I couldn't supply any performance data because I couldn't figure out the
correct R commands to calculate H %*% X  without using %*% or t()!

I was just wondering if there were a way to calculate

H %*% solve(t(H) %*% Ainv %*% H) %*% t(H) %*% Ainv %*% d

without using t() or %*%.  And there doesn't seem to be (my original
question didn't make it clear that I don't have X precalculated).

My take-home lesson from Brian Ripley is that H %*% X is fast
--but this is only useful to me if one has X precalculated, and in
general I don't.   But this discussion suggests to me that it might be
a good idea to change my routines and calculate X anyway.

thanks again Prof Ripley and Dimitris Rizopoulos


very best wishes

Robin



>> system.time(for(i in 1:100) t(H) %*% Ainv)
>>
> [1] 2.19 0.01 2.21 0.00 0.00
>
>> system.time(for(i in 1:100) crossprod(H, Ainv))
>>
> [1] 1.33 0.00 1.33 0.00 0.00
>
> so each is quite fast and the difference is not great.  However,  
> that is
> not comparing %*% with crossprod, but t & %*% with crossprod.
>
> I get
>
>
>> system.time(for(i in 1:1000) H %*% X)
>>
> [1] 0.05 0.01 0.06 0.00 0.00
>
> which is hardly 'slow' (60 us for %*%), especially compared to  
> forming X
> in
>
>
>> system.time({X  = solve(t(H) %*% Ainv %*% H) %*% t(H) %*% Ainv %*%  
>> d})
>>
> [1] 0.04 0.00 0.04 0.00 0.00
>
> I would probably have written
>
>
>> system.time({X <- solve(crossprod(H, Ainv %*% H), crossprod 
>> (crossprod(Ainv, H), d))})
>>
> 1] 0.03 0.00 0.03 0.00 0.00
>
> which is faster and does give the same answer.
>
> [BTW, I used 2.2.0-beta which defaults to gcFirst=TRUE.]
>
> -- 





--
Robin Hankin
Uncertainty Analyst
National Oceanography Centre, Southampton
European Way, Southampton SO14 3ZH, UK
  tel  023-8059-7743




More information about the R-help mailing list