Commit 40ced4b6 authored by Florian Gerber's avatar Florian Gerber

v 0.7-2.2

parent f46556ce
Package: optimParallel
Type: Package
Title: Parallel Versions of the Gradient-Based optim() Methods
Version: 0.7-2
Date: 2018-05-01
Version: 0.7-2.2
Date: 2018-07-23
Author: Florian Gerber
Maintainer: Florian Gerber <florian.gerber@math.uzh.ch>
Description: Provides parallel versions of the gradient-based optim() methods. The main function of the package is optimParallel(), which has the same usage and output as optim(). Using optimParallel() can significantly reduce the optimization time.
......
- version 0.7-1: CRAN release
commit dbc3d37114f3d1acfeea52f58e1693cb31d01eff
- version 0.7-2.2:
(1) indexing 'par' by names inside 'fn' works now.
e.g. optimParallel(par=c(a=1), fn <- function(x) {x["a"]^2})
(2) using functions and method from loaded packages works now.
'fn' and 'gr' have now .GlobalEnv as parent environment.
(3) the default value for the argument 'method' is now "L-BFGS-B".
(4) the help page ?optimParallel contains a new section 'Notes'
summarizing considerations for the practical use.
- version 0.7-2: CRAN release
commit f46556cee870a5c13145ddfdf5f2e3998ea0b317
Author: Florian Gerber <florian.gerber@math.uzh.ch>
Date: Mon Apr 30 14:15:58 2018 +0200
Date: Tue May 1 12:43:35 2018 +0200
\ No newline at end of file
integratArgs <- function(f, args){
integrateArgs <- function(f, args){
form <- formals(f)
if(!is.null(form))
for(i in seq_along(form))
assign(names(form)[i], form[[i]])
if(!is.null(args))
for(i in seq_along(args))
assign(names(args)[i], args[[i]])
ff <- function(){}
parent.env(environment(ff)) <- .GlobalEnv
body(ff) <- body(f)
if(any(names(form) == "..."))
formals(ff) <- form[names(form) == "..."]
ff
}
getFunctions <- function(f, args, firstArg){
getFunctions <- function(f, args, firstArg, parnames){
if(is.vector(firstArg))
firstArg <- matrix(data=firstArg)
lapply(1:ncol(firstArg), function(x){
args[[names(formals(f))[1]]] <- firstArg[,x]
integratArgs(f=f, args=args)
lapply(seq_len(ncol(firstArg)), function(x){
fa <- firstArg[,x]
names(fa) <- parnames
args[[names(formals(f))[1]]] <- fa
integrateArgs(f=f, args=args)
})
}
#' @importFrom parallel parLapply
evalParallel <- function(cl, f, args, firstArg){
funlist <- getFunctions(f=f, args=args, firstArg=firstArg)
evalParallel <- function(cl, f, args, firstArg, parnames){
funlist <- getFunctions(f=f, args=args, firstArg=firstArg, parnames=parnames)
parallel::parLapply(cl=cl, X=funlist, fun=function(x) x())
}
......@@ -13,11 +13,11 @@
#' @param fn see the documentation of \code{\link[stats]{optim}}.
#' @param gr see the documentation of \code{\link[stats]{optim}}.
#' @param ... see the documentation of \code{\link[stats]{optim}}.
#' Note that depending on the chosen cluster type, \code{fn} and \code{gr} have no access to \code{.GlobalEnv}.
#' Hence, all object required by \code{fn} and \code{gr} have to be added here.
#' @param method parallel versions of the gradient-based methods \code{"L-BFGS-B"}, \code{"BFGS"}, and \code{"CG"} of \code{\link[stats]{optim}} are available.
#' See the documentation of \code{\link[stats]{optim}}.
#' If another method is specified, the arguments are directly passed to \code{\link[stats]{optim}}.
#' Note that depending on the chosen cluster type, the \code{.GlobalEnv} of the R processes in the cluster contain different R objects compared to the main R process.
#' In that case, it may be necessary to add all R object required by \code{fn} and \code{gr} here in order to pass them to the R processes in the cluster.
#' @param method parallel versions of the gradient-based methods \code{"L-BFGS-B"} (default), \code{"BFGS"}, and \code{"CG"} of \code{\link[stats]{optim}} are available.
#' See the documentation of \code{\link[stats]{optim}} for information on those methods.
#' If another method is specified, all arguments are directly passed to \code{\link[stats]{optim}}.
#' @param lower see the documentation of \code{\link[stats]{optim}}.
#' @param upper see the documentation of \code{\link[stats]{optim}}.
#' @param control see the documentation of \code{\link[stats]{optim}}.
......@@ -30,13 +30,13 @@
#' See \code{\link[parallel]{setDefaultCluster}} for information on how to set up a default cluster.}
#' \item{\code{forward}}{ logical vector of length 1. If \code{FALSE} (default when loading the package), a numeric central difference approximation of the gradient defined as
#' \eqn{(fn(x+\epsilon)-fn(x-\epsilon))/(2\epsilon)} is used, which corresponds to the approximation used in \code{\link[stats]{optim}}.
#' If \code{TRUE}, a nummeric forward difference approximation of the gradient essentially defined as
#' \eqn{(fn(x+\epsilon)-fn(x))/\epsilon} is used. This reduces the number of function calls from \eqn{1+2p} to \eqn{1+p} and can be useful, if the number of available cores is smaller than \eqn{1+2p}.}
#' If \code{TRUE}, a numeric forward difference approximation of the gradient essentially defined as
#' \eqn{(fn(x+\epsilon)-fn(x))/\epsilon} is used. This reduces the number of function calls from \eqn{1+2p} to \eqn{1+p} and can be useful if the number of available cores is smaller than \eqn{1+2p} and if the memory limit is reached.}
#' \item{\code{loginfo}}{ logical vector of length 1 with default value \code{FALSE} when loading the package. If \code{TRUE},
#' additional log information containing the evaluated parameters as well as return the values of \code{fn} and \code{gr} is returned.}
#' }
#'
#' @return Same as \code{\link[stats]{optim}}. See the documentation thereof.\cr
#' @return Same as the return value of \code{\link[stats]{optim}}. See the documentation thereof for more information.\cr
#' If a gradient-based method is specified and \code{parallel=list(loginfo=TRUE)}, additional log information containing the evaluated parameters as well as
#' the return values of \code{fn} and \code{gr} is returned.
#'
......@@ -49,6 +49,32 @@
#' optimParallel: an R Package Providing Parallel Versions of the Gradient-Based Optimization Methods of optim().
#' ArXiv e-prints. URL http://arxiv.org/abs/1804.11058.
#' Also available as vignette of this package \code{vignette("optimParallel")}.
#'
#' @section Notes:
#' \describe{
#' \item{1.}{If \code{fn} or \code{gr} depend on functions or methods from loaded packages,
#' it may be necessary to explicitly load those packages in all processes of the cluster.
#' For \code{cl} of class \code{"cluster"} one can use \code{clusterEvalQ(cl, search())} to check
#' whether all required packages are on the search paths of all processes.
#' If, for example, the R package \pkg{spam} is required and missing on those search paths,
#' it can be added via \code{clusterEvalQ(cl, library("spam"))}.}
#' \item{2.}{If \code{fn} or \code{gr} depend on functions or objects defined in the current R session,
#' it may be necessary to pass them to \code{optimParallel} via the \code{...} argument.
#' Alternatively, they can be made available to the R processes in the cluster via \code{\link[parallel]{clusterEvalQ}}.}
#' \item{3.}{Using parallel R code inside \code{fn} and \code{gr} may not work, because this results in nested parallel processing.}
#' \item{4.}{Using \code{optimParellel} with \eqn{n} parallel processes increases the memory usage by about factor \eqn{n} compared to a call to \code{\link[stats]{optim}}.
#' If the memory limit is reached this may severely slowdown the optimization.
#' Strategies to reduce memory usage are
#' (1) kill all unused processes on the computer,
#' (2) revise the code of \code{fn} and/or \code{gr} to reduce its memory usage, and
#' (3) reduce the number of parallel processes by specifying the argument \code{parallel=list(forward=TRUE)} and/or
#' setting up a cluster with less parallel processes.}
#' }
#'
#' @section Issues and bug report:
#' A list of known issues of \code{optimParallel} can be found at \url{https://git.math.uzh.ch/florian.gerber/optimParallel/issues}.
#' Please report issues not listed there to\eqn{\,} \email{florian.gerber@@math.uzh.ch}. Do not forget to include
#' an R script reproducing the issue and the output of \code{sessionInfo()}.
#'
#' @seealso
#' \code{\link[stats]{optim}},
......@@ -110,7 +136,7 @@
#' setDefaultCluster(cl=NULL); stopCluster(cl) }
#' @export
#' @importFrom stats optim
optimParallel <- function(par, fn, gr = NULL, ..., method = c("BFGS", "L-BFGS-B", "CG"),
optimParallel <- function(par, fn, gr = NULL, ..., method = c("L-BFGS-B", "BFGS", "CG"),
lower = -Inf, upper = Inf, control = list(), hessian = FALSE,
parallel=list()){
dots <- list(...)
......@@ -145,7 +171,8 @@ optimParallel <- function(par, fn, gr = NULL, ..., method = c("BFGS", "L-BFGS-B"
forward=parallel$forward,
lower=lower, upper=upper,
cl=parallel$cl, ndeps=control$ndeps,
fnscale=fnscale, parscale=parscale)
fnscale=fnscale, parscale=parscale,
parnames=names(par))
out <- stats::optim(par=par, fn=fg$f, gr=fg$g, method = method, lower=lower,
upper=upper, control=control, hessian=hessian)
out$value <- out$value*fnscale
......@@ -159,7 +186,8 @@ optimParallel <- function(par, fn, gr = NULL, ..., method = c("BFGS", "L-BFGS-B"
#' @importFrom parallel parLapply
parallel_fg_generator <- function(fn, gr=NULL, args_list=list(),
forward=FALSE, lower=-Inf, upper=Inf,
cl=NULL, ndeps=1e-3, fnscale=1, parscale=1){
cl=NULL, ndeps=1e-3, fnscale=1, parscale=1,
parnames=NULL){
stopifnot(is.function(fn),
is.null(gr) || is.function(gr),
is.list(args_list),
......@@ -168,7 +196,8 @@ parallel_fg_generator <- function(fn, gr=NULL, args_list=list(),
is.null(cl) || inherits(cl, "cluster"),
is.null(ndeps) || is.numeric(ndeps),
is.numeric(fnscale) || is.null(fnscale),
is.numeric(parscale) || is.null(parscale))
is.numeric(parscale) || is.null(parscale),
is.character(parnames) || is.null(parnames))
if(any(is.na(lower))) lower[is.na(lower)] <- -Inf
if(any(is.na(upper))) lower[is.na(upper)] <- Inf
......@@ -197,7 +226,7 @@ parallel_fg_generator <- function(fn, gr=NULL, args_list=list(),
}
}
PAR <- cbind(PAR, par)
e <- unname(unlist(evalParallel(cl=cl, f=fn, args=args_list, firstArg=PAR)))
e <- unname(unlist(evalParallel(cl=cl, f=fn, args=args_list, firstArg=PAR, parnames=parnames)))
e <- e/fnscale
value <- e[length(e)]
length(e) <- length(e)-1
......@@ -222,7 +251,7 @@ parallel_fg_generator <- function(fn, gr=NULL, args_list=list(),
}
}
PAR <- cbind(PAR, par)
e <- unname(unlist(evalParallel(cl=cl, f=fn, args=args_list, firstArg=PAR)))
e <- unname(unlist(evalParallel(cl=cl, f=fn, args=args_list, firstArg=PAR, parnames=parnames)))
e <- e/fnscale
value <- e[length(e)]
length(e) <- length(e)-1
......@@ -230,8 +259,8 @@ parallel_fg_generator <- function(fn, gr=NULL, args_list=list(),
grad <- c(e_mat[,1]-e_mat[,2])/ndepsused
}
}else{ # gr is not null
funlist <- list(getFunctions(fn, args_list, par)[[1]],
getFunctions(gr, args_list, par)[[1]])
funlist <- list(getFunctions(f=fn, args=args_list, firstArg=par, parnames=parnames)[[1]],
getFunctions(f=gr, args=args_list, firstArg=par, parnames=parnames)[[1]])
res <- parallel::parLapply(cl=cl, X=funlist, fun=function(x) x())
value <- res[[1]]/fnscale
grad <- res[[2]]/fnscale
......
......@@ -8,6 +8,6 @@ on "L-BFGS-B", the speed increase is about factor 1+2p when no analytic gradient
1+2p processor cores are available.
See the ArXiv e-prints URL http://arxiv.org/abs/1804.11058
also available as package vignette.
also available as package vignette for more information.
R> vignette("optimParallel")
\ No newline at end of file
......@@ -13,7 +13,7 @@
\alias{optimParallel-package}
\title{parallel version of \code{\link[stats]{optim}}}
\usage{
optimParallel(par, fn, gr = NULL, ..., method = c("BFGS", "L-BFGS-B", "CG"),
optimParallel(par, fn, gr = NULL, ..., method = c("L-BFGS-B", "BFGS", "CG"),
lower = -Inf, upper = Inf, control = list(), hessian = FALSE,
parallel = list())
}
......@@ -25,12 +25,12 @@ optimParallel(par, fn, gr = NULL, ..., method = c("BFGS", "L-BFGS-B", "CG"),
\item{gr}{see the documentation of \code{\link[stats]{optim}}.}
\item{...}{see the documentation of \code{\link[stats]{optim}}.
Note that depending on the chosen cluster type, \code{fn} and \code{gr} have no access to \code{.GlobalEnv}.
Hence, all object required by \code{fn} and \code{gr} have to be added here.}
Note that depending on the chosen cluster type, the \code{.GlobalEnv} of the R processes in the cluster contain different R objects compared to the main R process.
In that case, it may be necessary to add all R object required by \code{fn} and \code{gr} here in order to pass them to the R processes in the cluster.}
\item{method}{parallel versions of the gradient-based methods \code{"L-BFGS-B"}, \code{"BFGS"}, and \code{"CG"} of \code{\link[stats]{optim}} are available.
See the documentation of \code{\link[stats]{optim}}.
If another method is specified, the arguments are directly passed to \code{\link[stats]{optim}}.}
\item{method}{parallel versions of the gradient-based methods \code{"L-BFGS-B"} (default), \code{"BFGS"}, and \code{"CG"} of \code{\link[stats]{optim}} are available.
See the documentation of \code{\link[stats]{optim}} for information on those methods.
If another method is specified, all arguments are directly passed to \code{\link[stats]{optim}}.}
\item{lower}{see the documentation of \code{\link[stats]{optim}}.}
......@@ -48,14 +48,14 @@ If the argument is not specified or \code{NULL}, the default cluster is used.
See \code{\link[parallel]{setDefaultCluster}} for information on how to set up a default cluster.}
\item{\code{forward}}{ logical vector of length 1. If \code{FALSE} (default when loading the package), a numeric central difference approximation of the gradient defined as
\eqn{(fn(x+\epsilon)-fn(x-\epsilon))/(2\epsilon)} is used, which corresponds to the approximation used in \code{\link[stats]{optim}}.
If \code{TRUE}, a nummeric forward difference approximation of the gradient essentially defined as
\eqn{(fn(x+\epsilon)-fn(x))/\epsilon} is used. This reduces the number of function calls from \eqn{1+2p} to \eqn{1+p} and can be useful, if the number of available cores is smaller than \eqn{1+2p}.}
If \code{TRUE}, a numeric forward difference approximation of the gradient essentially defined as
\eqn{(fn(x+\epsilon)-fn(x))/\epsilon} is used. This reduces the number of function calls from \eqn{1+2p} to \eqn{1+p} and can be useful if the number of available cores is smaller than \eqn{1+2p} and if the memory limit is reached.}
\item{\code{loginfo}}{ logical vector of length 1 with default value \code{FALSE} when loading the package. If \code{TRUE},
additional log information containing the evaluated parameters as well as return the values of \code{fn} and \code{gr} is returned.}
}}
}
\value{
Same as \code{\link[stats]{optim}}. See the documentation thereof.\cr
Same as the return value of \code{\link[stats]{optim}}. See the documentation thereof for more information.\cr
If a gradient-based method is specified and \code{parallel=list(loginfo=TRUE)}, additional log information containing the evaluated parameters as well as
the return values of \code{fn} and \code{gr} is returned.
}
......@@ -71,6 +71,36 @@ and the R package \pkg{parallel} to evaluate \code{fn}
and its (approximate) gradient in parallel.\cr\cr
Some default values of the argument \code{parallel} can be set via\cr\code{options("optimParallel.forward", "optimParallel.loginfo")}.
}
\section{Notes}{
\describe{
\item{1.}{If \code{fn} or \code{gr} depend on functions or methods from loaded packages,
it may be necessary to explicitly load those packages in all processes of the cluster.
For \code{cl} of class \code{"cluster"} one can use \code{clusterEvalQ(cl, search())} to check
whether all required packages are on the search paths of all processes.
If, for example, the R package \pkg{spam} is required and missing on those search paths,
it can be added via \code{clusterEvalQ(cl, library("spam"))}.}
\item{2.}{If \code{fn} or \code{gr} depend on functions or objects defined in the current R session,
it may be necessary to pass them to \code{optimParallel} via the \code{...} argument.
Alternatively, they can be made available to the R processes in the cluster via \code{\link[parallel]{clusterEvalQ}}.}
\item{3.}{Using parallel R code inside \code{fn} and \code{gr} may not work, because this results in nested parallel processing.}
\item{4.}{Using \code{optimParellel} with \eqn{n} parallel processes increases the memory usage by about factor \eqn{n} compared to a call to \code{\link[stats]{optim}}.
If the memory limit is reached this may severely slowdown the optimization.
Strategies to reduce memory usage are
(1) kill all unused processes on the computer,
(2) revise the code of \code{fn} and/or \code{gr} to reduce its memory usage, and
(3) reduce the number of parallel processes by specifying the argument \code{parallel=list(forward=TRUE)} and/or
setting up a cluster with less parallel processes.}
}
}
\section{Issues and bug report}{
A list of known issues of \code{optimParallel} can be found at \url{https://git.math.uzh.ch/florian.gerber/optimParallel/issues}.
Please report issues not listed there to\eqn{\,} \email{florian.gerber@math.uzh.ch}. Do not forget to include
an R script reproducing the issue and the output of \code{sessionInfo()}.
}
\examples{
negll <- function(par, x, sleep=0, verbose=TRUE){
if(verbose)
......
......@@ -13,70 +13,90 @@ f2 <- function(x,y){
f3 <- function(x,y=1){
x+y
}
fnames <- function(x){
x["a"]+x["b"]+x["c"]
}
test_that("evalParallel: f1", {
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=NULL,
firstArg=c(1)),
firstArg=c(1), parnames=NULL),
list(1))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=NULL,
firstArg=c(1,2)),
firstArg=c(1,2), parnames=NULL),
list(c(1,2)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=NULL,
firstArg=matrix(c(1,2), ncol=2)),
firstArg=matrix(c(1,2), ncol=2), parnames=NULL),
list(1,2))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=NULL,
firstArg=c(1,2,3,4,5)),
firstArg=c(1,2,3,4,5), parnames=NULL),
list(c(1,2,3,4,5)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=list(a=1),
firstArg=c(1,2,3,4,5)),
firstArg=c(1,2,3,4,5), parnames=NULL),
list(c(1,2,3,4,5)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=list(x=100),
firstArg=c(1,2,3,4,5)),
firstArg=c(1,2,3,4,5), parnames=NULL),
list(c(1,2,3,4,5)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=NULL,
firstArg=matrix(c(1,2,3,4,5), ncol=5)),
firstArg=matrix(c(1,2,3,4,5), ncol=5), parnames=NULL),
list(1,2,3,4,5))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=list(a=1),
firstArg=matrix(c(1,2,3,4,5), ncol=5)),
firstArg=matrix(c(1,2,3,4,5), ncol=5), parnames=NULL),
list(1,2,3,4,5))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f1, args=list(x=100),
firstArg=matrix(c(1,2,3,4,5), ncol=5)),
firstArg=matrix(c(1,2,3,4,5), ncol=5), parnames=NULL),
list(1,2,3,4,5))
})
test_that("evalParallel: f2", {
expect_equal(optimParallel:::evalParallel(cl=cl, f=f2, args=list(x=1,y=1),
firstArg=matrix(c(1:4), ncol=4)),
firstArg=matrix(c(1:4), ncol=4), parnames=NULL),
list(f2(x=1, y=1),
f2(x=2, y=1),
f2(x=3, y=1),
f2(x=4, y=1)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f2, args=list(x=1,y=1),
firstArg=t(array(1:4, c(4,3)))),
firstArg=t(array(1:4, c(4,3))), parnames=NULL),
list(f2(x=c(1,1,1), y=1),
f2(x=c(2,2,2), y=1),
f2(x=c(3,3,3), y=1),
f2(x=c(4,4,4), y=1)))
expect_equal(optimParallel:::evalParallel(cl=cl, f=f2, args=list(y=1,x=1),
firstArg=t(array(1:4, c(4,3)))),
firstArg=t(array(1:4, c(4,3))), parnames=NULL),
list(f2(x=c(1,1,1), y=1),
f2(x=c(2,2,2), y=1),
f2(x=c(3,3,3), y=1),
f2(x=c(4,4,4), y=1)))
expect_error(optimParallel:::evalParallel(cl=cl, f=f2, args=list(x=1),
firstArg=t(array(1:4, c(4,3)))))
firstArg=t(array(1:4, c(4,3))), parnames=NULL))
})
test_that("evalParallel: f3 defaults", {
expect_equal(optimParallel:::evalParallel(cl=cl, f=f3, args=list(x=1),
firstArg=1),
firstArg=1, parnames=NULL),
list(f3(x=1)))
})
test_that("evalParallel: fnames", {
expect_equal(optimParallel:::evalParallel(cl=cl, f=fnames, args=list(x=1),
firstArg=array(1:3, c(3,1)), parnames=c("a","b","c")),
list(fnames(x=c(a=1,b=2,c=3))))
expect_equal(optimParallel:::evalParallel(cl=cl, f=fnames, args=list(x=1),
firstArg=array(1:6, c(3,2)),
parnames=c("a","b","c")),
list(fnames(x=c(a=1,b=2,c=3)),
fnames(x=c(a=4,b=5,c=6))))
expect_equal(optimParallel:::evalParallel(cl=cl, f=fnames, args=list(x=1),
firstArg=array(1:9, c(3,3)),
parnames=c("a","b","c")),
list(fnames(x=c(a=1,b=2,c=3)),
fnames(x=c(a=4,b=5,c=6)),
fnames(x=c(a=7,b=8,c=9))))
})
......@@ -20,9 +20,65 @@ test_that("optimParallel",{
compareOptim(list(par=c(1,2,3), fn=FN1, gr=GR1, sleep=0,
method = "L-BFGS-B",
control=structure(list(maxit = 10,
factr = 2.22044604925031e-16,
ndeps = 0.001),
.Names = c("maxit","factr", "ndeps"))),
factr = 2.22044604925031e-16),
.Names = c("maxit","factr"))),
verbose=verbose)
})
FN2 <- function(par, sleep){
Sys.sleep(sleep)
par["a"]^2+par["b"]^2
}
GR2 <- function(par, sleep){
Sys.sleep(sleep)
2*c(par["a"],par["b"])
}
FN3 <- function(par, sleep){
Sys.sleep(sleep)
par["a"]^2
}
GR3 <- function(par, sleep){
Sys.sleep(sleep)
2*c(par["a"])
}
test_that("optimParallel - named arguments",{
compareOptim(list(par=c(a=1,b=2), fn=FN2, sleep=0,
method = "L-BFGS-B",
control=structure(list(maxit = 10,
factr = 2.22044604925031e-16),
.Names = c("maxit","factr"))),
verbose=verbose)
compareOptim(list(par=c(a=1,b=2), fn=FN2, gr= GR2, sleep=0,
method = "L-BFGS-B",
control=structure(list(maxit = 10,
factr = 2.22044604925031e-16),
.Names = c("maxit","factr"))),
verbose=verbose)
compareOptim(list(par=c(a=1), fn=FN3, sleep=0,
method = "L-BFGS-B",
control=structure(list(maxit = 10,
factr = 2.22044604925031e-16),
.Names = c("maxit","factr"))),
verbose=verbose)
compareOptim(list(par=c(a=1), fn=FN3, gr= GR3, sleep=0,
method = "L-BFGS-B",
control=structure(list(maxit = 10,
factr = 2.22044604925031e-16),
.Names = c("maxit","factr"))),
verbose=verbose)
})
FN4 <- function(par){
print(search())
diag(spam(1:4, 2))
sum(par^2)
}
test_that("optimParallel - dispatch to other packages",{
skip_if_not(require("spam"), message="spam not available for testing dispatching to loaded packages")
clusterEvalQ(cl, require("spam"))
expect_true({optimParallel(par=c(a=1,b=2), fn=FN4, method = "L-BFGS-B"); TRUE})
})
......@@ -160,9 +160,6 @@ test_that("parscale",{
})
test_that("gradient",{
optimParallel(par=2, fn=f4, gr=g4, method = "L-BFGS-B" )
compareOptim(list(par=c(2), fn=f4, gr=g4, method = "L-BFGS-B",
control=list(factr=factr)),
verbose=verbose)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment