makeCacheMatrix()
Calculating the inverse as well as performing other operations can be
a very expensive task. It may be useful or more memory efficient to
save(cache) the inverse if this operation will be repeated. Lexical
scoping in R makes this possible. In lexical
scoping R looks up the value of a variable in the environment where
the function was defined, not where it was called.
makeCacheMatrix is a function to:
- set the value of the matrix
- get the value of the matrix
- set the inverse of the matrix
- retrieve the inverse of the matrix
The super
assignment operator (<<-) is utilized in the function below.
“Super
assignment, <<-, never creates a variable in the current
environment, but instead modifies an existing variable found in a parent
environment.”
makeCacheMatrix <- function(x = matrix()) {
inv <- NULL
set <- function(m){
x <<- m
inv <<- NULL
}
get <- function() x
setInv <- function(a){inv <<- a}
getInv <- function() inv
list(set = set,
get = get,
setInv = setInv,
getInv = getInv)
}
cacheSolve()
cacheSolve() takes a makeCacheMatrix object and returns the inverse
of the associated matrix. cacheSolve() assumes that the matrix
set by makeCacheMatrix is invertible.
If the inverse is cached, cacheSolve retrieves and returns it;
otherwise, it calculates the inverse, caches it before returning the
inverse to the user.
cacheSolve <- function(x, ...) {
## Return a matrix that is the inverse of 'x'
inv <- x$getInv()
if(!is.null(inv)){
message('Getting Cached inverse...')
return(inv)
}else{
message('Inverse is not cached! Calculating inverse...')
mat <- x$get()
inv <- solve(mat, ...)
x$setInv(inv)
inv
}
}
TESTING
set.seed(1)
m <- matrix(sample(0:10, 9), nrow = 3, ncol = 3)
m
[,1] [,2] [,3]
[1,] 8 0 2
[2,] 3 1 10
[3,] 6 4 9
Instantiate an instance of makeCacheMatrix
M <- makeCacheMatrix(m)
M$get()
[,1] [,2] [,3]
[1,] 8 0 2
[2,] 3 1 10
[3,] 6 4 9
M$getInv()
NULL
Get Inverse of M(an object of makeCacheMatrix)
Since this is the first time cacheSolve is called for object M, the
inverse is not stored (i.e. M$getInv() yields NULL). cacheSolve(M)
calculates and returns the inverse.
cacheSolve(M) # (1)
Inverse is not cached! Calculating inverse...
[,1] [,2] [,3]
[1,] 0.13135593 -0.03389831 0.008474576
[2,] -0.13983051 -0.25423729 0.313559322
[3,] -0.02542373 0.13559322 -0.033898305
Running cachSolve(M)
a second time yields:
cacheSolve(M)
Getting Cached inverse...
[,1] [,2] [,3]
[1,] 0.13135593 -0.03389831 0.008474576
[2,] -0.13983051 -0.25423729 0.313559322
[3,] -0.02542373 0.13559322 -0.033898305
The cached inverse was retrieved since inverse was already calculated
in (1) above.
Source:
- https://adv-r.hadley.nz/index.html
- https://www.coursera.org/learn/r-programming/home/info
LS0tDQp0aXRsZTogIkxleGljYWwgU2NvcGluZzogQ2FjaGluZyBEYXRhIg0KYXV0aG9yOiAiU0sgTWlsbGVyIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMjIyAqKm1ha2VDYWNoZU1hdHJpeCgpKioNCg0KQ2FsY3VsYXRpbmcgdGhlIGludmVyc2UgYXMgd2VsbCBhcyBwZXJmb3JtaW5nIG90aGVyIG9wZXJhdGlvbnMgY2FuIGJlIGEgdmVyeSANCmV4cGVuc2l2ZSB0YXNrLiBJdCBtYXkgYmUgdXNlZnVsIG9yIG1vcmUgbWVtb3J5IGVmZmljaWVudCB0byBzYXZlKGNhY2hlKSB0aGUgDQppbnZlcnNlIGlmIHRoaXMgb3BlcmF0aW9uIHdpbGwgYmUgcmVwZWF0ZWQuIFtMZXhpY2FsIHNjb3BpbmddKGh0dHBzOi8vYWR2LXIuaGFkbGV5Lm56L2Z1bmN0aW9ucy5odG1sI2xleGljYWwtc2NvcGluZykgaW4gUiBtYWtlcyB0aGlzIHBvc3NpYmxlLiBJbiBbbGV4aWNhbCBzY29waW5nXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TY29wZV8oY29tcHV0ZXJfc2NpZW5jZSkjTGV4aWNhbF9zY29wZV92cy5fZHluYW1pY19zY29wZSkgUiBsb29rcyB1cCB0aGUgdmFsdWUgb2YgYSB2YXJpYWJsZSBpbiB0aGUgZW52aXJvbm1lbnQNCndoZXJlIHRoZSBmdW5jdGlvbiB3YXMgZGVmaW5lZCwgbm90IHdoZXJlIGl0IHdhcyBjYWxsZWQuDQoNCm1ha2VDYWNoZU1hdHJpeCBpcyBhIGZ1bmN0aW9uIHRvOiAgDQotIHNldCB0aGUgdmFsdWUgb2YgdGhlIG1hdHJpeCAgDQotIGdldCB0aGUgdmFsdWUgb2YgdGhlIG1hdHJpeCAgDQotIHNldCB0aGUgaW52ZXJzZSBvZiB0aGUgbWF0cml4ICAgDQotIHJldHJpZXZlIHRoZSBpbnZlcnNlIG9mIHRoZSBtYXRyaXggIA0KDQpUaGUgW3N1cGVyIGFzc2lnbm1lbnQgb3BlcmF0b3IgKDw8LSldKGh0dHBzOi8vYWR2LXIuaGFkbGV5Lm56L2Vudmlyb25tZW50cy5odG1sKSBpcyB1dGlsaXplZCBpbiB0aGUgZnVuY3Rpb24gYmVsb3cuICJbU3VwZXIgYXNzaWdubWVudF0oaHR0cHM6Ly9hZHYtci5oYWRsZXkubnovZW52aXJvbm1lbnRzLmh0bWwpLCA8PC0sIG5ldmVyIGNyZWF0ZXMgYSB2YXJpYWJsZSBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCwgYnV0IGluc3RlYWQgbW9kaWZpZXMgYW4gZXhpc3RpbmcgdmFyaWFibGUgZm91bmQgaW4gYSBwYXJlbnQgZW52aXJvbm1lbnQuIg0KDQpgYGB7cn0NCm1ha2VDYWNoZU1hdHJpeCA8LSBmdW5jdGlvbih4ID0gbWF0cml4KCkpIHsNCiAgaW52IDwtIE5VTEwNCiAgDQogIHNldCA8LSBmdW5jdGlvbihtKXsNCiAgICB4IDw8LSBtDQogICAgaW52IDw8LSBOVUxMDQogIH0NCiAgDQogIGdldCA8LSBmdW5jdGlvbigpIHgNCiAgDQogIHNldEludiA8LSBmdW5jdGlvbihhKXtpbnYgPDwtIGF9DQogIA0KICBnZXRJbnYgPC0gZnVuY3Rpb24oKSBpbnYNCiAgDQogIGxpc3Qoc2V0ID0gc2V0LCANCiAgICAgICBnZXQgPSBnZXQsDQogICAgICAgc2V0SW52ID0gc2V0SW52LCANCiAgICAgICBnZXRJbnYgPSBnZXRJbnYpDQoNCn0NCmBgYA0KDQoNCg0KIyMjIyAqKmNhY2hlU29sdmUoKSoqDQoNCmNhY2hlU29sdmUoKSB0YWtlcyBhIG1ha2VDYWNoZU1hdHJpeCBvYmplY3QgYW5kIHJldHVybnMgdGhlIGludmVyc2Ugb2YgdGhlIA0KYXNzb2NpYXRlZCBtYXRyaXguIGNhY2hlU29sdmUoKSAqYXNzdW1lcyogdGhhdCB0aGUgbWF0cml4IHNldCBieSBtYWtlQ2FjaGVNYXRyaXggaXMNCioqaW52ZXJ0aWJsZSoqLg0KDQpJZiB0aGUgaW52ZXJzZSBpcyBjYWNoZWQsIGNhY2hlU29sdmUgcmV0cmlldmVzIGFuZCByZXR1cm5zIGl0OyBvdGhlcndpc2UsIGl0IA0KY2FsY3VsYXRlcyB0aGUgaW52ZXJzZSwgY2FjaGVzIGl0IGJlZm9yZSByZXR1cm5pbmcgdGhlIGludmVyc2UgdG8gdGhlIHVzZXIuDQoNCmBgYHtyfQ0KY2FjaGVTb2x2ZSA8LSBmdW5jdGlvbih4LCAuLi4pIHsNCiAgIyMgUmV0dXJuIGEgbWF0cml4IHRoYXQgaXMgdGhlIGludmVyc2Ugb2YgJ3gnDQogIGludiA8LSB4JGdldEludigpDQogIA0KICBpZighaXMubnVsbChpbnYpKXsNCiAgICBtZXNzYWdlKCdHZXR0aW5nIENhY2hlZCBpbnZlcnNlLi4uJykNCiAgICByZXR1cm4oaW52KQ0KICB9ZWxzZXsNCiAgICBtZXNzYWdlKCdJbnZlcnNlIGlzIG5vdCBjYWNoZWQhIENhbGN1bGF0aW5nIGludmVyc2UuLi4nKQ0KICAgIA0KICAgIG1hdCA8LSB4JGdldCgpDQogICAgaW52IDwtIHNvbHZlKG1hdCwgLi4uKQ0KICAgIHgkc2V0SW52KGludikNCiAgICBpbnYNCiAgfQ0KICANCiAgDQp9DQpgYGANCg0KDQoNCg0KDQojIyMjICoqVEVTVElORyoqDQpgYGB7cn0NCnNldC5zZWVkKDEpDQptIDwtIG1hdHJpeChzYW1wbGUoMDoxMCwgOSksIG5yb3cgPSAzLCBuY29sID0gMykNCm0NCmBgYA0KDQoNCg0KIyMjIyMgSW5zdGFudGlhdGUgYW4gaW5zdGFuY2Ugb2YgbWFrZUNhY2hlTWF0cml4DQpgYGB7cn0NCk0gPC0gbWFrZUNhY2hlTWF0cml4KG0pDQpgYGANCg0KYGBge3J9DQpNJGdldCgpDQpgYGANCmBgYHtyfQ0KTSRnZXRJbnYoKQ0KYGBgDQoNCg0KDQojIyMjICoqR2V0IEludmVyc2Ugb2YgTShhbiBvYmplY3Qgb2YgbWFrZUNhY2hlTWF0cml4KSoqDQpTaW5jZSB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIGNhY2hlU29sdmUgaXMgY2FsbGVkIGZvciBvYmplY3QgTSwgdGhlIGludmVyc2UNCmlzIG5vdCBzdG9yZWQgKGkuZS4gTSRnZXRJbnYoKSB5aWVsZHMgTlVMTCkuIGNhY2hlU29sdmUoTSkgY2FsY3VsYXRlcyBhbmQgDQpyZXR1cm5zIHRoZSBpbnZlcnNlLg0KDQpgYGB7cn0NCmNhY2hlU29sdmUoTSkgIyAoMSkNCmBgYA0KDQoNCg0KUnVubmluZyBgY2FjaFNvbHZlKE0pYCBhIHNlY29uZCB0aW1lIHlpZWxkczoNCmBgYHtyfQ0KY2FjaGVTb2x2ZShNKQ0KYGBgDQoNCg0KVGhlIGNhY2hlZCBpbnZlcnNlIHdhcyByZXRyaWV2ZWQgc2luY2UgaW52ZXJzZSB3YXMgYWxyZWFkeSBjYWxjdWxhdGVkIGluICgxKSBhYm92ZS4NCg0KU291cmNlOiAgDQotIGh0dHBzOi8vYWR2LXIuaGFkbGV5Lm56L2luZGV4Lmh0bWwgIA0KLSBodHRwczovL3d3dy5jb3Vyc2VyYS5vcmcvbGVhcm4vci1wcm9ncmFtbWluZy9ob21lL2luZm8NCg==