This repository was archived by the owner on Nov 27, 2019. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathcachematrix.R
More file actions
128 lines (108 loc) · 3.92 KB
/
Copy pathcachematrix.R
File metadata and controls
128 lines (108 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
## Create a matrix object that stores the original matrix and its "solved
## version", with the intent of caching the solved matrix so that it does not
## need to be recomputed each time it is needed.
makeCacheMatrix <- function(mat = matrix()) {
matSolved <- NULL
# Store a matrix in this object and clear the solved matrix.
# This basically reinitializes the object with a new matrix.
#
set <- function(inMat) {
mat <<- inMat
matSolved <<- NULL
}
# Retrieve the original matrix from this object.
#
get <- function() mat
# Store the solved matrix in this object.
#
setSolved <- function(inMatSolved) matSolved <<- inMatSolved
# Retrieve the solved matrix from this object.
#
getSolved <- function() matSolved
# Return the function list.
#
list(set = set,
get = get,
setSolved = setSolved,
getSolved = getSolved)
}
## Solve a matrix using the solve() function. Note that if only the first
## argument is provided, solve() computes the inverse of the matrix. Return the
## solved version, but use the cached version if it is available.
cacheSolve <- function(x, ...) {
# Return the cached matrix if it exists.
#
matSolved <- x$getSolved()
if (!is.null(matSolved)) {
message("getting cached data")
return(matSolved)
}
# Invoke solve() on the original matrix.
#
matSolved <- solve(x$get(), ...)
# Cache the solved matrix and return it.
#
x$setSolved(matSolved)
matSolved
}
## Unit Tests
cacheSolveTest <- function() {
## Test basic caching.
##
n <- 3
mat <- matrix(rnorm(1:(n*n)), nrow=n, ncol=n)
matCached <- makeCacheMatrix(mat)
matSolved1 <- cacheSolve(matCached)
matSolved2 <- cacheSolve(matCached)
if (!identical(matSolved1, matSolved2))
message("Cached version does not match solved version")
## Use a time test to see if we really save time
##
n <- 128
mat <- matrix(rnorm(1:(n*n)), nrow=n, ncol=n)
matCached <- makeCacheMatrix(mat)
time1 <- system.time(matSolved1 <- cacheSolve(matCached))
time2 <- system.time(matSolved2 <- cacheSolve(matCached))
if (time1["user.self"] < time2["user.self"])
message("Solve time is less than cache time")
## Compute machine epsilon (floating precision)
## This should be about 2^-53 on most machines.
##
eps <- 0.5
while(1.0 - eps != 1.0)
eps <- eps / 2.0
eps <- eps * 2.0
## This really just tests to see if the matrix inverse is computed
## correctly, which is more of a test of the solve() function. Multiply the
## original matrix by the inverse. Subtract the identity and the result
## should be a zero matrix, within the limits of machine precision.
##
## Note that the allowable error will be much more than machine epsilon due
## to the large number of operations in solve(). We just take a guess here,
## since all we are doing is looking for a result close to zero. The
## allowable error should be porportional to the size of the matrix, and
## hence, the number of operations.
##
n <- 20
mat <- matrix(rnorm(1:(n*n)), nrow=n, ncol=n)
matCached <- makeCacheMatrix(mat)
matSolved <- cacheSolve(matCached)
tmp <- mat %*% matSolved
tmp <- abs(tmp - diag(n))
b <- tmp > (.Machine$double.eps * n * 64)
if (sum(b) != 0)
message("Incorrect matrix inversion")
## Test some of the internals
##
if (!identical(mat, matCached$get()))
message("get() not working")
if (!identical(matSolved, matCached$getSolved()))
message("getSolved() not working")
n <- 5
mat <- matrix(rnorm(1:(n*n)), nrow=n, ncol=n)
matCached$set(mat)
if (!identical(mat, matCached$get()))
message("get() after set() not working")
if (!is.null(matCached$getSolved()))
message("getSolved() after set() not working")
}