knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)

solvergater

R build status Codecov test coverage

It is a common task to solve an optimization problem when the objective is computed using an external application such as a finite-element-method partial differential equation solver that gets its input from the command line and writes its output to a number of files. The solvergater package provides a simple R gateway to such external apps.

Installation

You can install the development version from GitHub with:

# install.packages("devtools")
devtools::install_github("maciejsmolka/solvergater")

Usage

Let us start with a basic example which shows you how to run an external solver to compute the quantity of interest and its Jacobian matrix with respect to the parameters. The example uses a mock solver provided with the package.

library(solvergater)
rscript_path <- file.path(R.home(), "bin", "Rscript")
solver_path <- file.path(find.package("solvergater"), "exec", "fake_simple.R")
nparams <- 4
nqoi <- 5
solver_cmd <- paste(rscript_path, solver_path, nparams, nqoi)
s <- shell_solver(solver_cmd, nparams = nparams, qoi_file = "output_qoi",
                  jacobian_file = "output_jacobian", wd = tempdir())
run(s, c(20.11, 5, -1.2, 10.4), silent = TRUE)

The basic use case for solvergater is the support of the optimization problems with special attention paid for inverse problems. A simulated problem of the latter type can be as follows.

First, we prepare some 'observed data' by running the solver at a given point.

observed_data <- run(s, c(10, 10, 10, 10), silent = TRUE)$qoi

Then, as the objective we use the misfit between observed data and a current proposed set of parameters. We can compute it in two ways. First, we can obtain an objective function returning value and gradient at the same time.

x <- c(10.5, 9.44, 10.21, 8.14)
obj <- objective(s, observed_data, silent = TRUE)
obj(x)

Second, we can obtain two separate functions for value and gradient. This form is intended for the use in stats::optim().

solver_obj <- objective_functions(s, observed_data, silent = TRUE)
solver_obj$value(x)
solver_obj$gradient(x)

objective_functions() memoises internal calls to an actual solver, so in the above example only a single solver run is performed.

x1 <- c(0, 20, 0, 20)
solver_obj <- objective_functions(s, observed_data, silent = TRUE)
value_time <- system.time(solver_obj$value(x1))
gradient_time <- system.time(solver_obj$gradient(x1))
value_time
gradient_time


maciejsmolka/solvergater documentation built on Jan. 1, 2021, 8:28 a.m.