diff --git a/cachematrix.R b/cachematrix.R index a50be65aa44..5e5c1cebe14 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -1,15 +1,61 @@ -## Put comments here that give an overall description of what your -## functions do +## 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. +## This two functions do exactly that. Create matrix that stores its inverse (using makeCacheMatrix) +## then get its inverse (using cacheSolve) +## +## Minimal example: +## +## > mc <- makeCacheMatrix(mtx=matrix(c(1, 2, 3, 4), 2, 2)) +## +## > cacheSolve(mc) # first call, computing and set to cache +## [,1] [,2] +## [1,] -2 1.5 +## [2,] 1 -0.5 +## +## > cacheSolve(mc) # second call, getting from cache +## [,1] [,2] +## [1,] -2 1.5 +## [2,] 1 -0.5 -## Write a short comment describing this function -makeCacheMatrix <- function(x = matrix()) { +# makeCacheMatrix +# returns matrix object that stores its inverse +makeCacheMatrix <- function(mtx = matrix()) { + cachedInverse <- NULL + set <- function(y) { + # changes initial matrix and removes old matrix cache + mtx <<- y + cachedInverse <<- NULL + } + get <- function() mtx + setInverse <- function(inv) { + # sets inverse version of the matrix + cachedInverse <<- inv + } + getInverse <- function() { + # returns inverse of the matrix + cachedInverse + } + list(set=set, get=get, + setInverse=setInverse, + getInverse=getInverse) } -## Write a short comment describing this function +# cacheSolve +# looks for inverse of matrix in the cache, if not found, computes inverse and sets cache. Returns +# inverse of the matrix. cacheSolve <- function(x, ...) { - ## Return a matrix that is the inverse of 'x' + inv <- x$getInverse() + if(!is.null(inv)) { + # cached invers exists, return it + return(inv) + } + # inverse is not cached yet, cache it and return + mtx <- x$get() + inv <- solve(mtx, ...) + x$setInverse(inv) + inv } diff --git a/test_cachematrix.R b/test_cachematrix.R new file mode 100644 index 00000000000..4275468794c --- /dev/null +++ b/test_cachematrix.R @@ -0,0 +1,53 @@ +# Test for cachematrix.R +# uses testthat framework +# running tests: +# load R +# > require("testthat") +# > test_file("test_cachematrix.R") + +source("cachematrix.R"); + +context("makeCacheMatrixTest"); + +test_matrix <- matrix(c(1, 2, 3, 4), 2, 2) +test_matrix_inverse <- solve(test_matrix) + +test_that("Can be initialized with matrix", { + cm <- makeCacheMatrix(test_matrix) + expect_that(cm$get(), equals(test_matrix)); +}); + +test_that("Inverse of the cached matrix without matrix is null", { + cm <- makeCacheMatrix() + expect_that(cm$getInverse(), equals(NULL)); +}); + +test_that("Setting matrix should empty inverse", { + cm <- makeCacheMatrix() + cm$set(test_matrix) + cm$setInverse(test_matrix_inverse) + cm$set(test_matrix) + expect_that(cm$getInverse(), equals(NULL)); +}); + +test_that("Getting inverse should return cached inverse", { + cm <- makeCacheMatrix() + cm$set(test_matrix) + cm$setInverse(test_matrix_inverse) + expect_that(cm$getInverse(), equals(test_matrix_inverse)); +}); + + +context("cacheSolveTest"); + +test_that("Returns inverse from cached matrix", { + cm <- makeCacheMatrix(mtx=test_matrix) + cm$setInverse(test_matrix_inverse) + expect_that(cacheSolve(cm), equals(test_matrix_inverse)) +}); + +test_that("Computes and caches inverse", { + cm <- makeCacheMatrix(mtx=test_matrix) + expect_that(cm$getInverse(), equals(NULL)) + expect_that(cacheSolve(cm), equals(test_matrix_inverse)) +});