Skip to content

Commit a3a741f

Browse files
committed
Initial commit
Added code to create makeCacheMatrix and cacheSolve. Tweaked the ideas from the vector demo to do some mild checking for bad things (tolerance in inverse, parameters accidentally passed to cacheSolve that will create disaster).
1 parent e4eed41 commit a3a741f

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

cachematrix.R

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,76 @@
1-
## Put comments here that give an overall description of what your
2-
## functions do
1+
## This creates a matrix object with a cacheable inverse and defines a function
2+
## to recall or compute and cache the inverse. I added a tiny bit of checking
3+
## to make sure inverses are within a tolerance and the user is not passing a named
4+
## parameter to cacheSolve that will interfere with the solve function.
35

4-
## Write a short comment describing this function
5-
6-
makeCacheMatrix <- function(x = matrix()) {
6+
## Construct the cacheable matrix: an object with a cacheable inverse.
7+
## Unlike in the example code for vectors, we keep a copy of the input in the
8+
## local environment to protect against lazy eval of the input. This is discussed
9+
## at https://class.coursera.org/rprog-002/forum/thread?thread_id=370
10+
## As per instructions, I assume an invertible matrix is passed in when the
11+
## function is used (contrary to the default value of x!)
12+
## NOTE: I have added a tolerance parameter and an optional test to the setter to
13+
## see if the user is passing an inverse that is within the tolerance in each entry.
14+
## Who knows where the disgusting inverse the user inserts comes from?
15+
## I just want to make sure it has some semblence of correctness if I will permit
16+
## it to be set. I'm sure this is not the best way to check such things.
17+
## It is easy to require tighter
18+
## tolerance than solve can achieve, but at least it's good to know that.
19+
## The inverse will not be set without an appropriate tolerance attached
20+
## to the makeCacheMatrix.
721

22+
makeCacheMatrix <- function(x = matrix(), tol = 1e-7, check.inverse = TRUE) {
23+
inv <- NULL
24+
x <- x
25+
tol <- tol
26+
set <- function(y) {
27+
x <<- y
28+
inv <<- NULL
29+
}
30+
get <- function() x
31+
setinv <- function(inverse, check = check.inverse) {
32+
if (check){
33+
diff <- x %*% inverse - diag(nrow(x))
34+
# if any entry exceeds tolerance warn user
35+
if (sum(abs(diff) > tol)) message(paste(c("passed inverse not within required tolerance of ", tol,". Inverse set to NULL.")))
36+
inv <<- NULL
37+
} else {
38+
inv <<- inverse
39+
}
40+
}
41+
getinv <- function() inv
42+
settol <- function(tolerance) tol <<- tolerance
43+
gettol <- function() tol
44+
list(set = set, get = get,
45+
setinv = setinv, getinv = getinv,
46+
settol = settol, gettol = gettol)
847
}
948

1049

11-
## Write a short comment describing this function
50+
## If the makeCacheMatrix has a cached inverse, return it.
51+
## Otherwise, calculate the inverse, cache it, and return it.
52+
## We check for an accidental parameter
53+
## name collision: if ... contains a parameter named b, it will wreak havoc
54+
## with the use of solve
1255

1356
cacheSolve <- function(x, ...) {
14-
## Return a matrix that is the inverse of 'x'
57+
inv <- x$getinv()
58+
tol <- x$gettol()
59+
args <- list(...)
60+
if(!is.null(inv)) {
61+
message("getting cached inverse")
62+
return(inv)
63+
}
64+
mat <- x$get()
65+
# If user has passed an argument called "b",
66+
# it will interfere with the "b" argument of solve, resulting in chaos.
67+
# Check first that args is non-empty, then whether "b" is in there
68+
# and issue a warning if necessary.
69+
if (length(args) > 0 && exists("b", where=args)) {
70+
warning("the passed b argument will interfere with the construction of the inverse matrix")
71+
}
72+
73+
inv <- solve(a=mat, ...)
74+
x$setinv(inv)
75+
inv
1576
}

0 commit comments

Comments
 (0)