Trying to compute the power of a matrix in R, I found that package expm
implements the operator %^%.
So x %^% k computes the k-th power of a matrix.
> A<-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> A %^% 5
[,1] [,2] [,3]
[1,] 6469 18038 2929
[2,] 21837 60902 9889
[3,] 10440 29116 4729
but, to my surprise:
> A
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
somehow the initial matrix A has changed to A %^% 4 !!!
How do you perform the matrix power operation?
I have fixed that bug in the R-forge sources (of "expm" package), svn rev. 53. --> expm R-forge page For some reason the web page still shows rev.52, so the following may not yet solve your problem (but should within 24 hours):
Otherwise, get the svn version directly, and install yourself:
Thanks to "gd047" who alerted me to the problem by e-mail. Note that R-forge also has its own bug tracking facilities.
Martint
Very quick solution without using any package is using recursivity: if your matrix is a
HTH
This is not a proper answer, but may be a good place to have this discussion and understand the inner workings of R. This sort of bug has crept up before in another package I was using.
First, note that simply assigning the matrix to a new variable first does not help:
My guess is that R is trying to be smart passing by reference instead of values. To actually get this to work you need to do something to differentiate A from B:
What is the explicit way of doing this?
Finally, in the C code for the package, there is this comment:
But I don't understand why R lets C/Fortran code have side effects in the global environment.
A^5 = (A^4)*A
I suppose the library mutates the original variable, A, so that the each step involves multiplying the result-up-till-then with the original matrix, A. The result you get back seem fine, just assign them to a new variable.
Although the source-code is not visible in the package since it is packed in a
.dll file
, I believe the algorithm used by the package is the fast exponentiation algorithm, which you can study by looking at the function calledmatpowfast
instead.You need two variables :
result
, in order to store the output,mat
, as an intermediate variable.To compute
A^6
, since6 = 110
(binary writing), in the end,result = A^6
andmat = A^4
. This is the same forA^5
.You could easily check if
mat = A^8
when you try to computeA^n
for any8<n<16
. If so, you have your explanation.The package function uses the initial variable
A
as the intermediate variablemat
.