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):
install.packages("expm", repos="http://R-Forge.R-project.org")
Otherwise, get the svn version directly, and install yourself:
svn checkout svn://svn.r-forge.r-project.org/svnroot/expm
Thanks to "gd047" who alerted me to the problem by e-mail.
Note that R-forge also has its own bug tracking facilities.
Martint
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:
> A <- B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> r1 <- A %^% 5
> A
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
> B
[,1] [,2] [,3]
[1,] 691 1926 312
[2,] 2331 6502 1056
[3,] 1116 3108 505
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:
`%m%` <- function(x, k) {
tmp <- x*1
res <- tmp%^%k
res
}
> B <-matrix(c(1,3,0,2,8,4,1,1,1),nrow=3)
> r2 <- B %m% 5
> B
[,1] [,2] [,3]
[1,] 1 2 1
[2,] 3 8 1
[3,] 0 4 1
What is the explicit way of doing this?
Finally, in the C code for the package, there is this comment:
NB: x will be altered! The caller must make a copy if needed
But I don't understand why R lets C/Fortran code have side effects in the global environment.
An inefficient version (since it's more efficient to first diagonalize your matrix) in base without much effort is:
pow = function(x, n) Reduce(`%*%`, replicate(n, x, simplify = FALSE))
I know this question is specifically about an old bug in expm, but it's one of the first results for "matrix power R" at the moment, so hopefully this little shorthand can be useful for someone else who ends up here just looking for a quick way to run matrix powers without installing any packages.
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 called matpowfast instead.
You need two variables :
result, in order to store the output,
mat, as an intermediate variable.
To compute A^6, since 6 = 110 (binary writing), in the end, result = A^6 and mat = A^4. This is the same for A^5.
You could easily check if mat = A^8 when you try to compute A^n for any 8<n<16. If so, you have your explanation.
The package function uses the initial variable A as the intermediate variable mat.
Very quick solution without using any package is using recursivity:
if your matrix is a
powA = function(n)
{
if (n==1) return (a)
if (n==2) return (a%*%a)
if (n>2) return ( a%*%powA(n-1))
}
HTH
You can simply use the Eigen values and Eigen vectors to compute the exponential of a matrix ;
# for a given matrix, A of power n
eig_vectors <- eigen(A)$vectors
eig_values <- eigen(A)$values
eig_vectors %*% diag(eig_values)^n %*% solve(eig_vectors)
Alternatively an improved answer from #MichaelChirico. The exponent 0 of a matrix will return its identity matrix instead of NULL.
pow = function(x, n) {
if (n == 0) {
I <- diag(length(diag(x)))
return(I)
}
Reduce(`%*%`, replicate(n, x, simplify = FALSE))
}
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.
Related
Good night. I have a homework of Coursera. But i have two days stuck trying to solve my problem.
My homework is:
Write the following functions:
makeCacheMatrix: This function creates a special "matrix" object that can cache its inverse.
cacheSolve: This function computes the inverse of the special "matrix" returned by makeCacheMatrix above. If the inverse has already been calculated (and the matrix has not changed), then the cachesolve should retrieve the inverse from the cache.
Computing the inverse of a square matrix can be done with the solve function in R. For example, if X is a square invertible matrix, then solve(X) returns its inverse.
I use the library matlib for calculate the inverse of the matrix.
library(matlib)
makeCacheMatrix <- function(x = matrix()) {
if (ncol(x)==nrow(x) && det(x)!=0) {
m<-NULL
set<-function(y){
x<<-y
m<<-NULL
}
get<-function() x
setinverse <- function() m <<- inv(x)
getinverse<-function() m
list(set=set,get=get,setinverse=setinverse,getinverse=getinverse)
}else{
return(message("The matrix is'n invertible."))
}
}
cacheSolve <- function(x, ...) {
m<-x$getinverse
if (!is.null(m)) {
message("getting cached data")
return(m)
}
data<-x$get
m <- inv(data, ...)
x$setinverse(m)
m
}
But when i'm trying for example test my code
x<-makeCacheMatrix(matrix(c(1,0,0,0,1,0,0,0,2),ncol=3,nrow=3))
x$get()
x$getinverse()
I obtain a NULL result. I don't know what's problem with my code. Can someone help me?
Given the code in the OP, x$getinverse() should return NULL because one must execute cacheSolve() in order to populate the cache. I explain the details of how the sample code for this assignment works, including the need for the second function to populate the cache, in the stackoverflow answer Caching the Mean of a Vector.
That said, the program has three defects that prevent it from operating correctly.
In cacheSolve(), m<-x$getinverse sets the value of m to a function, not the result of executing the getinverse() function
In cacheSolve(), data<-x$get returns the address of the function get() instead of its contents.
In cacheSolve(), x$setinverse(m) fails because the function setinverse() in makeCacheMatrix does not include an input argument.
Note that since I am a Community Mentor for the Hopkins R Programming course, I'm not allowed to post a complete solution because it would violate the Coursera Honor Code.
Once the errors are corrected, the code works like this:
> x <-makeCacheMatrix(matrix(c(1,0,0,0,1,0,0,0,2),ncol=3,nrow=3))
> cacheSolve(x)
[,1] [,2] [,3]
[1,] 1 0 0.0
[2,] 0 1 0.0
[3,] 0 0 0.5
> x$get()
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 2
> x$getinverse()
[,1] [,2] [,3]
[1,] 1 0 0.0
[2,] 0 1 0.0
[3,] 0 0 0.5
>
Good night. I have a homework of Coursera. But i have two days stuck trying to solve my problem.
My homework is:
Write the following functions:
makeCacheMatrix: This function creates a special "matrix" object that can cache its inverse.
cacheSolve: This function computes the inverse of the special "matrix" returned by makeCacheMatrix above. If the inverse has already been calculated (and the matrix has not changed), then the cachesolve should retrieve the inverse from the cache.
Computing the inverse of a square matrix can be done with the solve function in R. For example, if X is a square invertible matrix, then solve(X) returns its inverse.
I use the library matlib for calculate the inverse of the matrix.
library(matlib)
makeCacheMatrix <- function(x = matrix()) {
if (ncol(x)==nrow(x) && det(x)!=0) {
m<-NULL
set<-function(y){
x<<-y
m<<-NULL
}
get<-function() x
setinverse <- function() m <<- inv(x)
getinverse<-function() m
list(set=set,get=get,setinverse=setinverse,getinverse=getinverse)
}else{
return(message("The matrix is'n invertible."))
}
}
cacheSolve <- function(x, ...) {
m<-x$getinverse
if (!is.null(m)) {
message("getting cached data")
return(m)
}
data<-x$get
m <- inv(data, ...)
x$setinverse(m)
m
}
But when i'm trying for example test my code
x<-makeCacheMatrix(matrix(c(1,0,0,0,1,0,0,0,2),ncol=3,nrow=3))
x$get()
x$getinverse()
I obtain a NULL result. I don't know what's problem with my code. Can someone help me?
Given the code in the OP, x$getinverse() should return NULL because one must execute cacheSolve() in order to populate the cache. I explain the details of how the sample code for this assignment works, including the need for the second function to populate the cache, in the stackoverflow answer Caching the Mean of a Vector.
That said, the program has three defects that prevent it from operating correctly.
In cacheSolve(), m<-x$getinverse sets the value of m to a function, not the result of executing the getinverse() function
In cacheSolve(), data<-x$get returns the address of the function get() instead of its contents.
In cacheSolve(), x$setinverse(m) fails because the function setinverse() in makeCacheMatrix does not include an input argument.
Note that since I am a Community Mentor for the Hopkins R Programming course, I'm not allowed to post a complete solution because it would violate the Coursera Honor Code.
Once the errors are corrected, the code works like this:
> x <-makeCacheMatrix(matrix(c(1,0,0,0,1,0,0,0,2),ncol=3,nrow=3))
> cacheSolve(x)
[,1] [,2] [,3]
[1,] 1 0 0.0
[2,] 0 1 0.0
[3,] 0 0 0.5
> x$get()
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 2
> x$getinverse()
[,1] [,2] [,3]
[1,] 1 0 0.0
[2,] 0 1 0.0
[3,] 0 0 0.5
>
I write code manually of QR decomposition using Gram-Schmidt orthogonalization:
A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0),c(2,3,4))
gsm<-function(X){
m<-ncol(X)
n<-nrow(X)
# initialize Q and R
q<-matrix(0,m,n)
r<-matrix(0,n,n)
v<-matrix(0,m,n)
# initialize V
v[,1]<-X[,1]
q[,1]<-v[,1]/sqrt(sum(v[,1]^2))
r[1,1]<-t(X[,1])%*%q[,1]
for (i in 2:n){
dv<-0
for (j in 1:(i-1)) {
r[j,i]<-t(X[,i])%*%q[,j]
dv<-dv+r[j,i]*q[,j]
}
v[,i]<-X[,i]-dv
q[,i]<-v[,i]/sqrt(t(v[,i])%*%v[,i])
r[i,i]<-t(X[,i])%*%q[,i]
}
qrreport<-list("Q"=q,"R"=r)
return(qrreport)
}
gsm(A)
However, the code doesn't work and gives me the error:
Error in v[, 1] <- X[, 1] : number of items to replace is not a multiple of replacement length
And when I replace A with a 3*3 matrix: A<-cbind(c(2,-2,18),c(2,1,0),c(1,2,0)) and operate the function again, R throws a new error to me as:
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
Recycling array of length 1 in vector-array arithmetic is deprecated.
Use c() or as.vector() instead.
$ Q
[,1] [,2] [,3]
[1,] 0.1097643 0.89011215 -0.4423259
[2,] -0.1097643 0.45314800 0.8846517
[3,] 0.9878783 -0.04855157 0.1474420
$R
[,1] [,2] [,3]
[1,] 18.22087 0.1097643 -0.1097643
[2,] 0.00000 2.2333723 1.7964082
[3,] 0.00000 0.0000000 1.3269776
I am very confused where I make mistakes and hope someone could help me debug.
Your A matrix has 3 rows and 4 columns, so in gsm() m is 4 and n is 3. That means v has 4 rows and 3 columns, whereas X, which is really A, only has 3 rows. When v[, 1] <- X[, 1] tries to put the 1st column of X into the first
column of A, you get the error message you saw.
To debug things like this in RStudio, set a breakpoint on the line v[, 1] <- X[, 1] that caused the error, and look at the different items in the expression before executing it. If you're not using RStudio, you can still set a breakpoint there using the setBreakpoint function, but it's a lot more work.
I am not very experienced with R or Matlab, and I am trying to convert a Matlab code to R. The problem is, I am not exactly sure what the code does. Here is the matlab line I am having trouble with:
Wi = cell2mat(accumarray(s_group,s_u,[],#(x){repmat(sqrt(sum(x.*x)+eps),length(x),1)}));
I cannot find an R function that does the same sort of thing as the cell2mat in matlab.
When I run the code with my example data, the matlab gives me an array of length 86, which is the same length as the s_group and s_u variables.
However, when I use the same data with this R code:
Wi<-accumarray(s_group,s_u,sz=c(nrow(s_group),ncol(s_group)),func=function(x) matrix(sqrt(x*x),length(x),1))
it gives me the error
Error in accumarray(s_group, s_u, sz = c(length(s_group), 1), func = function(x) matrix(sqrt(x * :
Argument 'sz' does not fit with 'subs'.
I also tried it without the size specified:
Wi<-accumarray(s_group,s_u,func=function(x) matrix(sqrt(x*x),length(x),1))
and this gave me an array of length 21 with the error:
In A[i] <- func(val[subs == i]) :
number of items to replace is not a multiple of replacement length
Here is the original for-loop version from Matlab:
group_set = unique(group);
group_num = length(group_set);
Wi = zeros(n_XVar, 1);
for c = 1:group_num
idx = find(group==group_set(c));
Wc = u(idx,:);
di = sqrt(sum(sum(Wc.*Wc))+eps);
Wi(idx) = di;
end
Does anyone know what I can do to put this into R without using a for-loop?
Many thanks!
It seems the cell2mat function in Matlab turns a matrix of matrixes into a single matrix. A matrix of matrixes isn't exactly a common data type in R. But you can make one with
a<-matrix(list(), 2,2)
a[[1,1]]<-matrix(1, nrow=1)
a[[1,2]]<-matrix(2:4, nrow=1)
a[[2,1]]<-matrix(c(5,9), nrow=2)
a[[2,2]]<-matrix(c(6:8, 10:12), nrow=2, byrow=T)
(like the example on the MatLab help page for cel2mat). An R translation of that code might be
cell2mat<-function(m)
do.call(rbind, apply(m, 1, function(x) do.call(cbind,x)))
Which we can test wtih
cell2mat(a)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 5 6 7 8
# [3,] 9 10 11 12
This is probably not the most efficient translation but it's probably the simplest.
In R: How do I perform a log operation on every element of a matrix without using a loop?
I have a matrix m and I want each element to be replaced by its log.
log(m) doesn't work.
params = array(list(),c(2, 2))
then I manually set all elements.
params
[,1] [,2]
[1,] 3 3
[2,] 3 3
log(params)
Error in log(params) : Non-numeric argument to mathematical function
log(M) works for all of us on correct matrices:
R> M <- matrix(1:4,2)
R> M
[,1] [,2]
[1,] 1 3
[2,] 2 4
R> log(M)
[,1] [,2]
[1,] 0.00000 1.0986
[2,] 0.69315 1.3863
R>
Can you show us your M ?
You failed at making matrix -- this way you have a matrix of lists, and you want a matrix of numbers.
Try this:
params<-array(3,c(2,2))
log(params)
Now assume there is a 0 in some matrix cells. Furthermore, assume you want a 0 to appear in the output for such cells.
How would you compute the solution now?
Notice that log(0) is not a nice number.