Introduction to the assignment
In this example we introduce the <<- operator which can be used to assign a value to an object in an environment that is different from the current environment. Below are two functions that are used to create a special object that stores a numeric vector and cache’s its mean.
The first function, makeVector creates a special “vector”, which is really a list containing a function to
- set the value of the vector
- get the value of the vector
- set the value of the mean
- get the value of the mean
makeVector <- function(x = numeric()) {
m <- NULL
set <- function(y) {
x <<- y
m <<- NULL
}
get <- function() x
setmean <- function(mean) m <<- mean
getmean <- function() m
list(set = set, get = get,
setmean = setmean,
getmean = getmean)
}The following function calculates the mean of the special “vector” created with the above function. However, it first checks to see if the mean has already been calculated. If so, it gets the mean from the cache and skips the computation. Otherwise, it calculates the mean of the data and sets the value of the mean in the cache via the setmean function.
Assignment: Caching the Inverse of a Matrix
Matrix inversion is usually a costly computation and there may be some benefit to caching the inverse of a matrix rather than compute it repeatedly (there are also alternatives to matrix inversion that we will not discuss here). Your assignment is to write a pair of functions that cache the inverse of a matrix.
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.
makeCacheMatrix <- function(x = matrix()) {
inv <- NULL
get <- function() x
set <- function(y) {
x <<- y
inv <<- NULL
}
getinv <- function() inv
setinv <- function(inverse) {
inv <<- inverse
}
return(list(
set = set,
get = get,
getinverse = getinv,
setinverse = setinv
))
}
cacheSolve <- function(x,...) {
inverse <- x$getinverse()
if (!is.null(inverse)) {
return(inverse)
}
m <- solve(x$get())
x$setinverse(m)
#return(m)
}Explanation:
- Cosntructor function “makeCacheMatrix”
This is a function that caches the computed values or the inputs. In the second line we create the variable inv and set it by default to NULL.
library(DiagrammeR)
nodes <- create_node_df(
n = 10,
type = c(rep("m",5),rep('o',3),rep("c",2)),
label = c("set","get","get inverse","set inverse","cache constructor","object in RAM","matrix","inverse matrix",
"solve function","if not cached solve/save"),
color = c(rep('red',5),rep('blue',3),rep('green',2))
)
edges <- create_edge_df(
c(1,2,3,4,5,6,7,8,6,9,10),
c(5,5,5,5,6,5,6,6,9,6,9),
color = c(rep('red',5),rep('blue',4),rep('green',2)))
graph <- create_graph(
nodes_df = nodes,
edges_df = edges,attr_theme = "lr",directed = FALSE,graph_name = "Mind Map")
# View the graph
render_graph(graph)The first time that we run the function makeCacheMAtrix we create an object with 4 objects attached to it
the matrix value which can be accessed with the get function of the same object
set function that can change the cached value of matrix
get inverse function to get the cached inverse of the matrix, which sets its value to NULL every time we assign a new matrix
set inverse to get access to the object by the cacheSolve function
the
<<-operator in both set functions attached to the object, is used to assign values in the parent frame outside of the function’s environment created by makeCacheMatrix function.
the cacheSolve function on the other hand gets access to the object’s inverse matrix with the <- operator which " searches in the function’s environment and then searches one level up in the parent environment" and returns the cached inverse matrix without computing again of course or computes the inverse otherwise for a first entry matrix or if the matrix was changed with the makeCacheMatrix$set(.) function.
[1] TRUE
NULL
cacheSolve(m)
## now cacheSolve found out that the inverse in the object is NULL (<<- going one level up)
## and replace the NULL value with the inverse of the matrix
m$getinverse() [,1] [,2] [,3]
[1,] -0.1428571 0.4285714 -0.1428571
[2,] -0.7142857 1.1428571 0.2857143
[3,] 0.8571429 -0.5714286 -0.1428571
## now let's set another matrix in the m object
m$set(rbind(sqrt(c(2,2)),c(-1,2)))
## notice that every time we enter a new matrix the inverse is turned to NULL with the <<- operator that
## changes the m object's inverse value in the parent frame
m$getinverse()NULL