Caching the Inverse of a Matrix - r

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
>

Related

How do I keep track of a value on other environment in R

I'm trying to make an assignment for an online course and I'm stuck at trying to keep a value on cache. Basically,there would be two functions: One would be a closure function and host a variable to keep track of values on cache. The other one would be responsible for managing the matrices. Problem is the programn doesn't seem to keep the value of m stored for each matrix and always considers that there are already values on the cache. How can I keep track of the cached values?
makeCacheMatrix <- function(x = matrix()) {
m<-NULL
set<-function(y){
x<<-y
m<<-NULL
}
get<-function()x
inverse<-function(x) m<<-solve(x)
cache<-function() m
list(set=set(x),get=get(),inverse=inverse(x),cache=cache())
}
## Write a short comment describing this function
cacheSolve <- function(x, ...) {
## Return a matrix that is the inverse of 'x'
n<-makeCacheMatrix(x)$cache
if (!is.null(n)){
print("Loading from cache")
return(n)
}
else{
makeCacheMatrix(x)$set
data<-makeCacheMatrix(x)$get
makeCacheMatrix(data)$inverse
makeCacheMatrix(data)$cache
}}
It's not entirely clear what you are attempting here. My guess is that you want to have a cache so that if you need to run a resource-intensive function on an object then you only have to run it once, but thereafter be able to access the stored result of the computation. Whether the computation has been run or not, you want the same interface to access the result.
You could do that this way:
store_matrix_for_cache <- function(x = matrix()) {
m <<- NULL
function()
{
x <<- x
list(get = x, cache = m, solve = function() m <<- solve(x))
}
}
get_cached_result <- function(cache, ...)
{
if (is.null(cache()$cache))
{
cat("Solving before returning from cache\n")
cache()$solve()
}
else
{
cat("Loading from cache\n")
}
return(cache()$cache)
}
So let's test it on some sample data:
set.seed(69)
my_mat <- matrix(sample(9), nrow = 3)
my_mat
#> [,1] [,2] [,3]
#> [1,] 2 5 9
#> [2,] 4 1 6
#> [3,] 7 3 8
We start by writing our matrix to the cache. Note our "expensive" solve function hasn't been called yet, so this is computationally cheap:
my_cache <- store_matrix_for_cache(my_mat)
When we come to extract the result, then on the first occasion, we will trigger the solve calculation:
get_cached_result(my_cache)
#> Solving before returning from cache
#> [,1] [,2] [,3]
#> [1,] 2.000000 1.0000000 -2.0000000
#> [2,] -1.727273 -0.4545455 1.5454545
#> [3,] 1.090909 0.1818182 -0.8181818
However, the second (and subsequent times) we access the cache, we don't trigger the solve function, but instead return the stored result.
get_cached_result(my_cache)
#> Loading from cache
#> [,1] [,2] [,3]
#> [1,] 2.000000 1.0000000 -2.0000000
#> [2,] -1.727273 -0.4545455 1.5454545
#> [3,] 1.090909 0.1818182 -0.8181818
Note also that our accessor function can be shortened by removing the cat messages now we're happy it works as expected:
get_cached_result <- function(cache, ...)
{
if (is.null(cache()$cache)) cache()$solve()
cache()$cache
}
Created on 2020-07-25 by the reprex package (v0.3.0)

Caching inverse of a matrix in R [duplicate]

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
>

R programming:How to use loop on variables labelled in a consecutive manner?

I'm trying to figure out, how I can run a loop on some variables that have a consecutive label.
I want to do matrix.2-Matrix.1 and store it in matrix x.1, then Matrix.3-matrix.2 and store it in matrix x.2. There are 300 matrices(Matrix.1,Matrix.2,...Matrix.300) but for this example, I would like to just work on matrix 1,2 and 3.
I first tried an approach that involved the list function, but it didn't work, and then I thought about using a MACRO just like in SAS (the % symbol). But the Macro approach seemed not to work in R.
My code is below:
(The list approach)
> Matrix.1=matrix(c(1:6),nrow=2,ncol=3,byrow=TRUE)
> Matrix.2=matrix(c(1,8,9,17,15,2),nrow=2,ncol=3,byrow=TRUE)
> Matrix.3=matrix(c(0,1,2,3,6,0),nrow=2,ncol=3,byrow=TRUE)
> x.1=matrix(rep(0,6),nrow=2,ncol=3,byrow=TRUE)
> x.2=matrix(rep(0,6),nrow=2,ncol=3,byrow=TRUE)
> m=list(Matrix.1=Matrix.1,Matrix.2=Matrix.2,Matrix.3=Matrix.3)
> x=list(x.1=x.1,x.2=x.2)
> m[1]
$Matrix.1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
> m[2]
$Matrix.2
[,1] [,2] [,3]
[1,] 1 8 9
[2,] 17 15 2
> m[3]
$Matrix.3
[,1] [,2] [,3]
[1,] 0 1 2
[2,] 3 6 0
> x[1]
$x.1
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
> x[2]
$x.2
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 0 0 0
> for (i in 1:2){
+ x[i]=m[i+1]-m[i]
+ print(x[i])
+ }
Error in m[i + 1] - m[i] : non-numeric argument to binary operator
>
How can I make operations on list?
> #Other approach inspired from SAS
> for (i in i:2){
+ x.i=Matrix.i+1-Matrix.i
+ print(R.i)
+ }
Error: object 'Matrix.i' not found
This second approach isn't even doable in R.
What is the best way of dealing loops involving consecutively labelled variables?
Since m and x are both lists, you need to use m[[1]] and x[[1]] to extract its elements.
for (i in 1:2){
x[[i]] <- m[[i+1]]-m[[i]]
print(x[[i]])
}
On the other hand, if you have 300 matrices (Matrix.1, Matrix.2, ... Matrix.300), you could use get and assign to deal with the numerical labels. Here I first assign values to 300 matrices with names Matrix.1 through Matrix.300. Then I use get function to extract these matrices and generate list x.
for (i in 1:300) {
assign(paste("Matrix.", i, sep = ""), matrix(rnorm(9), 3, 3))
}
x <- list()
for (i in 2:300) {
x[[i-1]] <- get(paste("Matrix.", i, sep = "")) - get(paste("Matrix.", i-1, sep = ""))
}
It is the preferred method in R to use the apply family of functions to loop through objects. For lists, you can use lapply which returns a list, or sapply which returns the most simplified object it can without losing any information. With these functions, you output is stored in the same order as the input, which makes comparisons or additional steps much easier.
myProcessedList <- lapply(x, FUN=<some function>)
This is a lot simpler and more straightforward than using assign and get and is worth the investment to learn. SO has many useful examples.

R equivalent to diag(x,k) in matlab

I guess, I have a two leveled question referring to diag in R and matlab.
1) I was wondering if there was a way already developed to access different diagonals of matrices in R similar to the way it is done in Matlab (see http://www.mathworks.com/help/techdoc/ref/diag.html).
2) If there is not already a current function how can my code be improved such that it is similar to the R diag where
diag(x = 1, nrow, ncol) # returns the values of the diagonal
diag(x) <- value # inserts values on the diagonal
Presently my code returns the elements on the diagonal given k but how can it be written so that if it is specified like the second way (above) that it allows me to insert the values on the diagonal. Presently to do this, I use diag.ind to give me the indices and then using those indices to insert the values on the k diagonal.
Here is the code:
'diag.ind'<-function(x,k=0){
if(k=='') k=0
x<-as.matrix(x)
if(dim(x)[2]==dim(x)[1]){
stp_pt_r<-dim(x)[1]
stp_pt_c<-dim(x)[2]
}
if(ncol(x)> dim(x)[1]){
stp_pt_r<-dim(x)[1]
stp_pt_c<-stp_pt_r + 1
}
if(ncol(x)< dim(x)[1]){
stp_pt_c<-dim(x)[2]
stp_pt_r<-stp_pt_c+1
}
if(k==0){
r<-as.matrix(seq(1,stp_pt_r,by=1))
c<-as.matrix(seq(1,stp_pt_c,by=1))
ind.r<- cbind(r,c)
}
if(k>0){
r<-t(as.matrix(seq(1,stp_pt_r,by=1)))
c<-t(as.matrix(seq((1+k),stp_pt_c,by=1)))
ind<-t(rbind.fill.matrix(r,c))
ind.r<-ind[!is.na(ind[,2]),]
}
if(k<0){
k<-abs(k)
r<-t(as.matrix(seq((1+k),stp_pt_r,by=1)))
c<-t(as.matrix(seq(1,stp_pt_c,by=1)))
ind<-t(rbind.fill.matrix(r,c))
ind.r<-ind[!is.na(ind[,1]),]
}
diag.x<-x[ind.r]
output<-list(diag.x=diag.x, diag.ind=ind.r)
return(output)
}
This is kind of clunky and I feel like I must be reinventing the wheel. Thanks in advance for any insight!
After your reply to Andrie this may satisfy:
exdiag <- function(mat, off) {mat[row(mat)+off == col(mat)]}
x <- matrix(1:16, ncol=4)
exdiag(x,1)
#[1] 5 10 15
I was thinking you wanted a function that can assign or return one of a diagonal or a sub- or super- diagonal matrix, This is the constructor function:
subdiag <- function(vec, size, offset=0){
M <- matrix(0, size, size)
M[row(M)-offset == col(M)] <- vec
return(M)}
> subdiag(1, 5, 1)
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 1 0 0 0 0
[3,] 0 1 0 0 0
[4,] 0 0 1 0 0
[5,] 0 0 0 1 0
Called with only two arguments you would get a diagonal matrix. You can construct super-diagonal matrices with negative offsets. If this is what you wanted for the constructor, then it should not be too hard to construct a similar subdiag<- function to go along with it.
In MATLAB, to assign the values x to the diagonal of A:
n = size(A,1);
A(1:n+1:end) = x
Look up linear indexing.
Although, that might not be what you asked.

Matrix power in R

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.

Resources