From c97454d45168c31846cbb25b71ce6e7ce75df033 Mon Sep 17 00:00:00 2001 From: Rainer Thiel Date: Mon, 20 Apr 2015 19:59:59 +1200 Subject: [PATCH 1/2] rprog-013 assignment 2 ffirst commit --- README.md | 117 +++++++++----------------------------------------- cachematrix.R | 58 +++++++++++++++++++++---- 2 files changed, 70 insertions(+), 105 deletions(-) diff --git a/README.md b/README.md index 7a8c502a4be..ceeca5413df 100644 --- a/README.md +++ b/README.md @@ -1,105 +1,28 @@ ### Introduction -This second programming assignment will require you to write an R -function that is able to cache potentially time-consuming computations. -For example, taking the mean of a numeric vector is typically a fast -operation. However, for a very long vector, it may take too long to -compute the mean, especially if it has to be computed repeatedly (e.g. -in a loop). If the contents of a vector are not changing, it may make -sense to cache the value of the mean so that when we need it again, it -can be looked up in the cache rather than recomputed. In this -Programming Assignment you will take advantage of the scoping rules of -the R language and how they can be manipulated to preserve state inside -of an R object. +This is programming assignment 2 of the Data Science Specialisation +course module "R Programming" https://class.coursera.org/rprog-013 -### Example: Caching the Mean of a Vector +### makeCacheMatrix -In this example we introduce the `<<-` operator which can be used to -assign a value to an object in an environment that is different from the -current environment. Below are two functions that are used to create a -special object that stores a numeric vector and caches its mean. +This function creates a "special" matrix vector x and exposes it +through 4 functions that are returned as a list: +1. get() returns the input matrix x +2. set(y) assigns y, the matrix value argument to x +3. getminv() returns inv, the cached inverse of matrix x +4. setminv(minv) assigns the matrix inverse calculation minv to inv -The first function, `makeVector` creates a special "vector", which is -really a list containing a function to +Essentially makeCacheMatrix is a wrapper object for + x - the input matrix (assumed to be invertible) + y - the inverse of matrix x + associated getter and setter methods -1. set the value of the vector -2. get the value of the vector -3. set the value of the mean -4. get the value of the mean +### cacheSolve - +This function calculates the inverse of the matrix +returned by the makeCacheMatrix$get function. +It also caches the inverse result so that it can be returned +directly on subsequent calls without having to recalculate it. - makeVector <- function(x = numeric()) { - m <- NULL - set <- function(y) { - x <<- y - m <<- NULL - } - get <- function() x - setmean <- function(mean) m <<- mean - getmean <- function() m - list(set = set, get = get, - setmean = setmean, - getmean = getmean) - } - -The following function calculates the mean of the special "vector" -created with the above function. However, it first checks to see if the -mean has already been calculated. If so, it `get`s the mean from the -cache and skips the computation. Otherwise, it calculates the mean of -the data and sets the value of the mean in the cache via the `setmean` -function. - - cachemean <- function(x, ...) { - m <- x$getmean() - if(!is.null(m)) { - message("getting cached data") - return(m) - } - data <- x$get() - m <- mean(data, ...) - x$setmean(m) - m - } - -### Assignment: Caching the Inverse of a Matrix - -Matrix inversion is usually a costly computation and there may be some -benefit to caching the inverse of a matrix rather than computing it -repeatedly (there are also alternatives to matrix inversion that we will -not discuss here). Your assignment is to write a pair of functions that -cache the inverse of a matrix. - -Write the following functions: - -1. `makeCacheMatrix`: This function creates a special "matrix" object - that can cache its inverse. -2. `cacheSolve`: This function computes the inverse of the special - "matrix" returned by `makeCacheMatrix` above. If the inverse has - already been calculated (and the matrix has not changed), then - `cacheSolve` should retrieve the inverse from the cache. - -Computing the inverse of a square matrix can be done with the `solve` -function in R. For example, if `X` is a square invertible matrix, then -`solve(X)` returns its inverse. - -For this assignment, assume that the matrix supplied is always -invertible. - -In order to complete this assignment, you must do the following: - -1. Fork the GitHub repository containing the stub R files at - [https://github.com/rdpeng/ProgrammingAssignment2](https://github.com/rdpeng/ProgrammingAssignment2) - to create a copy under your own account. -2. Clone your forked GitHub repository to your computer so that you can - edit the files locally on your own machine. -3. Edit the R file contained in the git repository and place your - solution in that file (please do not rename the file). -4. Commit your completed R file into YOUR git repository and push your - git branch to the GitHub repository under your account. -5. Submit to Coursera the URL to your GitHub repository that contains - the completed R code for the assignment. - -### Grading - -This assignment will be graded via peer assessment. +This function depends on an instance of the makeCacheMatrix function, +passed in as mandatory argument makem. \ No newline at end of file diff --git a/cachematrix.R b/cachematrix.R index a50be65aa44..eacfaed5687 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -1,15 +1,57 @@ -## Put comments here that give an overall description of what your -## functions do - -## Write a short comment describing this function - +## +## This is programming assignment 2 of the Data Science Specialisation +## course module "R Programming" https://class.coursera.org/rprog-013 +##----------------------------------------------------------------------- +## makeCacheMatrix +## +## This function creates a "special" matrix vector x and exposes it +## through 4 functions that are returned as a list: +## 1. get() returns the input matrix x +## 2. set(y) assigns y, the matrix value argument to x +## 3. getminv() returns inv, the cached inverse of matrix x +## 4. setminv(minv) assigns the matrix inverse calculation minv to inv +## +## Essentially makeCacheMatrix is a wrapper object for +## x - the input matrix (assumed to be invertible) +## y - the inverse of matrix x +## associated getter and setter methods +## makeCacheMatrix <- function(x = matrix()) { + inv <- NULL + set <- function(y) { + x <<- y + inv <<- NULL + } + get <- function() x + setminv <- function(minv) inv <<- minv + getminv <- function() inv + list(set = set, get = get, + setminv = setminv, + getminv = getminv) } -## Write a short comment describing this function +## +## cacheSolve +## +## This function calculates the inverse of the matrix +## returned by the makeCacheMatrix$get function. +## It also caches the inverse result so that it can be returned +## directly on subsequent calls without having to recalculate it. +## +## This function depends on an instance of the makeCacheMatrix function, +## passed in as mandatory argument makem. +## +cacheSolve <- function(makem, ...) { -cacheSolve <- function(x, ...) { - ## Return a matrix that is the inverse of 'x' + minv <- makem$getminv() + if(!is.null(minv)) { + message("getting cached inverted matrix data") + return(minv) + } + data <- makem$get() + minv <- solve(data, ...) + makem$setminv(minv) + minv } From 7aedaa57bd2cb6e871088682f5904142dfef7a2b Mon Sep 17 00:00:00 2001 From: Rainer Thiel Date: Thu, 30 May 2024 16:14:54 +0200 Subject: [PATCH 2/2] Initial commit R Programming Assignment 2 --- .gitignore | 4 +++ ProgrammingAssignment2.Rproj | 13 ++++++++ README.md | 32 +++++------------- cachematrix.R | 65 +++++++++++++++++++++++++++++++++++- 4 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 .gitignore create mode 100644 ProgrammingAssignment2.Rproj diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000000..5b6a0652566 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.Rproj.user +.Rhistory +.RData +.Ruserdata diff --git a/ProgrammingAssignment2.Rproj b/ProgrammingAssignment2.Rproj new file mode 100644 index 00000000000..066341ea144 --- /dev/null +++ b/ProgrammingAssignment2.Rproj @@ -0,0 +1,13 @@ +Version: 1.0 + +RestoreWorkspace: Default +SaveWorkspace: Default +AlwaysSaveHistory: Default + +EnableCodeIndexing: Yes +UseSpacesForTab: Yes +NumSpacesForTab: 4 +Encoding: UTF-8 + +RnwWeave: Sweave +LaTeX: pdfLaTeX diff --git a/README.md b/README.md index ceeca5413df..584d91a5854 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,14 @@ -### Introduction +## Programming Assignment 2 - Lexical Scoping -This is programming assignment 2 of the Data Science Specialisation -course module "R Programming" https://class.coursera.org/rprog-013 +`runTests()` -### makeCacheMatrix +This function runs a few examples to test the matrix inversion and caching. -This function creates a "special" matrix vector x and exposes it -through 4 functions that are returned as a list: -1. get() returns the input matrix x -2. set(y) assigns y, the matrix value argument to x -3. getminv() returns inv, the cached inverse of matrix x -4. setminv(minv) assigns the matrix inverse calculation minv to inv +- There are 5 test cases, 3 are expected to work, 2 are expected to fail. +- An inner function handles the common stuff. +- A successful test returns the associated identity matrix. +- A test failure reports the error and continues onto the next test. -Essentially makeCacheMatrix is a wrapper object for - x - the input matrix (assumed to be invertible) - y - the inverse of matrix x - associated getter and setter methods +Note: I have had to round the identity matrix values (8 significant digits) -### cacheSolve - -This function calculates the inverse of the matrix -returned by the makeCacheMatrix$get function. -It also caches the inverse result so that it can be returned -directly on subsequent calls without having to recalculate it. - -This function depends on an instance of the makeCacheMatrix function, -passed in as mandatory argument makem. \ No newline at end of file +--- diff --git a/cachematrix.R b/cachematrix.R index eacfaed5687..4c4650afade 100644 --- a/cachematrix.R +++ b/cachematrix.R @@ -47,11 +47,74 @@ cacheSolve <- function(makem, ...) { minv <- makem$getminv() if(!is.null(minv)) { - message("getting cached inverted matrix data") + message("2. Fetch cached inverted matrix data") return(minv) } data <- makem$get() minv <- solve(data, ...) makem$setminv(minv) + message("1. Calculate inverse matrix and save in cache") minv } + +## +## runTests +## +## This function runs a few examples to test the matrix inversion and caching. +## +## There are 5 test cases, 3 are expected to work, 2 are expected to fail. +## An inner function solveAndCheck() handles the common stuff. +## A successful test returns the associated identity matrix. +## A test failure reports the error and continues onto the next test. +## +## Note: I have had to round the identity matrix values (8 significant digits) +## + +runTests <- function() { + + matObj <- makeCacheMatrix() # instantiate matrix object + + solveAndCheck <- function() { # the common stuff + + matObj$set(m1) # set the matrix + + tryCatch( # wrap to trap and continue + # and continue + { + message(label, "Start") + cacheSolve(matObj) # calculate inverse and cache + n1 <- cacheSolve(matObj) # fetch from cache + message("3. Calculate and show rounded identity matrix") + idm <- m1 %*% n1 + print(round(idm, 8)) + message(label, "*** SUCCESS ***") + }, + error=function(e) { + message(label, "*** FAILURE ***") + print(e) + } + ) + + } + + label <- "Test1: " + m1 <- matrix(c(1/2,-1/4,-1,3/4),nrow=2) # discussion example matrix + solveAndCheck() + + label <- "Test2: " + m1 <- matrix(rnorm(144),nrow=12) # another example matrix + solveAndCheck() + + label <- "Test3: " + m1 <- matrix(rnorm(144),nrow=8) # bad - not a square matrix + solveAndCheck() + + label <- "Test4: " + m1 <- matrix(c(3,2,0,7,0,1,2,-2,1), nrow=3) # another example matrix + solveAndCheck() + + label <- "Test5: " + m1 <- matrix(11:26, nrow=4) # bad - singular matrix + solveAndCheck() + +}