This is an attempt at the Caching the Inverse of a Matrix Assignment from Programming with R, the exercise is to demonstrate closures.
Closures get their name because they enclose the environment of the parent function and can access all its variables. Closures are useful for making function factories, and are one way to manage mutable state in R.
It allows us to have two levels of parameters: a parent level that controls operation and a child level that does the work. The example, makeCacheMatrix(), uses this idea to store x and inv in the enclosing environment of the set, get, setInverse, getInverse functions. That means the environment within which they were defined, i.e., the environment created by the makeCacheMatrix().
makeCacheMatrix(): This function creates a special “matrix” object that can cache its inverse:
makeCacheMatrix <- function(x = matrix()) {
i <- NULL
set <- function(y) {
x <<- y
i <<- NULL
}
get <- function() x
setinverse <- function(inverse) i <<- inverse
getinverse <- function() i
list(set = set, get = get,
setinverse = setinverse,
getinverse = getinverse)
}
cacheSolve: This function computes the inverse of the special “matrix” returned by makeCacheMatrix above.
cacheSolve <- function(x, ...) {
i <- x$getinverse()
if (!is.null(i)) {
message("getting cached data")
return(i)
}
data <- x$get()
i <- solve(data, ...)
x$setinverse(i)
i
}
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] (https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/solve) function in R.
#solve(B) - if impossible
B <- matrix(c(1:4),2,2)
#Return inverse after computation
B1 <- makeCacheMatrix(B)
cacheSolve(B1)
## [,1] [,2]
## [1,] -2 1.5
## [2,] 1 -0.5
#Return inverse from cache
cacheSolve(B1)
## getting cached data
## [,1] [,2]
## [1,] -2 1.5
## [2,] 1 -0.5
When you print a closure, or the environment you see the function itself, you should print it
cacheSolve
## function(x, ...) {
## i <- x$getinverse()
## if (!is.null(i)) {
## message("getting cached data")
## return(i)
## }
## data <- x$get()
## i <- solve(data, ...)
## x$setinverse(i)
## i
##
## }
## <bytecode: 0x0000000008dde910>
# see the contents of the environment
as.list(environment(cacheSolve))
## $B1
## $B1$set
## function(y) {
## x <<- y
## i <<- NULL
## }
## <environment: 0x0000000007889378>
##
## $B1$get
## function() x
## <environment: 0x0000000007889378>
##
## $B1$setinverse
## function(inverse) i <<- inverse
## <environment: 0x0000000007889378>
##
## $B1$getinverse
## function() i
## <environment: 0x0000000007889378>
##
##
## $B
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## $makeCacheMatrix
## function(x = matrix()) {
## i <- NULL
## set <- function(y) {
## x <<- y
## i <<- NULL
## }
## get <- function() x
## setinverse <- function(inverse) i <<- inverse
## getinverse <- function() i
## list(set = set, get = get,
## setinverse = setinverse,
## getinverse = getinverse)
## }
##
## $cacheSolve
## function(x, ...) {
## i <- x$getinverse()
## if (!is.null(i)) {
## message("getting cached data")
## return(i)
## }
## data <- x$get()
## i <- solve(data, ...)
## x$setinverse(i)
## i
##
## }
## <bytecode: 0x0000000008dde910>
library(pryr)
## Registered S3 method overwritten by 'pryr':
## method from
## print.bytes Rcpp
# re-run cacheSolve()
B <- matrix(c(1:4),2,2)
B1 <- makeCacheMatrix(B)
cacheSolve(B1)
## [,1] [,2]
## [1,] -2 1.5
## [2,] 1 -0.5
unenclose(cacheSolve)
## function (x, ...)
## {
## i <- x$getinverse()
## if (!is.null(i)) {
## message("getting cached data")
## return(i)
## }
## data <- x$get()
## i <- solve(data, ...)
## x$setinverse(i)
## i
## }
## <environment: package:pryr>
The execution environment normally disappears after the function returns a value. However, functions capture their enclosing environments. This means when function cacheSolve() returns function makeCacheMatrix(), function b_makeCacheMatrix() captures and stores the execution environment of function cacheSolve(), and it doesn’t disappear.
Feel free to reach out to me, if you have any questions :) Linda, 13/05/2020