knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" )
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.
You can install the development version from GitHub with:
# install.packages("devtools") devtools::install_github("maciejsmolka/solvergater")
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
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.