From 214c39b875d781088dd3eaa6412d0ae868eab638 Mon Sep 17 00:00:00 2001 From: Rohan Shah Date: Thu, 3 Sep 2015 10:45:07 +1000 Subject: [PATCH 1/4] Added code to call matlab --- NAMESPACE | 1 + R/matlab.R | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 R/matlab.R diff --git a/NAMESPACE b/NAMESPACE index ee1af53..8ab5d1d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,3 +2,4 @@ S3method(print,runr_results) export(proc_bash) export(proc_julia) export(proc_python) +export(proc_matlab) \ No newline at end of file diff --git a/R/matlab.R b/R/matlab.R new file mode 100644 index 0000000..0591341 --- /dev/null +++ b/R/matlab.R @@ -0,0 +1,59 @@ +#' Run a matlab process +#' +#' This function returns a list of functions to start/run/stop a matlab process. +#' The code is sent to matlab via a socket connection, and the results are +#' written back in another socket connection. +#' @param port A TCP port number +#' @return A list of functions \code{start()}, \code{exec()}, \code{running()} +#' (check if the process has been running), and \code{stop()}. +#' @export +#' @examples \dontrun{ +#' mat = proc_matlab() +#' mat$start() +#' mat$exec('1+1') +#' mat$exec('x = 1 + 1; x = x + x; x;') # return nothing +#' mat$exec('5:9') # [ 5 6 7 8 9] +#' mat$running() # should be TRUE +#' mat$stop() +#' } + +proc_matlab <- function(port = 6011, existing=FALSE){ + require(R.matlab) + matlab <- NULL + exec_code = function(...){ + if (is.null(matlab)) stop('the process has not been started yet') + code = as.character(c(...)) + code = unlist(strsplit(code, "\n")) + result <- sapply(code, function(x) evaluatec(matlab, x)) + return(do.call(paste, c(as.list(result), sep = "\n"))) + } + + list( + start = function() { + if (!is.null(matlab)) { + warning('the program has been started') + return(invisible()) + } + Matlab$startServer(port=port) + matlab <<- Matlab(port=port) + isOpen <- open(matlab, trials=30, interval = 0, timeout = 1) + if(!isOpen) + { + stop("Unable to connect to matlab server") + } + invisible() + }, + + exec = exec_code, + + running = function() !is.null(matlab), + + stop = function() { + close(matlab) + matlab <<- NULL + invisible() + } + ) +} + + From e0570c90ae7361d492fc75cf7676a2970db61ee2 Mon Sep 17 00:00:00 2001 From: Rohan Shah Date: Sun, 6 Sep 2015 11:01:01 +1000 Subject: [PATCH 2/4] Changes to allow for multi-line expressions in exec_code --- DESCRIPTION | 1 + R/matlab.R | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index b3f9cbf..36c44a2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -11,6 +11,7 @@ Authors@R: c( person("Adam", "Lyon", role = "aut"), person("Yalei", "Du", role = "aut") ) +Suggests: R.matlab Maintainer: Yihui Xie License: GPL URL: https://github.com/yihui/runr diff --git a/R/matlab.R b/R/matlab.R index 0591341..38200e8 100644 --- a/R/matlab.R +++ b/R/matlab.R @@ -12,19 +12,19 @@ #' mat$start() #' mat$exec('1+1') #' mat$exec('x = 1 + 1; x = x + x; x;') # return nothing +#' mat$exec('x = 1 + 1\n x = x + x\n x') # return nothing #' mat$exec('5:9') # [ 5 6 7 8 9] +#' mat$exec('x = 1; while x < 10\n disp(x);\n x = x + 1;\n end') #Prints numbers 1 to 9 #' mat$running() # should be TRUE #' mat$stop() #' } proc_matlab <- function(port = 6011, existing=FALSE){ - require(R.matlab) matlab <- NULL exec_code = function(...){ if (is.null(matlab)) stop('the process has not been started yet') code = as.character(c(...)) - code = unlist(strsplit(code, "\n")) - result <- sapply(code, function(x) evaluatec(matlab, x)) + result = sapply(code, function(x) R.matlab::evaluatec(matlab, x)) return(do.call(paste, c(as.list(result), sep = "\n"))) } @@ -34,9 +34,9 @@ proc_matlab <- function(port = 6011, existing=FALSE){ warning('the program has been started') return(invisible()) } - Matlab$startServer(port=port) - matlab <<- Matlab(port=port) - isOpen <- open(matlab, trials=30, interval = 0, timeout = 1) + R.matlab::Matlab$startServer(port=port) + matlab <<- R.matlab::Matlab(port=port) + isOpen = open(matlab, trials=30, interval = 0, timeout = 1) if(!isOpen) { stop("Unable to connect to matlab server") From a171300b8a12888ff834ff8d2c44bcb7a921fa63 Mon Sep 17 00:00:00 2001 From: Rohan Shah Date: Sun, 6 Sep 2015 11:03:15 +1000 Subject: [PATCH 3/4] Removed 'existing' argument I thought it might be a good idea to re-use the matlab instance, but it's probably unnecessary. They start pretty fast. --- R/matlab.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/matlab.R b/R/matlab.R index 38200e8..05a84c0 100644 --- a/R/matlab.R +++ b/R/matlab.R @@ -19,7 +19,7 @@ #' mat$stop() #' } -proc_matlab <- function(port = 6011, existing=FALSE){ +proc_matlab <- function(port = 6011){ matlab <- NULL exec_code = function(...){ if (is.null(matlab)) stop('the process has not been started yet') From 8bbc82878ea369cc2a1af027e4e2950e083fad51 Mon Sep 17 00:00:00 2001 From: Rohan Shah Date: Wed, 7 Oct 2015 12:12:40 +1000 Subject: [PATCH 4/4] Updated call to evaluate() to reflect changes in R.matlab --- R/matlab.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/matlab.R b/R/matlab.R index 05a84c0..57218f7 100644 --- a/R/matlab.R +++ b/R/matlab.R @@ -24,7 +24,7 @@ proc_matlab <- function(port = 6011){ exec_code = function(...){ if (is.null(matlab)) stop('the process has not been started yet') code = as.character(c(...)) - result = sapply(code, function(x) R.matlab::evaluatec(matlab, x)) + result = sapply(code, function(x) R.matlab::evaluate(matlab, x, capture=TRUE)) return(do.call(paste, c(as.list(result), sep = "\n"))) }