From cbc64b941f8f19cc8700497b481775356872c7b5 Mon Sep 17 00:00:00 2001 From: Peter Slatala Date: Wed, 21 May 2014 20:49:30 -0700 Subject: [PATCH 1/5] Implementation of makeCacheMatrix --- cachematrix.R | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/cachematrix.R b/cachematrix.R index a50be65aa44..03c9139eeb4 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -3,8 +3,34 @@ ## Write a short comment describing this function +# This function creates a special matrix object, which inverse will be cached, if computed using cacheSolve +# x is the matrix you want to allow to be cached makeCacheMatrix <- function(x = matrix()) { - + # initialize the variable which will store the inversed cached value + # initially do not assign any value (it will be lazily assigned when cacheSolve is called) + inversedCache <- NULL + + # changes the stored matrix to a different one + # cleares cache + set <- function(newMatrix) { + x <<- newMatrix + inversedCache <<- NULL + } + + # returns the backend matrix + get <- function() x + + # returns the cached inverse. Cached inverse will be NULL if it has + # not been computed yet + getinverse <- function() inversedCache + + # sets the cached inverse + setinverse <- function(inverse) inversedCache <<- inverse + + # returns a 'public API' of this makeCacheMatrix + list(set = set, get = get, + getinverse = getinverse, + setinverse = setinverse) } From cec976579e6755f28d4a3d188a49bfaee401c52f Mon Sep 17 00:00:00 2001 From: Peter Slatala Date: Wed, 21 May 2014 20:59:25 -0700 Subject: [PATCH 2/5] Implementation of cacheSolve function --- cachematrix.R | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/cachematrix.R b/cachematrix.R index 03c9139eeb4..b3d78b6c6ed 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -34,8 +34,26 @@ makeCacheMatrix <- function(x = matrix()) { } -## Write a short comment describing this function - +# This function returns an inverse of the matrix. If the inverse is not already +# computed, it will compute it and store in cache; otherwise, it will just return the value from cache +# x must be the output of the makeCacheMatrix function cacheSolve <- function(x, ...) { - ## Return a matrix that is the inverse of 'x' + # try to get cached value + inverse <- x$getinverse() + + # verify if inverse has ever been cached (NULL indicates it has not been computed yet) + # if it has been computed; return cached value + if(!is.null(inverse)) { + message("getting cached data") + return(inverse) + } + + # otherwise, compute the inverse and store in cache + computedInverse <- solve(x$get()) + + # store computed value in cache + x$setinverse(computedInverse) + + # return the value + computedInverse } From 1910c3e6fd9c299f0cb1afaa25fe93d1bbe921b5 Mon Sep 17 00:00:00 2001 From: Peter Slatala Date: Wed, 21 May 2014 21:33:28 -0700 Subject: [PATCH 3/5] Alternative solution proposal --- cachematrix.R | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/cachematrix.R b/cachematrix.R index b3d78b6c6ed..4614c3b249d 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -54,6 +54,63 @@ cacheSolve <- function(x, ...) { # store computed value in cache x$setinverse(computedInverse) - # return the value + # return the computed value computedInverse } + +## THIS IS THE END OF ASSIGNMENT; READ BELOW IF YOU WANT TO GIVE ME PERSONAL FEEDBACK ON DIFFERENT APPROACH ## +## (you can shoot me an email luserek at gmail) + + +### +### I do not think that suggested proposal of methods is a good one +### The problem I see is that makeCacheMatrix returns a public setters for the cache item +### and everyone who sees this object can change it - even when it won't be good thing to do +### This breaks encapsulation of fields. +### I think that cacheSolve should be part of the makeCacheMatrix and setinverse should not be exposed; +### getinverse should call inverse and cache it (given that the cache already belongs to the matrix) +### +### See the example below: + +# Example: +# cm <- cachedMatrix(hilbert(8)) +# cm$getinverse() # will compute it +# cm$getinverse() # will return cached value +cachedMatrix <- function(x = matrix()) { + # initialize the variable which will store the inversed cached value + # initially do not assign any value (it will be lazily assigned when cacheSolve is called) + inversedCache <- NULL + + # returns the backend matrix + get <- function() x + + # changes the stored matrix to a different one + # cleares cache + set <- function(newMatrix) { + x <<- newMatrix + inversedCache <<- NULL + } + + # this function now computes inverse if it is yet computed or returns cached value + # The advantage of this approach is that nobody should be able to change cached value ever; only this method + # can do it; which guarantees that it corresponds correctly to the matrix itself + # the logic in this function is the same as the logic in the cacheSolve above, but it is encapsulated + getinverse <- function() { + # same logic as earlier: see if we already have cached value, if not, compute and cache it + if(!is.null(inversedCache)) { + message("getting cached data") + return(inversedCache) + } + + # compute + inversedCache <<- solve(x) + + # return computed value + inversedCache + } + + # returns a 'public API' of this makeCacheMatrix + # the public API now does not expose setinverse as it is handled internally + list(set = set, get = get, + getinverse = getinverse) +} \ No newline at end of file From 47ec369a5d86dddb3faf63735c16e5c2d5f5a872 Mon Sep 17 00:00:00 2001 From: Peter Slatala Date: Wed, 21 May 2014 21:35:11 -0700 Subject: [PATCH 4/5] Remove generic comments from top; provide examples --- cachematrix.R | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cachematrix.R b/cachematrix.R index 4614c3b249d..06bf0778556 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -1,10 +1,7 @@ -## Put comments here that give an overall description of what your -## functions do - -## Write a short comment describing this function - -# This function creates a special matrix object, which inverse will be cached, if computed using cacheSolve +# This function creates a special matrix object, which allows to cache the inverse value, if computed using cacheSolve # x is the matrix you want to allow to be cached +# Usage example: +# mc <- makeCacheMatrix(hilbert(8)) makeCacheMatrix <- function(x = matrix()) { # initialize the variable which will store the inversed cached value # initially do not assign any value (it will be lazily assigned when cacheSolve is called) @@ -37,6 +34,10 @@ makeCacheMatrix <- function(x = matrix()) { # This function returns an inverse of the matrix. If the inverse is not already # computed, it will compute it and store in cache; otherwise, it will just return the value from cache # x must be the output of the makeCacheMatrix function +# Usage example: +# mc <- makeCacheMatrix(hilbert(8)) +# cacheSolve(mc) # will compute and store inverse in cache +# cacheSolve(mc) # will return value from cache cacheSolve <- function(x, ...) { # try to get cached value inverse <- x$getinverse() From bd8e1f0943e0b1cdbd0d0d9a122ef3ce3f7713b8 Mon Sep 17 00:00:00 2001 From: Piotr Slatala Date: Wed, 21 May 2014 21:55:57 -0700 Subject: [PATCH 5/5] Add missing ... to params --- cachematrix.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cachematrix.R b/cachematrix.R index 06bf0778556..40844d2eed8 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -50,7 +50,7 @@ cacheSolve <- function(x, ...) { } # otherwise, compute the inverse and store in cache - computedInverse <- solve(x$get()) + computedInverse <- solve(x$get(), ...) # store computed value in cache x$setinverse(computedInverse) @@ -114,4 +114,4 @@ cachedMatrix <- function(x = matrix()) { # the public API now does not expose setinverse as it is handled internally list(set = set, get = get, getinverse = getinverse) -} \ No newline at end of file +}